初始化2

This commit is contained in:
2026-04-08 17:10:58 +08:00
commit 4986d90eb9
532 changed files with 112617 additions and 0 deletions

View File

@@ -0,0 +1,72 @@
import request from '@/utils/request'
import type { ApiResult, PageResult } from '@/api'
import type { AppApiKey, AppApiKeyParam } from './model'
import { APP_API_URL } from '@/config/setting'
const BASE = APP_API_URL + '/apikey'
/** 分页查询 API Key - 直接用基础路径,后端 @GetMapping 支持分页参数 */
export async function pageAppApiKey(params: AppApiKeyParam) {
const res = await request.get<ApiResult<PageResult<AppApiKey>>>(BASE, { params })
if (res.data.code === 0) return res.data.data
return Promise.reject(new Error(res.data.message))
}
/** 查询全部 API Key */
export async function listAppApiKey(params?: AppApiKeyParam) {
const res = await request.get<ApiResult<AppApiKey[]>>(BASE, { params })
if (res.data.code === 0 && res.data.data) return res.data.data
return Promise.reject(new Error(res.data.message))
}
/** 创建 API Key */
export async function createAppApiKey(data: {
name: string
expireTime?: string
scopes?: string
remark?: string
}) {
const res = await request.post<ApiResult<AppApiKey>>(BASE, data)
if (res.data.code === 0) return res.data.data
return Promise.reject(new Error(res.data.message))
}
/** 更新 API Key 状态 */
export async function updateAppApiKeyStatus(id: number, status: number) {
const res = await request.put<ApiResult<unknown>>(BASE + `/${id}/status?status=${status}`)
if (res.data.code === 0) return res.data.message
return Promise.reject(new Error(res.data.message))
}
/** 删除 API Key */
export async function removeAppApiKey(id: number) {
const res = await request.delete<ApiResult<unknown>>(BASE + '/' + id)
if (res.data.code === 0) return res.data.message
return Promise.reject(new Error(res.data.message))
}
/** 获取 API Key 速率限制 */
export async function getApiRateLimits() {
const res = await request.get<ApiResult<{
plan: string
rps: number
dailyLimit: number
usedToday: number
remainingToday: number
}>>(BASE + '/rate-limits')
if (res.data.code === 0 && res.data.data) return res.data.data
return Promise.reject(new Error(res.data.message))
}
/** 获取 API Key 统计 */
export async function getAppApiKeyStats() {
const res = await request.get<ApiResult<{
total: number
active: number
expired: number
disabled: number
totalUsage: number
}>>(BASE + '/stats')
if (res.data.code === 0 && res.data.data) return res.data.data
return Promise.reject(new Error(res.data.message))
}

View File

@@ -0,0 +1,31 @@
/** API Key 数据模型 */
export interface AppApiKey {
id: number
name: string
apiKey: string
keyPrefix: string
status: number // 0=正常, 1=禁用
scopes?: string
expireTime?: string
lastUsedAt?: string
usageCount: number
remark?: string
createTime: string
updateTime: string
}
/** API Key 查询参数 */
export interface AppApiKeyParam {
page?: number
limit?: number // 与后端 BaseParam 一致
name?: string
status?: number
}
/** 分页结果 - 后端 MyBatis-Plus 返回 records */
export interface AppApiKeyPageResult {
records: AppApiKey[]
total: number
size: number
current: number
}

View File

@@ -0,0 +1,120 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { AppConfig, AppConfigParam, BatchSaveRequest } from './model';
import {APP_API_URL} from '@/config/setting';
/**
* 分页查询应用配置
*/
export async function pageAppConfig(params: AppConfigParam) {
const res = await request.get<ApiResult<PageResult<AppConfig>>>(
APP_API_URL + '/app-config/page',
{
params
}
);
if (res.data.code === 0) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 获取应用配置列表
*/
export async function listAppConfig(params?: AppConfigParam) {
const res = await request.get<ApiResult<AppConfig[]>>(
APP_API_URL + '/app-config',
{
params
}
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 根据应用ID获取配置映射
*/
export async function getConfigsMap(productId: number) {
const res = await request.get<ApiResult<Record<string, any>>>(
APP_API_URL + `/app/app-config/map/${productId}`
);
if (res.data.code === 0) {
return res.data.data || {};
}
return Promise.reject(new Error(res.data.message));
}
/**
* 获取单个配置值
*/
export async function getConfigValue(productId: number, configKey: string) {
const res = await request.get<ApiResult<string>>(
APP_API_URL + '/app-config/value',
{
params: { productId, configKey }
}
);
if (res.data.code === 0) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 保存配置
*/
export async function saveAppConfig(data: AppConfig) {
const res = await request.post<ApiResult<void>>(
APP_API_URL + '/app-config',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 批量保存配置
*/
export async function batchSaveAppConfig(data: BatchSaveRequest) {
const res = await request.post<ApiResult<void>>(
APP_API_URL + '/app-config/batch',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 更新配置
*/
export async function updateAppConfig(data: AppConfig) {
const res = await request.put<ApiResult<void>>(
APP_API_URL + '/app-config',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 删除配置
*/
export async function deleteAppConfig(configId: number) {
const res = await request.delete<ApiResult<void>>(
APP_API_URL + `/app-config/${configId}`
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}

View File

@@ -0,0 +1,66 @@
import type { PageParam } from '@/api';
import type { PageResult } from '@/api';
/**
* 应用配置
*/
export interface AppConfig {
configId?: number;
productId?: number;
configKey?: string;
configValue?: string;
configType?: string;
isEncrypted?: number;
isSecret?: number;
description?: string;
sortNumber?: number;
tenantId?: number;
createdTime?: string;
updatedTime?: string;
deleted?: number;
}
/**
* 应用配置查询参数
*/
export interface AppConfigParam extends PageParam {
configId?: number;
productId?: number;
configKey?: string;
configType?: string;
isSecret?: number;
}
/**
* 批量保存请求
*/
export interface BatchSaveRequest {
productId: number;
configs: AppConfig[];
}
/**
* 配置类型定义
*/
export interface ConfigType {
key: string;
name: string;
icon: string;
description: string;
configs: ConfigField[];
}
/**
* 配置字段定义
*/
export interface ConfigField {
key: string;
label: string;
type: 'input' | 'textarea' | 'number' | 'select' | 'switch' | 'password' | 'json';
required?: boolean;
placeholder?: string;
options?: Array<{ label: string; value: any }>;
defaultValue?: any;
description?: string;
secret?: boolean;
}

View File

@@ -0,0 +1,62 @@
import request from '@/utils/request'
import type { ApiResult, PageResult } from '@/api'
import type { AppCredential, AppCredentialParam } from './model'
import {APP_API_URL} from '@/config/setting'
const BASE = APP_API_URL + '/app-credential'
/** 分页查询凭证 */
export async function pageAppCredential(params: AppCredentialParam) {
const res = await request.get<ApiResult<PageResult<AppCredential>>>(BASE + '/page', { params })
if (res.data.code === 0) return res.data.data
return Promise.reject(new Error(res.data.message))
}
/** 查询全部凭证 */
export async function listAppCredential(params?: AppCredentialParam) {
const res = await request.get<ApiResult<AppCredential[]>>(BASE, { params })
if (res.data.code === 0 && res.data.data) return res.data.data
return Promise.reject(new Error(res.data.message))
}
/** 根据ID查询凭证 */
export async function getAppCredential(id: number) {
const res = await request.get<ApiResult<AppCredential>>(BASE + '/' + id)
if (res.data.code === 0 && res.data.data) return res.data.data
return Promise.reject(new Error(res.data.message))
}
/** 创建凭证(自动生成 AppID/AppSecret仅此次返回明文 */
export async function createAppCredential(data: AppCredential) {
const res = await request.post<ApiResult<AppCredential>>(BASE, data)
if (res.data.code === 0) return { message: res.data.message, data: res.data.data }
return Promise.reject(new Error(res.data.message))
}
/** 修改凭证信息(不含密钥) */
export async function updateAppCredential(data: AppCredential) {
const res = await request.put<ApiResult<unknown>>(BASE, data)
if (res.data.code === 0) return res.data.message
return Promise.reject(new Error(res.data.message))
}
/** 重置 AppSecret */
export async function resetAppCredentialSecret(id: number) {
const res = await request.post<ApiResult<AppCredential>>(BASE + '/resetSecret/' + id)
if (res.data.code === 0) return { message: res.data.message, data: res.data.data }
return Promise.reject(new Error(res.data.message))
}
/** 禁用/启用凭证 */
export async function updateAppCredentialStatus(id: number, status: number) {
const res = await request.put<ApiResult<unknown>>(BASE + `/status/${id}/${status}`)
if (res.data.code === 0) return res.data.message
return Promise.reject(new Error(res.data.message))
}
/** 删除凭证 */
export async function removeAppCredential(id: number) {
const res = await request.delete<ApiResult<unknown>>(BASE + '/' + id)
if (res.data.code === 0) return res.data.message
return Promise.reject(new Error(res.data.message))
}

View File

@@ -0,0 +1,33 @@
import type { PageParam } from '@/api'
export interface AppCredential {
id?: number
appId?: number
name?: string
clientId?: string
clientSecret?: string
type?: string
scopes?: string
expireTime?: string
lastUsedAt?: string
remark?: string
sortNumber?: number
status?: number
deleted?: number
userId?: number
tenantId?: number
createTime?: string
updateTime?: string
// 关联字段
productName?: string
productCode?: string
icon?: string
}
export interface AppCredentialParam extends PageParam {
appId?: number
name?: string
clientId?: string
type?: string
status?: number
}

View File

@@ -0,0 +1,43 @@
import request from '@/utils/request'
import type { ApiResult, PageResult } from '@/api'
import type { AppEvent, AppEventParam } from './model'
import {APP_API_URL} from '@/config/setting'
const BASE = APP_API_URL + '/app-event'
/** 分页查询动态 */
export async function pageAppEvent(params: AppEventParam) {
const res = await request.get<ApiResult<PageResult<AppEvent>>>(BASE + '/page', { params })
if (res.data.code === 0) return res.data.data
return Promise.reject(new Error(res.data.message))
}
/** 查询全部动态 */
export async function listAppEvent(params?: AppEventParam) {
const res = await request.get<ApiResult<AppEvent[]>>(BASE, { params })
if (res.data.code === 0 && res.data.data) return res.data.data
return Promise.reject(new Error(res.data.message))
}
/** 获取应用最新一条动态 */
export async function getLatestAppEvent(productId: number) {
const res = await request.get<ApiResult<AppEvent>>(BASE + '/latest/' + productId)
if (res.data.code === 0) return res.data.data
return Promise.reject(new Error(res.data.message))
}
/** 记录一条操作动态(静默:失败不抛出) */
export async function addAppEvent(data: AppEvent): Promise<void> {
try {
await request.post<ApiResult<unknown>>(BASE, data)
} catch {
// 动态记录失败不影响主流程,静默处理
}
}
/** 清空应用所有动态 */
export async function clearAppEvents(productId: number) {
const res = await request.delete<ApiResult<unknown>>(BASE + '/clear/' + productId)
if (res.data.code === 0) return res.data.message
return Promise.reject(new Error(res.data.message))
}

View File

@@ -0,0 +1,26 @@
import type { PageParam } from '@/api'
export interface AppEvent {
id?: number
appId?: number
eventType?: string
title?: string
content?: string
operatorId?: number
operator?: string
refId?: number
refType?: string
extra?: string
sortNumber?: number
status?: number
userId?: number
tenantId?: number
createTime?: string
updateTime?: string
}
export interface AppEventParam extends PageParam {
appId?: number
eventType?: string
operatorId?: number
}

View File

@@ -0,0 +1,219 @@
import request from '@/utils/request'
import type { ApiResult, PageResult } from '@/api'
import type { AppProduct, AppProductParam } from './model'
import { APP_API_URL } from '@/config/setting'
const BASE = APP_API_URL + '/product'
// ============ 基础 CRUD ============
/** 分页查询应用产品 */
export async function pageAppProduct(params: AppProductParam) {
const res = await request.get<ApiResult<PageResult<AppProduct>>>(BASE + '/page', { params })
if (res.data.code === 0) return res.data.data
return Promise.reject(new Error(res.data.message))
}
/** 分页查询应用产品(别名,兼容 cmsWebsite 接口) */
export const page = pageAppProduct
/** 分页查询应用产品(别名,兼容旧代码) */
export async function pageAppProductAll(params: AppProductParam) {
return pageAppProduct(params)
}
/** 获取应用产品详情 */
export async function getAppProduct(productId: number) {
const res = await request.get<ApiResult<AppProduct>>(BASE + '/detail/' + productId)
if (res.data.code === 0) return res.data.data
return Promise.reject(new Error(res.data.message))
}
/** 获取应用产品详情ByCode */
export async function getAppProductByCode(code: string) {
const res = await request.get<ApiResult<AppProduct>>(BASE + '/info/' + code)
if (res.data.code === 0) return res.data.data
return Promise.reject(new Error(res.data.message))
}
/** 新增应用产品 */
export async function addAppProduct(data: Partial<AppProduct>) {
const res = await request.post<ApiResult<AppProduct>>(BASE + '/create', data)
if (res.data.code === 0) return res.data.data
return Promise.reject(new Error(res.data.message))
}
/** 修改应用产品 */
export async function updateAppProduct(data: Partial<AppProduct>) {
const res = await request.put<ApiResult<unknown>>(BASE + '/update', data)
if (res.data.code === 0) return res.data.message
return Promise.reject(new Error(res.data.message))
}
/** 删除应用产品 */
export async function removeAppProduct(id: number) {
const res = await request.delete<ApiResult<unknown>>(BASE + '/delete/' + id)
if (res.data.code === 0) return res.data.message
return Promise.reject(new Error(res.data.message))
}
// ============ 开发者相关 ============
/** 获取开发者应用列表 */
export async function getDeveloperApps(params?: AppProductParam) {
const res = await request.get<ApiResult<AppProduct[]>>(BASE + '/list', { params })
if (res.data.code === 0 && res.data.data) return res.data.data
return Promise.reject(new Error(res.data.message))
}
/** 分页查询我的应用(创建者) */
export async function getMyApps(params: { page?: number; limit?: number }) {
const res = await request.get<ApiResult<PageResult<AppProduct>>>(BASE + '/my/page', { params })
if (res.data.code === 0) return res.data.data
return Promise.reject(new Error(res.data.message))
}
/** 分页查询我参与的应用 */
export async function getJoinedApps(params: { page?: number; limit?: number }) {
const res = await request.get<ApiResult<PageResult<AppProduct>>>(BASE + '/joined/page', { params })
if (res.data.code === 0) return res.data.data
return Promise.reject(new Error(res.data.message))
}
/** 开发者提交审核 */
export async function submitReview(id: number) {
const res = await request.post<ApiResult<unknown>>(BASE + '/submit/' + id)
if (res.data.code === 0) return res.data.message
return Promise.reject(new Error(res.data.message))
}
/** 提交发布审核(别名) */
export const submitPublishReview = submitReview
/** 撤回审核申请 */
export async function withdrawPublishReview(id: number) {
const res = await request.post<ApiResult<unknown>>(BASE + '/withdraw/' + id)
if (res.data.code === 0) return res.data.message
return Promise.reject(new Error(res.data.message))
}
/** 开发者下架应用 */
export async function deprecated(id: number) {
const res = await request.post<ApiResult<unknown>>(BASE + '/unpublish/' + id)
if (res.data.code === 0) return res.data.message
return Promise.reject(new Error(res.data.message))
}
/** 下架应用(别名) */
export const unpublishAppProduct = deprecated
// ============ 市场相关 ============
/** 获取市场应用列表 */
export async function getMarketApps(params: AppProductParam) {
const res = await request.get<ApiResult<PageResult<AppProduct>>>(BASE + '/market/page', { params })
if (res.data.code === 0) return res.data.data
return Promise.reject(new Error(res.data.message))
}
/** 获取市场应用详情 */
export async function getMarketApp(productId: number) {
const res = await request.get<ApiResult<AppProduct>>(BASE + '/detail/' + productId)
if (res.data.code === 0) return res.data.data
return Promise.reject(new Error(res.data.message))
}
// ============ 管理后台 ============
/** 获取待审核列表 */
export async function getPendingReviewApps(params: AppProductParam) {
const res = await request.get<ApiResult<PageResult<AppProduct>>>(BASE + '/page', {
params: { ...params, publishStatus: 'pending_review' },
})
if (res.data.code === 0) return res.data.data
return Promise.reject(new Error(res.data.message))
}
/** 分页查询发布审核列表(别名) */
export const pagePublishReviews = getPendingReviewApps
/** 审核通过 */
export async function approve(id: number) {
const res = await request.post<ApiResult<unknown>>(BASE + '/approve/' + id)
if (res.data.code === 0) return res.data.message
return Promise.reject(new Error(res.data.message))
}
/** 审核通过(别名) */
export const approvePublishReview = approve
/** 审核拒绝 */
export async function reject(id: number, reason: string) {
const res = await request.post<ApiResult<unknown>>(BASE + '/reject/' + id, null, { params: { reason } })
if (res.data.code === 0) return res.data.message
return Promise.reject(new Error(res.data.message))
}
/** 审核拒绝(别名,接收对象参数) */
export async function rejectPublishReview(params: { productId: number; rejectReason: string }) {
return reject(params.productId, params.rejectReason)
}
// ============ 其他 ============
/** 按用户ID列表批量统计应用数量 */
export interface UserAppStats {
userId: number
totalCount: number
publishedCount: number
}
export async function getUserAppStats(userIds: number[]) {
const res = await request.post<ApiResult<UserAppStats[]>>(BASE + '/user-stats', userIds)
if (res.data.code === 0 && res.data.data) return res.data.data
return []
}
/** 获取全部应用(下拉框用) */
export async function getAllAppProduct() {
const res = await request.get<ApiResult<AppProduct[]>>(BASE + '/all')
if (res.data.code === 0 && res.data.data) return res.data.data
return Promise.reject(new Error(res.data.message))
}
/** 获取当前用户可访问的应用列表(带角色信息,用于权限过滤) */
export async function getMyAccessibleApps() {
const res = await request.get<ApiResult<AppProduct[]>>(BASE + '/accessible')
if ((res.data.code === 0 || res.data.code === 200) && res.data.data) return res.data.data
return []
}
/** 更新访问量 */
export async function updateClicks(id: number) {
const res = await request.post<ApiResult<unknown>>(BASE + '/view/' + id)
if (res.data.code === 0) return res.data.message
return Promise.reject(new Error(res.data.message))
}
/** 记录应用访问(更新最近访问时间) */
export async function recordVisit(id: number) {
const res = await request.post<ApiResult<unknown>>(BASE + '/visit/' + id)
// 静默失败,不影响主流程
if (res.data.code !== 0) {
console.warn('记录访问失败', res.data.message)
}
}
/** 收藏/取消收藏 */
export async function toggleLike(id: number) {
const res = await request.post<ApiResult<unknown>>(BASE + '/like/' + id)
if (res.data.code === 0) return res.data.data
return Promise.reject(new Error(res.data.message))
}
/** 重新生成密钥 */
export async function regenerateSecret(id: number) {
const res = await request.post<ApiResult<unknown>>(BASE + '/regenerateSecret/' + id)
if (res.data.code === 0) return res.data.data
return Promise.reject(new Error(res.data.message))
}

View File

@@ -0,0 +1,186 @@
import type { PageParam } from '@/api'
import type { AppRole } from '../appUser/model'
export interface AppProduct {
productId?: number
productName?: string
productCode?: string
productSecret?: string
appType?: number
categoryId?: number
industryParent?: string
industryChild?: string
logo?: string
icon?: string
qrcode?: string
screenshots?: string
description?: string
content?: string
keywords?: string
domain?: string
prefix?: string
packageName?: string
homeUrl?: string
adminUrl?: string
apiUrl?: string
downloadUrl?: string
version?: string
edition?: string
minVersion?: string
priceType?: string
price?: number
linePrice?: number
renewPrice?: number
deliveryMethod?: number
chargingMethod?: number
subscriptionPeriod?: string
publishStatus?: string
publishTime?: string
reviewTime?: string
reviewerId?: number
rejectReason?: string
clicks?: number
installs?: number
downloads?: number
rating?: number
likes?: number
developer?: string
developerPhone?: string
developerEmail?: string
recommend?: number
official?: number
market?: number
showIndex?: number
searchEnabled?: number
templateId?: number
style?: string
config?: string
themeColor?: string
lang?: string
icpNo?: string
policeNo?: string
status?: number
statusText?: string
running?: number
expirationTime?: string
sortNumber?: number
deleted?: number
userId?: number
tenantId?: number
createTime?: string
updateTime?: string
/** 当前用户在该应用中的角色(仅 joined/accessible 查询返回) */
myRole?: AppRole
}
export interface AppProductParam extends PageParam {
appType?: number
categoryId?: number
publishStatus?: string
status?: number
keywords?: string
developer?: string
market?: number
official?: number
recommend?: number
userId?: number
}
// App Type 枚举
export const APP_TYPE = {
WEBSITE: 10,
WECHAT_MP: 20,
DOUYIN_MP: 30,
BAIDU_MP: 40,
ALIPAY_MP: 50,
ANDROID: 60,
IOS: 70,
MACOS: 80,
WINDOWS: 90,
PLUGIN: 100,
} as const
export type APP_TYPE_KEY = keyof typeof APP_TYPE
export const APP_TYPE_NAME: Record<number, string> = {
[APP_TYPE.WEBSITE]: '网站',
[APP_TYPE.WECHAT_MP]: '微信小程序',
[APP_TYPE.DOUYIN_MP]: '抖音小程序',
[APP_TYPE.BAIDU_MP]: '百度小程序',
[APP_TYPE.ALIPAY_MP]: '支付宝小程序',
[APP_TYPE.ANDROID]: 'Android APP',
[APP_TYPE.IOS]: 'iOS APP',
[APP_TYPE.MACOS]: 'macOS 应用',
[APP_TYPE.WINDOWS]: 'Windows 应用',
[APP_TYPE.PLUGIN]: '插件',
}
// Publish Status 枚举
export const PUBLISH_STATUS = {
DEVELOPING: 'developing',
PENDING_REVIEW: 'pending_review',
PUBLISHED: 'published',
REJECTED: 'rejected',
DEPRECATED: 'deprecated',
} as const
export type PUBLISH_STATUS_KEY = keyof typeof PUBLISH_STATUS
export const PUBLISH_STATUS_NAME: Record<string, string> = {
[PUBLISH_STATUS.DEVELOPING]: '开发中',
[PUBLISH_STATUS.PENDING_REVIEW]: '待审核',
[PUBLISH_STATUS.PUBLISHED]: '已上架',
[PUBLISH_STATUS.REJECTED]: '审核未通过',
[PUBLISH_STATUS.DEPRECATED]: '已下架',
}
// Price Type 枚举
export const PRICE_TYPE = {
FREE: 'free',
ONE_TIME: 'one_time',
SUBSCRIPTION: 'subscription',
} as const
export type PRICE_TYPE_KEY = keyof typeof PRICE_TYPE
export const PRICE_TYPE_NAME: Record<string, string> = {
[PRICE_TYPE.FREE]: '免费',
[PRICE_TYPE.ONE_TIME]: '一次性',
[PRICE_TYPE.SUBSCRIPTION]: '订阅',
}
// Edition 枚举
export const EDITION = {
STANDARD: 'standard',
PROFESSIONAL: 'professional',
PERPETUAL: 'perpetual',
} as const
export type EDITION_KEY = keyof typeof EDITION
export const EDITION_NAME: Record<string, string> = {
[EDITION.STANDARD]: '标准版',
[EDITION.PROFESSIONAL]: '专业版',
[EDITION.PERPETUAL]: '永久授权',
}
// Status 枚举
export const STATUS = {
INACTIVE: 0,
RUNNING: 1,
MAINTENANCE: 2,
CLOSED: 3,
ARREARS: 4,
VIOLATION: 5,
} as const
export type STATUS_KEY = keyof typeof STATUS
export const STATUS_NAME: Record<number, string> = {
[STATUS.INACTIVE]: '未开通',
[STATUS.RUNNING]: '运行中',
[STATUS.MAINTENANCE]: '维护中',
[STATUS.CLOSED]: '已关闭',
[STATUS.ARREARS]: '已欠费',
[STATUS.VIOLATION]: '违规停机',
}

View File

@@ -0,0 +1,158 @@
import request from '@/utils/request'
import type { ApiResult, PageResult } from '@/api'
import type { AppResource, AppResourceParam } from './model'
import {APP_API_URL} from '@/config/setting'
const BASE = APP_API_URL + '/developer-resource'
/** 分页查询资源 */
export async function pageAppResource(params: AppResourceParam) {
const res = await request.get<ApiResult<PageResult<AppResource>>>(BASE + '/page', { params })
if (res.data.code === 0) return res.data.data
return Promise.reject(new Error(res.data.message))
}
/** 查询资源列表(不分页) */
export async function listAppResource(params?: AppResourceParam) {
const res = await request.get<ApiResult<AppResource[]>>(BASE, { params })
if (res.data.code === 0 && res.data.data) return res.data.data
return Promise.reject(new Error(res.data.message))
}
/** 获取资源详情 */
export async function getAppResource(resourceId: number) {
const res = await request.get<ApiResult<AppResource>>(BASE + '/' + resourceId)
if (res.data.code === 0) return res.data.data
return Promise.reject(new Error(res.data.message))
}
/** 统计各类型资源数量 */
export async function statsAppResource(): Promise<Record<string, number>> {
const res = await request.get<ApiResult<Record<string, number>>>(BASE + '/stats')
if (res.data.code === 0) return res.data.data ?? {}
return Promise.reject(new Error(res.data.message))
}
/** 新增资源 */
export async function addAppResource(data: AppResource) {
const res = await request.post<ApiResult<AppResource>>(BASE, data)
if (res.data.code === 0) return res.data.data
return Promise.reject(new Error(res.data.message))
}
/** 修改资源 */
export async function updateAppResource(data: AppResource) {
const res = await request.put<ApiResult<AppResource>>(BASE, data)
if (res.data.code === 0) return res.data.data
return Promise.reject(new Error(res.data.message))
}
/** 删除资源 */
export async function removeAppResource(resourceId: number, code?: string) {
const res = await request.delete<ApiResult<unknown>>(BASE + '/' + resourceId, code ? { data: { code } } : {})
if (res.data.code === 0) return res.data.message
return Promise.reject(new Error(res.data.message))
}
/** 批量删除资源 */
export async function removeBatchAppResource(ids: number[]) {
const res = await request.delete<ApiResult<unknown>>(BASE + '/batch', { data: ids })
if (res.data.code === 0) return res.data.message
return Promise.reject(new Error(res.data.message))
}
/** 测试数据库连接 */
export async function testConnection(params: { host: string; port?: number; dbType?: string; username: string; password: string; dbName?: string }) {
const res = await request.post<ApiResult<{ success: boolean; message: string; detail?: string }>>(BASE + '/test-connection', params)
if (res.data.code === 0) return res.data.data
return Promise.reject(new Error(res.data.message))
}
/** 测试 SSH 连接 */
export async function testSshConnection(params: { host: string; port?: number; username: string; password: string }) {
const res = await request.post<ApiResult<{ success: boolean; message: string; detail?: string }>>(BASE + '/test-ssh', params)
if (res.data.code === 0) return res.data.data
return Promise.reject(new Error(res.data.message))
}
/** 重试创建数据库 */
export async function retryCreateDatabase(resourceId: number) {
const res = await request.post<ApiResult<unknown>>(BASE + '/retry-create-database/' + resourceId)
if (res.data.code === 0) return res.data.message
return Promise.reject(new Error(res.data.message))
}
/** 重置数据库密码 */
export async function resetDatabasePassword(resourceId: number) {
const res = await request.post<ApiResult<{ password: string }>>(BASE + '/reset-password/' + resourceId)
if (res.data.code === 200 || res.data.code === 0) return res.data.data
return Promise.reject(new Error(res.data.message))
}
/** 刷新存储桶信息 */
export async function refreshStorage(resourceId: number) {
const res = await request.post<ApiResult<{ usedBytes: number; objectCount: number }>>(BASE + '/refresh-storage/' + resourceId)
if (res.data.code === 200 || res.data.code === 0) return res.data.data
return Promise.reject(new Error(res.data.message))
}
/** 检查域名 DNS 状态 */
export async function checkDomainDns(resourceId: number) {
const res = await request.post<ApiResult<{ status: 'ok' | 'error' | 'pending'; ip?: string; message?: string }>>(BASE + '/check-dns/' + resourceId)
if (res.data.code === 200 || res.data.code === 0) return res.data.data
return Promise.reject(new Error(res.data.message))
}
/** 生成 Nginx 配置 */
export async function generateNginxConfig(resourceId: number) {
const res = await request.get<ApiResult<{ config: string }>>(BASE + '/nginx-config/' + resourceId)
if (res.data.code === 200 || res.data.code === 0) return res.data.data
return Promise.reject(new Error(res.data.message))
}
/** 获取域名统计信息 */
export async function getDomainStats() {
const res = await request.get<ApiResult<{
total: number
icpCount: number
sslCount: number
expiringCount: number
errorCount: number
}>>(BASE + '/domain-stats')
if (res.data.code === 200 || res.data.code === 0) return res.data.data
return Promise.reject(new Error(res.data.message))
}
/** 批量导入域名 */
export async function importDomains(data: { domains: Array<Partial<AppResource>> }) {
const res = await request.post<ApiResult<{ success: number; failed: number; errors: string[] }>>(BASE + '/import-domains', data)
if (res.data.code === 200 || res.data.code === 0) return res.data.data
return Promise.reject(new Error(res.data.message))
}
/** 导出域名列表 */
export async function exportDomains(params?: AppResourceParam) {
const res = await request.get(BASE + '/export-domains', { params, responseType: 'blob' })
return res.data
}
/** 获取1Panel服务器状态 */
export interface ServerStatus {
cpu: string // CPU 使用率 %
memory: string // 内存使用率 %
memoryUsed: string // 内存已用
memoryTotal: string // 内存总量
disk: string // 磁盘使用率 %
diskUsed: string // 磁盘已用
diskTotal: string // 磁盘总量
load: string // 系统负载
uptime: string // 运行时间
online: number // 在线状态 1=在线 0=离线
message?: string // 错误信息
}
export async function getServerStatus(resourceId: number): Promise<ServerStatus> {
const res = await request.get<ApiResult<ServerStatus>>(BASE + '/server-status/' + resourceId)
if (res.data.code === 200 || res.data.code === 0) return res.data.data!
return Promise.reject(new Error(res.data.message))
}

View File

@@ -0,0 +1,156 @@
import type { PageParam } from '@/api'
/**
* 开发者资源
*/
export interface AppResource {
resourceId?: number
resourceType?: string // server | database | storage | domain | ssl
name?: string
provider?: string // tencent | aliyun | huawei | other
// 服务器
ip?: string
sshPort?: number // SSH 端口默认22
sshUsername?: string // SSH 用户名(用于远程执行命令)
sshPassword?: string // SSH 密码AES加密用于远程执行命令
mysqlPort?: number // MySQL 端口默认3306
pgPort?: number // PostgreSQL 端口默认5432
panelPort?: number // 1Panel 面板端口默认8888
panelUsername?: string // 1Panel 面板用户名
panelPassword?: string // 1Panel 面板密码AES加密
panelPath?: string // 1Panel 面板路径前缀(如 /abc123
adminUsername?: string // MySQL/PostgreSQL 管理员用户名(用于远程建库)
adminPassword?: string // MySQL/PostgreSQL 管理员密码AES加密用于远程建库
// 数据库
dbType?: string // MySQL | PostgreSQL | Redis | MongoDB
serverResourceId?: number // 关联服务器资源ID
host?: string
port?: number
dbUsername?: string
dbPassword?: string
// 云存储
region?: string
acl?: string // public-read | private
usedBytes?: number
// 域名
domain?: string
registrar?: string
icp?: boolean
icpNo?: string
sslBound?: boolean
sslResourceId?: number // 关联的 SSL 证书资源ID
sslCertName?: string // 关联的 SSL 证书名称
dnsRecords?: DnsRecord[] // DNS 记录列表
whoisInfo?: WhoisInfo // WHOIS 信息
autoRenew?: boolean // 是否自动续费
// 域名健康状态
dnsStatus?: 'ok' | 'error' | 'pending' | 'unknown' // DNS 解析状态
dnsIp?: string // DNS 解析到的 IP
healthStatus?: 'healthy' | 'warning' | 'error' | 'unknown' // 综合健康状态
healthCheckAt?: string // 最后健康检查时间
subDomains?: AppResource[] // 子域名列表
parentDomainId?: number // 父域名 ID用于子域名
isWildcard?: boolean // 是否通配符域名
serverResourceId?: number // 关联的服务器资源ID
serverName?: string // 关联的服务器名称
nginxConfig?: string // Nginx 配置
// SSL
certType?: string // DV | OV | EV
issuer?: string
privateKey?: string // 私钥AES加密存储
publicKey?: string // 公钥
certificate?: string // 证书内容/证书文件
certChain?: string // 证书链(中间证书)
algorithm?: string // 加密算法RSA/ECC
keyBits?: number // 密钥长度2048/4096等
// Git仓库
gitPath?: string // Git仓库路径如: websopy/core
gitCloneUrl?: string // Git Clone URL
gitWebUrl?: string // Git Web访问URLGitea页面地址
gitAccessLevel?: string // Git权限级别: read/write/admin
// 云存储凭证
credentialId?: number // 关联的云账号凭证ID
// 通用
status?: string // running | stopped | expired | pending
appId?: number
productName?: string
expireAt?: string
remark?: string
userId?: number
tenantId?: number
deleted?: number
createTime?: string
updateTime?: string
// ─── 协作权限字段 ────────────────────────────────────────────
/**
* 资源所有者 userId创建者
* 后端在创建时自动设置,前端只读
*/
ownerUserId?: number
/**
* 当前访问者对该资源的权限级别(后端计算,前端只读)
* 0 - 无权限
* 1 - 基础查看(名称/IP/端口/状态,所有团队成员)
* 2 - 连接查看(用户名、连接方式,技术负责人)
* 3 - 完全权限(包含密码/私钥仅资源Owner
*/
accessLevel?: 0 | 1 | 2 | 3
/**
* 敏感字段是否为脱敏占位符(后端返回 "******" 表示已脱敏)
*/
isMasked?: boolean
/** 是否是资源创建者(前端根据 ownerUserId vs 当前 UserId 计算) */
isOwner?: boolean
}
/**
* DNS 记录
*/
export interface DnsRecord {
type: string // A, AAAA, CNAME, MX, TXT, NS
name: string
value: string
ttl?: number
priority?: number
}
/**
* WHOIS 信息
*/
export interface WhoisInfo {
registrar?: string
creationDate?: string
expirationDate?: string
updatedDate?: string
nameServers?: string[]
status?: string[]
}
/**
* 资源查询参数
*/
export interface AppResourceParam extends PageParam {
resourceId?: number
resourceType?: string
appId?: number
provider?: string
status?: string
userId?: number
tenantId?: number
keywords?: string
icp?: boolean
sslBound?: boolean
}

View File

@@ -0,0 +1,110 @@
import request from '@/utils/request'
import type { ApiResult, PageResult } from '@/api'
import type { AppUser, AppUserParam, CheckAccessResult } from './model'
import { APP_API_URL } from '@/config/setting'
const BASE = APP_API_URL + '/app-user'
type InviteApiItem = AppUser & {
appName?: string
app_name?: string
product_name?: string
appIcon?: string
inviterName?: string
inviter_name?: string
productCode?: string
product_code?: string
}
function normalizeInvite(invite: InviteApiItem): AppUser {
return {
...invite,
productName: invite.productName || invite.appName || invite.product_name || invite.app_name,
productCode: invite.productCode || invite.product_code,
icon: invite.icon || invite.appIcon || invite.avatar,
username: invite.username || invite.inviterName || invite.inviter_name || invite.nickname
}
}
/** 分页查询成员 */
export async function pageAppUser(params: AppUserParam) {
const res = await request.get<ApiResult<PageResult<AppUser>>>(BASE + '/page', { params })
if (res.data.code === 0) return res.data.data
return Promise.reject(new Error(res.data.message))
}
/** 查询全部成员 */
export async function listAppUser(params?: AppUserParam) {
const res = await request.get<ApiResult<AppUser[]>>(BASE, { params })
if (res.data.code === 0 && res.data.data) return res.data.data
return Promise.reject(new Error(res.data.message))
}
/** 邀请成员userId 或 phone 二选一) */
export async function inviteAppUser(data: { productId: number; userId?: number; phone?: string; role?: string }) {
const res = await request.post<ApiResult<AppUser>>(BASE + '/invite', data)
if (res.data.code === 0) return res.data.message
return Promise.reject(new Error(res.data.message))
}
/** 修改成员角色 */
export async function updateAppUserRole(id: number, role: string) {
const res = await request.put<ApiResult<unknown>>(BASE + `/role/${id}/${role}`)
if (res.data.code === 0) return res.data.message
return Promise.reject(new Error(res.data.message))
}
/** 删除成员 */
export async function removeAppUser(id: number) {
const res = await request.delete<ApiResult<unknown>>(BASE + '/' + id)
if (res.data.code === 0) return res.data.message
return Promise.reject(new Error(res.data.message))
}
// ============ 邀请确认相关 ============
/** 查询当前用户的待确认邀请列表 */
export async function listPendingInvites() {
const res = await request.get<ApiResult<InviteApiItem[]>>(BASE + '/invites/pending')
const { code, data, message } = res.data
if (code === 0 || code === 200) {
return Array.isArray(data) ? data.map(normalizeInvite) : []
}
return Promise.reject(new Error(message))
}
/** 统计当前用户的待确认邀请数量 */
export async function countPendingInvites() {
const res = await request.get<ApiResult<{ count: number }>>(BASE + '/invites/pending/count')
const { code, data, message } = res.data
if ((code === 0 || code === 200) && data) return data.count
return Promise.reject(new Error(message))
}
/** 接受邀请 */
export async function acceptInvite(inviteId: number) {
const res = await request.post<ApiResult<unknown>>(BASE + `/invites/${inviteId}/accept`)
if (res.data.code === 0 || res.data.code === 200) return res.data.message
return Promise.reject(new Error(res.data.message))
}
/** 拒绝邀请 */
export async function rejectInvite(inviteId: number) {
const res = await request.post<ApiResult<unknown>>(BASE + `/invites/${inviteId}/reject`)
if (res.data.code === 0 || res.data.code === 200) return res.data.message
return Promise.reject(new Error(res.data.message))
}
// ============ 权限相关 ============
/**
* 检查当前用户是否有开发者中心访问权限
* 返回accessible是否有权限、isPlatformDeveloper是否平台级开发者、apps可访问应用列表
*/
export async function checkAppAccess() {
const res = await request.get<ApiResult<CheckAccessResult>>(BASE + '/check-access')
if (res.data.code === 0 && res.data.data) return res.data.data
// 兼容 code=200
if (res.data.code === 200 && res.data.data) return res.data.data
return Promise.reject(new Error(res.data.message))
}

View File

@@ -0,0 +1,54 @@
import type { PageParam } from '@/api'
/** 应用成员角色 */
export type AppRole = 'owner' | 'admin' | 'developer' | 'viewer'
export interface AppUser {
id?: number
appId?: number
userId?: number
username?: string
avatar?: string
role?: AppRole
inviteBy?: number
inviteTime?: string
inviteExpireTime?: string
sortNumber?: number
status?: number
inviteStatus?: number // 0-正常(直接加入), 1-待确认, 2-已拒绝
tenantId?: number
createTime?: string
updateTime?: string
// 关联字段(来自 sys_user
nickname?: string
userAvatar?: string
phone?: string
// 关联字段(来自 app_product
productName?: string
productCode?: string
icon?: string
}
export interface AppUserParam extends PageParam {
appId?: number
userId?: number
role?: string
status?: number
username?: string
}
/** 用户在某应用中的权限信息check-access / accessible 接口返回) */
export interface AppPermissionInfo {
appId: number
productName: string
productCode?: string
icon?: string
role: AppRole
}
/** check-access 接口返回 */
export interface CheckAccessResult {
accessible: boolean
isPlatformDeveloper: boolean
apps?: AppPermissionInfo[]
}

View File

@@ -0,0 +1,62 @@
import request from '@/utils/request'
import type { ApiResult, PageResult } from '@/api'
import type { AppVersion, AppVersionParam } from './model'
import {APP_API_URL} from '@/config/setting'
const BASE = APP_API_URL + '/app-version'
/** 分页查询版本 */
export async function pageAppVersion(params: AppVersionParam) {
const res = await request.get<ApiResult<PageResult<AppVersion>>>(BASE + '/page', { params })
if (res.data.code === 0) return res.data.data
return Promise.reject(new Error(res.data.message))
}
/** 查询全部版本 */
export async function listAppVersion(params?: AppVersionParam) {
const res = await request.get<ApiResult<AppVersion[]>>(BASE, { params })
if (res.data.code === 0 && res.data.data) return res.data.data
return Promise.reject(new Error(res.data.message))
}
/** 获取当前版本 */
export async function getCurrentVersion(productId: number) {
const res = await request.get<ApiResult<AppVersion>>(BASE + '/current/' + productId)
if (res.data.code === 0) return res.data.data
return Promise.reject(new Error(res.data.message))
}
/** 新增版本 */
export async function addAppVersion(data: AppVersion) {
const res = await request.post<ApiResult<unknown>>(BASE, data)
if (res.data.code === 0) return res.data.message
return Promise.reject(new Error(res.data.message))
}
/** 修改版本 */
export async function updateAppVersion(data: AppVersion) {
const res = await request.put<ApiResult<unknown>>(BASE, data)
if (res.data.code === 0) return res.data.message
return Promise.reject(new Error(res.data.message))
}
/** 发布版本 */
export async function publishAppVersion(id: number) {
const res = await request.post<ApiResult<unknown>>(BASE + '/publish/' + id)
if (res.data.code === 0) return res.data.message
return Promise.reject(new Error(res.data.message))
}
/** 回滚到指定版本 */
export async function rollbackAppVersion(id: number) {
const res = await request.post<ApiResult<unknown>>(BASE + '/rollback/' + id)
if (res.data.code === 0) return res.data.message
return Promise.reject(new Error(res.data.message))
}
/** 删除版本 */
export async function removeAppVersion(id: number) {
const res = await request.delete<ApiResult<unknown>>(BASE + '/' + id)
if (res.data.code === 0) return res.data.message
return Promise.reject(new Error(res.data.message))
}

View File

@@ -0,0 +1,32 @@
import type { PageParam } from '@/api'
export interface AppVersion {
id?: number
appId?: number
versionNo?: string
versionName?: string
changelog?: string
packageUrl?: string
packageSize?: number
packageHash?: string
env?: string
status?: number
isCurrent?: boolean
publishBy?: number
publishTime?: string
remark?: string
sortNumber?: number
userId?: number
tenantId?: number
createTime?: string
updateTime?: string
// 关联字段
productName?: string
}
export interface AppVersionParam extends PageParam {
appId?: number
env?: string
status?: number
isCurrent?: boolean
}

View File

@@ -0,0 +1,58 @@
import request from '@/utils/request'
import type { ApiResult, PageResult } from '@/api'
import type { AppArticle, AppArticleParam, AppArticleCount } from './model'
import { APP_API_URL } from '@/config/setting'
const BASE = APP_API_URL + '/article'
function isSuccess(code?: number) {
return code === 0 || code === 200
}
export async function pageAppArticle(params: AppArticleParam) {
const res = await request.get<ApiResult<PageResult<AppArticle>>>(BASE + '/page', { params })
if (isSuccess(res.data.code)) return res.data.data
return Promise.reject(new Error(res.data.message))
}
export async function listAppArticle(params?: AppArticleParam) {
const res = await request.get<ApiResult<AppArticle[]>>(BASE, { params })
if (isSuccess(res.data.code) && res.data.data) return res.data.data
return Promise.reject(new Error(res.data.message))
}
export async function addAppArticle(data: AppArticle) {
const res = await request.post<ApiResult<unknown>>(BASE, data)
if (isSuccess(res.data.code)) return res.data.message
return Promise.reject(new Error(res.data.message))
}
export async function updateAppArticle(data: AppArticle) {
const res = await request.put<ApiResult<unknown>>(BASE, data)
if (isSuccess(res.data.code)) return res.data.message
return Promise.reject(new Error(res.data.message))
}
export async function removeAppArticle(id?: number) {
const res = await request.delete<ApiResult<unknown>>(BASE + '/' + id)
if (isSuccess(res.data.code)) return res.data.message
return Promise.reject(new Error(res.data.message))
}
export async function getAppArticle(id: number) {
const res = await request.get<ApiResult<AppArticle>>(BASE + '/' + id)
if (isSuccess(res.data.code) && res.data.data) return res.data.data
return Promise.reject(new Error(res.data.message))
}
export async function getAppArticleByCode(code: string) {
const res = await request.get<ApiResult<AppArticle>>(BASE + '/getByCode/' + code)
if (isSuccess(res.data.code) && res.data.data) return res.data.data
return Promise.reject(new Error(res.data.message))
}
export async function getAppArticleCount(params: AppArticleParam) {
const res = await request.get<ApiResult<AppArticleCount>>(BASE + '/data', { params })
if (isSuccess(res.data.code)) return res.data.data
return Promise.reject(new Error(res.data.message))
}

View File

@@ -0,0 +1,43 @@
import type { PageParam } from '@/api'
export interface AppArticle {
articleId?: number
title?: string
type?: number
model?: string
code?: string
categoryId?: number
categoryName?: string
parentId?: number
image?: string
source?: string
overview?: string
content?: string
actualViews?: number
likes?: number
userId?: number
author?: string
recommend?: number
sortNumber?: number
status?: number
deleted?: number
tenantId?: number
createTime?: string
updateTime?: string
}
export interface AppArticleParam extends PageParam {
articleId?: number
model?: string
status?: number
categoryId?: number
recommend?: number
keywords?: string
tenantId?: number
}
export interface AppArticleCount {
totalNum?: number
publishedNum?: number
recommendNum?: number
}

View File

@@ -0,0 +1,46 @@
import request from '@/utils/request'
import type { ApiResult, PageResult } from '@/api'
import type { AppArticleCategory, AppArticleCategoryParam } from './model'
import { APP_API_URL } from '@/config/setting'
const BASE = APP_API_URL + '/article-category'
function isSuccess(code?: number) {
return code === 0 || code === 200
}
export async function pageAppArticleCategory(params: AppArticleCategoryParam) {
const res = await request.get<ApiResult<PageResult<AppArticleCategory>>>(BASE + '/page', { params })
if (isSuccess(res.data.code)) return res.data.data
return Promise.reject(new Error(res.data.message))
}
export async function listAppArticleCategory(params?: AppArticleCategoryParam) {
const res = await request.get<ApiResult<AppArticleCategory[]>>(BASE, { params })
if (isSuccess(res.data.code) && res.data.data) return res.data.data
return Promise.reject(new Error(res.data.message))
}
export async function addAppArticleCategory(data: AppArticleCategory) {
const res = await request.post<ApiResult<unknown>>(BASE, data)
if (isSuccess(res.data.code)) return res.data.message
return Promise.reject(new Error(res.data.message))
}
export async function updateAppArticleCategory(data: AppArticleCategory) {
const res = await request.put<ApiResult<unknown>>(BASE, data)
if (isSuccess(res.data.code)) return res.data.message
return Promise.reject(new Error(res.data.message))
}
export async function removeAppArticleCategory(id?: number) {
const res = await request.delete<ApiResult<unknown>>(BASE + '/' + id)
if (isSuccess(res.data.code)) return res.data.message
return Promise.reject(new Error(res.data.message))
}
export async function getAppArticleCategory(id: number) {
const res = await request.get<ApiResult<AppArticleCategory>>(BASE + '/' + id)
if (isSuccess(res.data.code) && res.data.data) return res.data.data
return Promise.reject(new Error(res.data.message))
}

View File

@@ -0,0 +1,33 @@
import type { PageParam } from '@/api'
export interface AppArticleCategory {
categoryId?: number
categoryCode?: string
title?: string
type?: number
image?: string
parentId?: number
path?: string
userId?: number
count?: number
sortNumber?: number
comments?: string
description?: string
hide?: number
recommend?: number
showIndex?: number
status?: number
deleted?: number
tenantId?: number
createTime?: string
updateTime?: string
value?: number
label?: string
}
export interface AppArticleCategoryParam extends PageParam {
categoryId?: number
status?: number
keywords?: string
tenantId?: number
}

307
app/api/app/cicd.ts Normal file
View File

@@ -0,0 +1,307 @@
import request from '@/utils/request'
// ========== 流水线 API ==========
/**
* 分页查询流水线
*/
export function pagePipeline(params?: {
page?: number
limit?: number
appId?: number
ciType?: string
enabled?: boolean
}) {
return request.get<{
code: number
message: string
data: {
records: AppPipeline[]
total: number
}
}>('/api/app/cicd/pipeline/page', { params })
}
/**
* 查询应用的所有流水线
*/
export function listPipelineByApp(appId: number) {
return request.get<{
code: number
message: string
data: AppPipeline[]
}>('/api/app/cicd/pipeline/app/' + appId)
}
/**
* 查询流水线详情
*/
export function getPipeline(id: number) {
return request.get<{
code: number
message: string
data: AppPipeline
}>('/api/app/cicd/pipeline/' + id)
}
/**
* 创建流水线
*/
export function createPipeline(data: Partial<AppPipeline>) {
return request.post<{
code: number
message: string
}>('/api/app/cicd/pipeline', data)
}
/**
* 更新流水线
*/
export function updatePipeline(data: Partial<AppPipeline>) {
return request.put<{
code: number
message: string
}>('/api/app/cicd/pipeline', data)
}
/**
* 删除流水线
*/
export function deletePipeline(id: number) {
return request.delete<{
code: number
message: string
}>('/api/app/cicd/pipeline/' + id)
}
/**
* 启用/禁用流水线
*/
export function togglePipeline(id: number, enabled: boolean) {
return request.post<{
code: number
message: string
}>('/api/app/cicd/pipeline/' + id + '/toggle?enabled=' + enabled)
}
/**
* 获取流水线状态
*/
export function getPipelineStatus(id: number) {
return request.get<{
code: number
message: string
data: {
id: number
status: string
lastBuildId?: number
lastBuildTime?: string
successCount: number
failureCount: number
}
}>('/api/app/cicd/pipeline/' + id + '/status')
}
// ========== 构建 API ==========
/**
* 分页查询构建记录
*/
export function pageBuild(params?: {
page?: number
limit?: number
appId?: number
status?: string
ciType?: string
branch?: string
}) {
return request.get<{
code: number
message: string
data: {
records: AppBuild[]
total: number
}
}>('/api/app/cicd/build/page', { params })
}
/**
* 查询应用的所有构建记录
*/
export function listBuildByApp(appId: number) {
return request.get<{
code: number
message: string
data: AppBuild[]
}>('/api/app/cicd/build/app/' + appId)
}
/**
* 查询构建详情
*/
export function getBuild(id: number) {
return request.get<{
code: number
message: string
data: AppBuild
}>('/api/app/cicd/build/' + id)
}
/**
* 获取应用最新构建
*/
export function getLatestBuild(appId: number) {
return request.get<{
code: number
message: string
data: AppBuild | null
}>('/api/app/cicd/build/latest/' + appId)
}
/**
* 触发构建
*/
export function triggerBuild(appId: number, branch?: string) {
return request.post<{
code: number
message: string
data: {
id: number
buildNumber: string
status: string
branch: string
}
}>('/api/app/cicd/build/trigger', null, {
params: { appId, branch }
})
}
/**
* 获取构建日志
*/
export function getBuildLog(id: number) {
return request.get<{
code: number
message: string
data: {
log: string
buildId: number
}
}>('/api/app/cicd/build/' + id + '/log')
}
/**
* 取消构建
*/
export function cancelBuild(id: number) {
return request.post<{
code: number
message: string
}>('/api/app/cicd/build/' + id + '/cancel')
}
/**
* 重试构建
*/
export function retryBuild(id: number) {
return request.post<{
code: number
message: string
data: {
id: number
buildNumber: string
status: string
}
}>('/api/app/cicd/build/' + id + '/retry')
}
/**
* 获取构建统计
*/
export function getBuildStats(appId: number) {
return request.get<{
code: number
message: string
data: {
total: number
success: number
failed: number
running: number
}
}>('/api/app/cicd/build/stats/' + appId)
}
/**
* 获取CI系统配置
*/
export function getCIConfig() {
return request.get<{
code: number
message: string
data: {
supportedCI: string[]
defaultCI: string
giteaUrl: string
}
}>('/api/app/cicd/config')
}
// ========== 类型定义 ==========
export interface AppPipeline {
id?: number
appId?: number
name?: string
description?: string
ciType?: 'gitea' | 'jenkins' | 'github'
repoFullName?: string
workflowFile?: string
stages?: string
env?: 'development' | 'staging' | 'production'
defaultBranch?: string
enabled?: boolean
autoDeploy?: boolean
timeout?: number
config?: string
lastBuildId?: number
lastBuildStatus?: string
lastBuildTime?: string
successCount?: number
failureCount?: number
userId?: number
tenantId?: number
createTime?: string
updateTime?: string
}
export interface AppBuild {
id?: number
appId?: number
versionId?: number
buildNumber?: string
name?: string
branch?: string
commitSha?: string
commitMessage?: string
commitAuthor?: string
ciType?: 'gitea' | 'jenkins' | 'github'
ciJobId?: string
ciRunId?: string
ciApiUrl?: string
status?: 'pending' | 'running' | 'success' | 'failed' | 'cancelled'
startedAt?: string
finishedAt?: string
duration?: number
logUrl?: string
artifactUrl?: string
artifactName?: string
artifactSize?: number
errorMessage?: string
triggerType?: 'manual' | 'webhook' | 'schedule'
triggeredBy?: number
config?: string
userId?: number
tenantId?: number
createTime?: string
updateTime?: string
}

View File

@@ -0,0 +1,76 @@
import request from '@/utils/request'
import type { ApiResult, PageResult } from '@/api'
import type { AppCloudCredential, AppCloudCredentialParam } from './model'
import {
CLOUD_PROVIDER_OPTIONS,
getProviderLabel,
getProviderIcon,
} from './model'
// 重新导出,保持向后兼容
export { CLOUD_PROVIDER_OPTIONS, getProviderLabel, getProviderIcon }
const BASE = '/api/app/cloud-credential'
/**
* 分页查询云账号凭证
*/
export async function pageCloudCredential(params?: AppCloudCredentialParam) {
const res = await request.get<ApiResult<PageResult<AppCloudCredential>>>(BASE + '/page', { params })
if (res.data.code === 200 || res.data.code === 0) return res.data.data
return Promise.reject(new Error(res.data.message))
}
/**
* 查询用户全部云账号凭证
*/
export async function listCloudCredential(provider?: string) {
const res = await request.get<ApiResult<AppCloudCredential[]>>(BASE, { params: { provider } })
if ((res.data.code === 200 || res.data.code === 0) && res.data.data) return res.data.data
return Promise.reject(new Error(res.data.message))
}
/**
* 根据ID查询云账号凭证
*/
export async function getCloudCredential(id: number) {
const res = await request.get<ApiResult<AppCloudCredential>>(BASE + '/' + id)
if ((res.data.code === 200 || res.data.code === 0) && res.data.data) return res.data.data
return Promise.reject(new Error(res.data.message))
}
/**
* 创建云账号凭证
*/
export async function createCloudCredential(data: AppCloudCredential) {
const res = await request.post<ApiResult<AppCloudCredential>>(BASE, data)
if (res.data.code === 200 || res.data.code === 0) return res.data.data
return Promise.reject(new Error(res.data.message))
}
/**
* 修改云账号凭证
*/
export async function updateCloudCredential(data: AppCloudCredential) {
const res = await request.put<ApiResult<unknown>>(BASE, data)
if (res.data.code === 200 || res.data.code === 0) return res.data.message
return Promise.reject(new Error(res.data.message))
}
/**
* 删除云账号凭证
*/
export async function removeCloudCredential(id: number) {
const res = await request.delete<ApiResult<unknown>>(BASE + '/' + id)
if (res.data.code === 200 || res.data.code === 0) return res.data.message
return Promise.reject(new Error(res.data.message))
}
/**
* 测试云账号凭证连接
*/
export async function testCloudCredential(id: number) {
const res = await request.post<ApiResult<{ success: boolean; message: string }>>(BASE + '/test/' + id)
if (res.data.code === 200 || res.data.code === 0) return res.data.data
return Promise.reject(new Error(res.data.message))
}

View File

@@ -0,0 +1,61 @@
import type { PageParam } from '@/api'
/**
* 云账号凭证
*/
export interface AppCloudCredential {
id?: number
userId?: number
tenantId?: number
name?: string
provider?: string // aliyun/tencent/huawei/qiniu
accessKeyId?: string // AK
accessKeySecret?: string // SK (AES加密存储)
status?: number // 0-禁用 1-启用
testStatus?: number // 0-未测试 1-测试成功 2-测试失败
testMessage?: string
remark?: string
deleted?: number
createTime?: string
updateTime?: string
}
/**
* 查询参数
*/
export interface AppCloudCredentialParam extends PageParam {
provider?: string
status?: number
name?: string
}
/**
* 云服务商选项
*/
export const CLOUD_PROVIDER_OPTIONS = [
{ label: '阿里云 OSS', value: 'aliyun', icon: '🟢' },
{ label: '腾讯云 COS', value: 'tencent', icon: '🔵' },
{ label: '华为云 OBS', value: 'huawei', icon: '🟠' },
{ label: '七牛云 Kodo', value: 'qiniu', icon: '🟡' },
]
/**
* 获取云服务商显示文本
*/
export function getProviderLabel(provider: string) {
const opt = CLOUD_PROVIDER_OPTIONS.find((i) => i.value === provider)
return opt ? `${opt.icon} ${opt.label}` : provider
}
/**
* 获取云服务商图标
*/
export function getProviderIcon(provider: string) {
const iconMap: Record<string, string> = {
aliyun: '🟢',
tencent: '🔵',
huawei: '🟠',
qiniu: '🟡',
}
return iconMap[provider] || '☁️'
}

View File

@@ -0,0 +1,75 @@
import request from '@/utils/request'
/**
* 生成二维码邀请
*/
export function generateInviteQrCode(data: {
appId: number
role: string
}) {
return request.post<{
code: number
message: string
data: {
qrCodeUrl: string
inviteUrl: string // 邀请链接,用于前端生成二维码
token: string
expireTime: string
}
}>('/api/app/developer/invite/qrcode', data)
}
/**
* 生成链接邀请
*/
export function generateInviteLink(data: {
appId: number
role: string
}) {
return request.post<{
code: number
message: string
data: {
inviteUrl: string
token: string
expireTime: string
}
}>('/api/app/developer/invite/link', data)
}
/**
* 验证邀请
*/
export function verifyInvite(data: {
token: string
appId?: number
}) {
return request.post<{
code: number
message: string
data: {
valid: boolean
appId: number
appName: string
role: string
inviterName: string
inviterAvatar?: string
expireTime: string
}
}>('/api/app/developer/invite/verify', data)
}
/**
* 接受邀请
*/
export function acceptInvite(data: {
token: string
appId?: number
role?: string
}) {
return request.post<{
code: number
message: string
data: null
}>('/api/app/developer/invite/accept', data)
}

View File

@@ -0,0 +1,55 @@
import request from '@/utils/request'
import type { ApiResult, PageResult } from '@/api'
import type { Notification, NotificationParam, UnreadCountResult } from './model'
import { APP_API_URL } from '@/config/setting'
const BASE = APP_API_URL + '/notification'
/** 分页查询通知列表 */
export async function pageNotification(params: NotificationParam) {
const res = await request.get<ApiResult<PageResult<Notification>>>(BASE + '/page', { params })
if (res.data.code === 0) return res.data.data
return Promise.reject(new Error(res.data.message))
}
/** 查询最近通知(用于铃铛下拉,最多 20 条) */
export async function listRecentNotification(params?: { type?: string; limit?: number }) {
const res = await request.get<ApiResult<Notification[]>>(BASE + '/recent', { params })
if (res.data.code === 0 && res.data.data) return res.data.data
return Promise.reject(new Error(res.data.message))
}
/** 获取未读数量统计 */
export async function getUnreadCount() {
const res = await request.get<ApiResult<UnreadCountResult>>(BASE + '/unread-count')
if (res.data.code === 0 && res.data.data) return res.data.data
return Promise.reject(new Error(res.data.message))
}
/** 标记单条通知为已读 */
export async function markRead(id: number) {
const res = await request.put<ApiResult<unknown>>(BASE + `/read/${id}`)
if (res.data.code === 0) return res.data.message
return Promise.reject(new Error(res.data.message))
}
/** 标记全部已读 */
export async function markAllRead(data?: { type?: string }) {
const res = await request.put<ApiResult<unknown>>(BASE + '/read-all', data)
if (res.data.code === 0) return res.data.message
return Promise.reject(new Error(res.data.message))
}
/** 删除单条通知 */
export async function removeNotification(id: number) {
const res = await request.delete<ApiResult<unknown>>(BASE + '/' + id)
if (res.data.code === 0) return res.data.message
return Promise.reject(new Error(res.data.message))
}
/** 清空全部已读通知 */
export async function clearReadNotifications(data?: { type?: string }) {
const res = await request.delete<ApiResult<unknown>>(BASE + '/clear-read', { data })
if (res.data.code === 0) return res.data.message
return Promise.reject(new Error(res.data.message))
}

View File

@@ -0,0 +1,60 @@
import type { PageParam } from '@/api'
/** 通知类型枚举 */
export type NotificationType = 'ticket' | 'review' | 'system' | 'resource' | 'permission' | 'member' | 'payment'
/** 通知实体 */
export interface Notification {
/** 通知 ID */
id?: number
/** 接收用户 ID */
userId?: number
/** 通知类型 */
type?: NotificationType
/** 通知标题 */
title?: string
/** 通知内容摘要 */
content?: string
/** 是否已读0 未读1 已读 */
isRead?: number
/** 关联业务 ID如工单ID、权限申请ID等 */
refId?: number
/** 关联业务类型(如 ticket、permission_request 等) */
refType?: string
/** 跳转链接 */
linkUrl?: string
/** 发送者 ID系统通知为 0 */
senderId?: number
/** 发送者名称 */
senderName?: string
/** 发送者头像 */
senderAvatar?: string
/** 租户 ID */
tenantId?: number
/** 创建时间 */
createTime?: string
/** 更新时间(标记已读时间) */
updateTime?: string
}
/** 通知查询参数 */
export interface NotificationParam extends PageParam {
/** 通知类型筛选 */
type?: NotificationType | ''
/** 是否已读0 未读1 已读,不传查全部 */
isRead?: number
}
/** 未读统计 */
export interface UnreadCountResult {
/** 总未读数 */
total?: number
/** 各类型未读数 */
ticket?: number
review?: number
system?: number
resource?: number
permission?: number
member?: number
payment?: number
}

View File

@@ -0,0 +1,148 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { AppSetting } from './model';
/**
* 分页查询设置
*/
export async function pageSetting(params: any) {
const res = await request.get<ApiResult<PageResult<AppSetting>>>(
'/api/app/setting/page',
{ params }
);
// 兼容后端返回 0 或 200 作为成功码
if (res.data.code === 0 || res.data.code === 200) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 获取设置列表
*/
export async function listSetting(params?: any) {
const res = await request.get<ApiResult<AppSetting[]>>(
'/api/app/setting',
{ params }
);
// 兼容后端返回 0 或 200 作为成功码
if (res.data.code === 0 || res.data.code === 200) {
return res.data.data || [];
}
return Promise.reject(new Error(res.data.message));
}
/**
* 根据分类获取设置
*/
export async function getSettingsByCategory(category: string) {
const res = await request.get<ApiResult<AppSetting[]>>(
`/api/app/setting/category/${category}`
);
// 兼容后端返回 0 或 200 作为成功码
if (res.data.code === 0 || res.data.code === 200) {
return res.data.data || [];
}
return Promise.reject(new Error(res.data.message));
}
/**
* 获取分类设置值Map格式
*/
export async function getCategoryValues(category: string) {
const res = await request.get<ApiResult<Record<string, string>>>(
`/api/app/setting/category/${category}/values`
);
// 兼容后端返回 0 或 200 作为成功码
if (res.data.code === 0 || res.data.code === 200) {
return res.data.data || {};
}
return {};
}
/**
* 根据key获取设置值
*/
export async function getSettingValue(key: string) {
const res = await request.get<ApiResult<string>>(
`/api/app/setting/key/${key}`
);
// 兼容后端返回 0 或 200 作为成功码
if (res.data.code === 0 || res.data.code === 200) {
return res.data.data;
}
return null;
}
/**
* 根据key获取完整设置
*/
export async function getSettingByKey(key: string) {
const res = await request.get<ApiResult<AppSetting>>(
`/api/app/setting/info/${key}`
);
// 兼容后端返回 0 或 200 作为成功码
if (res.data.code === 0 || res.data.code === 200) {
return res.data.data;
}
return null;
}
/**
* 保存或更新设置
*/
export async function saveSetting(data: Partial<AppSetting>) {
const res = await request.post<ApiResult<unknown>>(
'/api/app/setting',
data
);
// 兼容后端返回 0 或 200 作为成功码
if (res.data.code === 0 || res.data.code === 200) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 更新设置
*/
export async function updateSetting(data: Partial<AppSetting>) {
const res = await request.put<ApiResult<unknown>>(
'/api/app/setting',
data
);
// 兼容后端返回 0 或 200 作为成功码
if (res.data.code === 0 || res.data.code === 200) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 批量保存分类设置
*/
export async function batchSaveCategory(category: string, values: Record<string, any>) {
const res = await request.post<ApiResult<unknown>>(
`/api/app/setting/batch/${category}`,
values
);
// 兼容后端返回 0 或 200 作为成功码
if (res.data.code === 0 || res.data.code === 200) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 删除设置
*/
export async function removeSetting(settingId: number) {
const res = await request.delete<ApiResult<unknown>>(
`/api/app/setting/${settingId}`
);
// 兼容后端返回 0 或 200 作为成功码
if (res.data.code === 0 || res.data.code === 200) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}

View File

@@ -0,0 +1,45 @@
/**
* 平台设置
*/
export interface AppSetting {
/** 设置ID */
settingId?: number;
/** 设置分类basic/review/market/register/notify/maintenance */
category?: string;
/** 设置项标识 */
settingKey?: string;
/** 设置项名称 */
settingName?: string;
/** 设置值JSON格式 */
settingValue?: string;
/** 设置类型string/number/boolean/json */
valueType?: string;
/** 设置说明 */
description?: string;
/** 排序号 */
sortNumber?: number;
/** 是否启用 0否 1是 */
isEnabled?: number;
/** 是否公开前端可读0否 1是 */
isPublic?: number;
/** 租户id */
tenantId?: number;
/** 创建时间 */
createdTime?: number;
/** 更新时间 */
updatedTime?: number;
}
/**
* 平台设置查询参数
*/
export interface AppSettingParam {
settingId?: number;
category?: string;
settingKey?: string;
settingName?: string;
valueType?: string;
isEnabled?: number;
isPublic?: number;
tenantId?: number;
}

106
app/api/cms/cmsAd/index.ts Normal file
View File

@@ -0,0 +1,106 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { CmsAd, CmsAdParam } from './model';
import { MODULES_API_URL } from '@/config/setting';
/**
* 分页查询广告位
*/
export async function pageCmsAd(params: CmsAdParam) {
const res = await request.get<ApiResult<PageResult<CmsAd>>>(
MODULES_API_URL + '/cms/cms-ad/page',
{
params
}
);
if (res.data.code === 0) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 查询广告位列表
*/
export async function listCmsAd(params?: CmsAdParam) {
const res = await request.get<ApiResult<CmsAd[]>>(
MODULES_API_URL + '/cms/cms-ad',
{
params
}
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 添加广告位
*/
export async function addCmsAd(data: CmsAd) {
const res = await request.post<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-ad',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 修改广告位
*/
export async function updateCmsAd(data: CmsAd) {
const res = await request.put<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-ad',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 删除广告位
*/
export async function removeCmsAd(id?: number) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-ad/' + id
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 批量删除广告位
*/
export async function removeBatchCmsAd(data: (number | undefined)[]) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-ad/batch',
{
data
}
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 根据id查询广告位
*/
export async function getCmsAd(id: number) {
const res = await request.get<ApiResult<CmsAd>>(
MODULES_API_URL + '/cms/cms-ad/' + id
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}

View File

@@ -0,0 +1,65 @@
import type { PageParam } from '@/api';
/**
* 广告位
*/
export interface CmsAd {
// ID
adId?: number;
// 类型
type?: number;
// 唯一标识
code?: string;
// 栏目分类
categoryId?: number;
// 栏目名称
categoryName?: string;
// 页面ID
designId?: number;
// 广告类型
adType?: string;
// 广告位名称
name?: string;
// 宽
width?: string;
// 高
height?: string;
// css样式
style?: string;
// 广告图片
images?: any;
// 广告图片
imageList?: any;
// 路由/链接地址
path?: string;
// 用户ID
userId?: number;
// 语言
lang?: string;
// 页面ID
pageId?: number;
// 页面名称
pageName?: string;
// 排序(数字越小越靠前)
sortNumber?: number;
// 备注
description?: string;
// 状态, 0正常, 1冻结
status?: number;
// 是否删除, 0否, 1是
deleted?: number;
// 租户id
tenantId?: number;
// 创建时间
createTime?: string;
merchantId?: number;
}
/**
* 广告位搜索条件
*/
export interface CmsAdParam extends PageParam {
adId?: number;
pageId?: number;
keywords?: string;
}

View File

@@ -0,0 +1,106 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { CmsAdRecord, CmsAdRecordParam } from './model';
import { MODULES_API_URL } from '@/config/setting';
/**
* 分页查询广告图片
*/
export async function pageCmsAdRecord(params: CmsAdRecordParam) {
const res = await request.get<ApiResult<PageResult<CmsAdRecord>>>(
MODULES_API_URL + '/cms/cms-ad-record/page',
{
params
}
);
if (res.data.code === 0) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 查询广告图片列表
*/
export async function listCmsAdRecord(params?: CmsAdRecordParam) {
const res = await request.get<ApiResult<CmsAdRecord[]>>(
MODULES_API_URL + '/cms/cms-ad-record',
{
params
}
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 添加广告图片
*/
export async function addCmsAdRecord(data: CmsAdRecord) {
const res = await request.post<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-ad-record',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 修改广告图片
*/
export async function updateCmsAdRecord(data: CmsAdRecord) {
const res = await request.put<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-ad-record',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 删除广告图片
*/
export async function removeCmsAdRecord(id?: number) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-ad-record/' + id
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 批量删除广告图片
*/
export async function removeBatchCmsAdRecord(data: (number | undefined)[]) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-ad-record/batch',
{
data
}
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 根据id查询广告图片
*/
export async function getCmsAdRecord(id: number) {
const res = await request.get<ApiResult<CmsAdRecord>>(
MODULES_API_URL + '/cms/cms-ad-record/' + id
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}

View File

@@ -0,0 +1,35 @@
import type { PageParam } from '@/api';
/**
* 广告图片
*/
export interface CmsAdRecord {
// ID
adRecordId?: number;
// 广告标题
title?: string;
// 图片地址
path?: string;
// 链接地址
url?: string;
// 广告位ID
adId?: number;
// 排序(数字越小越靠前)
sortNumber?: number;
// 备注
description?: string;
// 状态, 0正常, 1冻结
status?: number;
// 租户id
tenantId?: number;
// 创建时间
createTime?: string;
}
/**
* 广告图片搜索条件
*/
export interface CmsAdRecordParam extends PageParam {
adRecordId?: number;
keywords?: string;
}

View File

@@ -0,0 +1,120 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { CmsAppConfig, CmsAppConfigParam, BatchSaveRequest } from './model';
import {MODULES_API_URL} from '@/config/setting';
/**
* 分页查询应用配置
*/
export async function pageCmsAppConfig(params: CmsAppConfigParam) {
const res = await request.get<ApiResult<PageResult<CmsAppConfig>>>(
MODULES_API_URL + '/cms/cms-app-config/page',
{
params
}
);
if (res.data.code === 0) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 获取应用配置列表
*/
export async function listCmsAppConfig(params?: CmsAppConfigParam) {
const res = await request.get<ApiResult<CmsAppConfig[]>>(
MODULES_API_URL + '/cms/cms-app-config/list',
{
params
}
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 根据应用ID获取配置映射
*/
export async function getConfigsMap(productId: number) {
const res = await request.get<ApiResult<Record<string, any>>>(
MODULES_API_URL + `/cms/cms-app-config/map/${productId}`
);
if (res.data.code === 0) {
return res.data.data || {};
}
return Promise.reject(new Error(res.data.message));
}
/**
* 获取单个配置值
*/
export async function getConfigValue(productId: number, configKey: string) {
const res = await request.get<ApiResult<string>>(
MODULES_API_URL + '/cms/cms-app-config/value',
{
params: { productId, configKey }
}
);
if (res.data.code === 0) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 保存配置
*/
export async function saveCmsAppConfig(data: CmsAppConfig) {
const res = await request.post<ApiResult<void>>(
MODULES_API_URL + '/cms/cms-app-config',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 批量保存配置
*/
export async function batchSaveCmsAppConfig(data: BatchSaveRequest) {
const res = await request.post<ApiResult<void>>(
MODULES_API_URL + '/cms/cms-app-config/batch',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 更新配置
*/
export async function updateCmsAppConfig(data: CmsAppConfig) {
const res = await request.put<ApiResult<void>>(
MODULES_API_URL + '/cms/cms-app-config',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 删除配置
*/
export async function deleteCmsAppConfig(configId: number) {
const res = await request.delete<ApiResult<void>>(
MODULES_API_URL + `/cms/cms-app-config/${configId}`
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}

View File

@@ -0,0 +1,66 @@
import type { PageParam } from '@/api';
import type { PageResult } from '@/api';
/**
* 应用配置
*/
export interface CmsAppConfig {
configId?: number;
productId?: number;
configKey?: string;
configValue?: string;
configType?: string;
isEncrypted?: number;
isSecret?: number;
description?: string;
sortNumber?: number;
tenantId?: number;
createdTime?: string;
updatedTime?: string;
deleted?: number;
}
/**
* 应用配置查询参数
*/
export interface CmsAppConfigParam extends PageParam {
configId?: number;
productId?: number;
configKey?: string;
configType?: string;
isSecret?: number;
}
/**
* 批量保存请求
*/
export interface BatchSaveRequest {
productId: number;
configs: CmsAppConfig[];
}
/**
* 配置类型定义
*/
export interface ConfigType {
key: string;
name: string;
icon: string;
description: string;
configs: ConfigField[];
}
/**
* 配置字段定义
*/
export interface ConfigField {
key: string;
label: string;
type: 'input' | 'textarea' | 'number' | 'select' | 'switch' | 'password' | 'json';
required?: boolean;
placeholder?: string;
options?: Array<{ label: string; value: any }>;
defaultValue?: any;
description?: string;
secret?: boolean;
}

View File

@@ -0,0 +1,162 @@
import request from '@/utils/request';
import type {ApiResult, PageResult} from '@/api';
import type {CmsArticle, CmsArticleParam} from './model';
function isSuccess(code?: number) {
return code === 0 || code === 200;
}
/**
* 分页查询文章
*/
export async function pageCmsArticle(params: CmsArticleParam) {
const res = await request.get<ApiResult<PageResult<CmsArticle>>>(
'/api/cms/cms-article/page',
{
params
}
);
if (isSuccess(res.data.code)) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 查询文章列表
*/
export async function listCmsArticle(params?: CmsArticleParam) {
const res = await request.get<ApiResult<CmsArticle[]>>(
'/api/cms/cms-article',
{
params
}
);
if (isSuccess(res.data.code) && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 添加文章
*/
export async function addCmsArticle(data: CmsArticle) {
const res = await request.post<ApiResult<unknown>>(
'/api/cms/cms-article',
data
);
if (isSuccess(res.data.code)) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 修改文章
*/
export async function updateCmsArticle(data: CmsArticle) {
const res = await request.put<ApiResult<unknown>>(
'/api/cms/cms-article',
data
);
if (isSuccess(res.data.code)) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 批量修改文章
*/
export async function updateBatchCmsArticle(data: any) {
const res = await request.put<ApiResult<unknown>>(
'/api/cms/cms-article/batch',
data
);
if (isSuccess(res.data.code)) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 删除文章
*/
export async function removeCmsArticle(id?: number) {
const res = await request.delete<ApiResult<unknown>>(
'/api/cms/cms-article/' + id
);
if (isSuccess(res.data.code)) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 批量删除文章
*/
export async function removeBatchCmsArticle(data: (number | undefined)[]) {
const res = await request.delete<ApiResult<unknown>>(
'/api/cms/cms-article/batch',
{
data
}
);
if (isSuccess(res.data.code)) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 根据id查询文章
*/
export async function getCmsArticle(id: number) {
const res = await request.get<ApiResult<CmsArticle>>(
'/api/cms/cms-article/' + id
);
if (isSuccess(res.data.code) && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 根据code查询文章
*/
export async function getByCode(code: string) {
const res = await request.get<ApiResult<CmsArticle>>(
'/api/cms/cms-article/getByCode/' + code
);
if (isSuccess(res.data.code) && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
export async function getCount(params: CmsArticleParam) {
const res = await request.get('/api/cms/cms-article/data', {
params
});
if (isSuccess(res.data.code)) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 文章批量导入
*/
export async function importArticles(file: File) {
const formData = new FormData();
formData.append('file', file);
const res = await request.post<ApiResult<unknown>>(
'/api/cms/cms-article/import',
formData
);
if (isSuccess(res.data.code)) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}

View File

@@ -0,0 +1,133 @@
import type { PageParam } from '@/api';
/**
* 文章
*/
export interface CmsArticle {
// 文章ID
articleId?: number;
// 文章标题
title?: string;
// 文章类型 0常规 1视频
type?: number;
// 文章模型
model?: string;
// 文章编号
code?: string;
// 文章详情
detail?: string;
// 列表显示方式(10小图展示 20大图展示)
showType?: number;
// 话题
topic?: string;
// 标签
tags?: any;
// 父级ID
parentId?: number;
parentName?: string;
// 栏目ID
categoryId?: number;
// 栏目名称
categoryName?: string;
// 封面图
image?: string;
// 来源
source?: string;
// 摘要
overview?: string;
// 虚拟阅读量(仅用作展示)
virtualViews?: number;
// 实际阅读量
actualViews?: number;
// 浏览权限(0公开 1会员 2密码)
permission?: number;
// 访问密码
password?: string;
// 确认密码
password2?: string;
// 发布来源客户端 (APP、H5、小程序等)
platform?: string;
// 文章附件
files?: string;
// 视频地址
video?: string;
// 接受的文件类型
accept?: string;
// 经度
longitude?: string;
// 纬度
latitude?: string;
// 所在省份
province?: string;
// 所在城市
city?: string;
// 所在辖区
region?: string;
// 街道地址
address?: string;
// 点赞数
likes?: number;
// 评论数
commentNumbers?: number;
// 提醒谁看
toUsers?: string;
// 文章内容
content?: string;
// 编辑器类型
editor?: number;
// PDF地址
pdfUrl?: string;
// 用户ID
userId?: number;
// 商户ID
merchantId?: number;
// 作者
author?: string;
// 语言
lang?: string;
// 是否推荐
recommend?: number;
// 是否同步翻译其他语言版本
translation?: boolean;
// 排序(数字越小越靠前)
sortNumber?: number;
// 备注
description?: string;
// 状态, 0已发布, 1待审核 2已驳回 3违规内容
status?: number;
// 状态描述
statusText?: string;
// 是否删除, 0否, 1是
deleted?: number;
// 租户id
tenantId?: number;
// 创建时间
createTime?: string;
// 修改时间
updateTime?: string;
// 是否移动端
isMobile?: boolean;
// 二维码
qrcode?: string;
// 文章路径
url?: string;
}
/**
* 文章搜索条件
*/
export interface CmsArticleParam extends PageParam {
articleId?: number;
model?: string;
status?: number;
categoryId?: number;
recommend?: number;
keywords?: string;
}
export interface CmsArticleCount {
totalNum?: number;
totalNum2?: number;
totalNum3?: number;
totalNum4?: number;
}

View File

@@ -0,0 +1,112 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { CmsArticleCategory, CmsArticleCategoryParam } from './model';
import { MODULES_API_URL } from '@/config/setting';
function isSuccess(code?: number) {
return code === 0 || code === 200;
}
/**
* 分页查询文章分类表
*/
export async function pageCmsArticleCategory(params: CmsArticleCategoryParam) {
const res = await request.get<ApiResult<PageResult<CmsArticleCategory>>>(
MODULES_API_URL + '/cms/cms-article-category/page',
{
params
}
);
if (isSuccess(res.data.code)) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 查询文章分类表列表
*/
export async function listCmsArticleCategory(params?: CmsArticleCategoryParam) {
const res = await request.get<ApiResult<CmsArticleCategory[]>>(
MODULES_API_URL + '/cms/cms-article-category',
{
params
}
);
if (isSuccess(res.data.code) && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 添加文章分类表
*/
export async function addCmsArticleCategory(data: CmsArticleCategory) {
const res = await request.post<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-article-category',
data
);
if (isSuccess(res.data.code)) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 修改文章分类表
*/
export async function updateCmsArticleCategory(data: CmsArticleCategory) {
const res = await request.put<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-article-category',
data
);
if (isSuccess(res.data.code)) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 删除文章分类表
*/
export async function removeCmsArticleCategory(id?: number) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-article-category/' + id
);
if (isSuccess(res.data.code)) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 批量删除文章分类表
*/
export async function removeBatchCmsArticleCategory(
data: (number | undefined)[]
) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-article-category/batch',
{
data
}
);
if (isSuccess(res.data.code)) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 根据id查询文章分类表
*/
export async function getCmsArticleCategory(id: number) {
const res = await request.get<ApiResult<CmsArticleCategory>>(
MODULES_API_URL + '/cms/cms-article-category/' + id
);
if (isSuccess(res.data.code) && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}

View File

@@ -0,0 +1,60 @@
import type { PageParam } from '@/api';
/**
* 文章分类表
*/
export interface CmsArticleCategory {
// 文章分类ID
categoryId?: number;
// 分类标识
categoryCode?: string;
// 分类名称
title?: string;
// 类型 0列表 1单页 2外链
type?: number;
// 分类图片
image?: string;
// 上级分类ID
parentId?: number;
// 路由/链接地址
path?: string;
// 组件路径
component?: string;
// 绑定的页面
pageId?: number;
// 用户ID
userId?: number;
// 文章数量
count?: number;
// 排序(数字越小越靠前)
sortNumber?: number;
// 备注
description?: string;
// 是否隐藏, 0否, 1是(仅注册路由不显示在左侧菜单)
hide?: number;
// 是否推荐
recommend?: number;
// 是否显示在首页
showIndex?: number;
// 状态, 0正常, 1禁用
status?: number;
// 是否删除, 0否, 1是
deleted?: number;
// 租户id
tenantId?: number;
// 创建时间
createTime?: string;
// 修改时间
updateTime?: string;
value?: number;
label?: string;
}
/**
* 文章分类表搜索条件
*/
export interface CmsArticleCategoryParam extends PageParam {
categoryId?: number;
status?: number;
keywords?: string;
}

View File

@@ -0,0 +1,106 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { CmsArticleComment, CmsArticleCommentParam } from './model';
import { MODULES_API_URL } from '@/config/setting';
/**
* 分页查询文章评论表
*/
export async function pageCmsArticleComment(params: CmsArticleCommentParam) {
const res = await request.get<ApiResult<PageResult<CmsArticleComment>>>(
MODULES_API_URL + '/cms/cms-article-comment/page',
{
params
}
);
if (res.data.code === 0) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 查询文章评论表列表
*/
export async function listCmsArticleComment(params?: CmsArticleCommentParam) {
const res = await request.get<ApiResult<CmsArticleComment[]>>(
MODULES_API_URL + '/cms/cms-article-comment',
{
params
}
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 添加文章评论表
*/
export async function addCmsArticleComment(data: CmsArticleComment) {
const res = await request.post<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-article-comment',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 修改文章评论表
*/
export async function updateCmsArticleComment(data: CmsArticleComment) {
const res = await request.put<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-article-comment',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 删除文章评论表
*/
export async function removeCmsArticleComment(id?: number) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-article-comment/' + id
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 批量删除文章评论表
*/
export async function removeBatchCmsArticleComment(data: (number | undefined)[]) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-article-comment/batch',
{
data
}
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 根据id查询文章评论表
*/
export async function getCmsArticleComment(id: number) {
const res = await request.get<ApiResult<CmsArticleComment>>(
MODULES_API_URL + '/cms/cms-article-comment/' + id
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}

View File

@@ -0,0 +1,47 @@
import type { PageParam } from '@/api';
/**
* 文章评论表
*/
export interface CmsArticleComment {
// 评价ID
commentId?: number;
// 文章ID
articleId?: number;
// 评分 (10好评 20中评 30差评)
score?: number;
// 评价内容
content?: string;
// 是否为图片评价
isPicture?: number;
// 评论者ID
userId?: number;
// 被评价者ID
toUserId?: number;
// 回复的评论ID
replyCommentId?: number;
// 回复者ID
replyUserId?: number;
// 排序(数字越小越靠前)
sortNumber?: number;
// 备注
description?: string;
// 状态, 0未读, 1已读
status?: number;
// 是否删除, 0否, 1是
deleted?: number;
// 租户id
tenantId?: number;
// 创建时间
createTime?: string;
// 修改时间
updateTime?: string;
}
/**
* 文章评论表搜索条件
*/
export interface CmsArticleCommentParam extends PageParam {
commentId?: number;
keywords?: string;
}

View File

@@ -0,0 +1,106 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { CmsArticleContent, CmsArticleContentParam } from './model';
import { MODULES_API_URL } from '@/config/setting';
/**
* 分页查询文章记录表
*/
export async function pageCmsArticleContent(params: CmsArticleContentParam) {
const res = await request.get<ApiResult<PageResult<CmsArticleContent>>>(
MODULES_API_URL + '/cms/cms-article-content/page',
{
params
}
);
if (res.data.code === 0) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 查询文章记录表列表
*/
export async function listCmsArticleContent(params?: CmsArticleContentParam) {
const res = await request.get<ApiResult<CmsArticleContent[]>>(
MODULES_API_URL + '/cms/cms-article-content',
{
params
}
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 添加文章记录表
*/
export async function addCmsArticleContent(data: CmsArticleContent) {
const res = await request.post<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-article-content',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 修改文章记录表
*/
export async function updateCmsArticleContent(data: CmsArticleContent) {
const res = await request.put<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-article-content',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 删除文章记录表
*/
export async function removeCmsArticleContent(id?: number) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-article-content/' + id
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 批量删除文章记录表
*/
export async function removeBatchCmsArticleContent(data: (number | undefined)[]) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-article-content/batch',
{
data
}
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 根据id查询文章记录表
*/
export async function getCmsArticleContent(id: number) {
const res = await request.get<ApiResult<CmsArticleContent>>(
MODULES_API_URL + '/cms/cms-article-content/' + id
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}

View File

@@ -0,0 +1,25 @@
import type { PageParam } from '@/api';
/**
* 文章记录表
*/
export interface CmsArticleContent {
//
id?: number;
// 文章ID
articleId?: number;
// 文章内容
content?: string;
// 租户id
tenantId?: number;
// 创建时间
createTime?: string;
}
/**
* 文章记录表搜索条件
*/
export interface CmsArticleContentParam extends PageParam {
id?: number;
keywords?: string;
}

View File

@@ -0,0 +1,106 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { CmsArticleCount, CmsArticleCountParam } from './model';
import { MODULES_API_URL } from '@/config/setting';
/**
* 分页查询点赞文章
*/
export async function pageCmsArticleCount(params: CmsArticleCountParam) {
const res = await request.get<ApiResult<PageResult<CmsArticleCount>>>(
MODULES_API_URL + '/cms/cms-article-count/page',
{
params
}
);
if (res.data.code === 0) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 查询点赞文章列表
*/
export async function listCmsArticleCount(params?: CmsArticleCountParam) {
const res = await request.get<ApiResult<CmsArticleCount[]>>(
MODULES_API_URL + '/cms/cms-article-count',
{
params
}
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 添加点赞文章
*/
export async function addCmsArticleCount(data: CmsArticleCount) {
const res = await request.post<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-article-count',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 修改点赞文章
*/
export async function updateCmsArticleCount(data: CmsArticleCount) {
const res = await request.put<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-article-count',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 删除点赞文章
*/
export async function removeCmsArticleCount(id?: number) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-article-count/' + id
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 批量删除点赞文章
*/
export async function removeBatchCmsArticleCount(data: (number | undefined)[]) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-article-count/batch',
{
data
}
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 根据id查询点赞文章
*/
export async function getCmsArticleCount(id: number) {
const res = await request.get<ApiResult<CmsArticleCount>>(
MODULES_API_URL + '/cms/cms-article-count/' + id
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}

View File

@@ -0,0 +1,25 @@
import type { PageParam } from '@/api';
/**
* 点赞文章
*/
export interface CmsArticleCount {
// 主键ID
id?: number;
// 文章ID
articleId?: number;
// 用户ID
userId?: number;
// 租户id
tenantId?: number;
// 创建时间
createTime?: string;
}
/**
* 点赞文章搜索条件
*/
export interface CmsArticleCountParam extends PageParam {
id?: number;
keywords?: string;
}

View File

@@ -0,0 +1,106 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { CmsArticleLike, CmsArticleLikeParam } from './model';
import { MODULES_API_URL } from '@/config/setting';
/**
* 分页查询点赞文章
*/
export async function pageCmsArticleLike(params: CmsArticleLikeParam) {
const res = await request.get<ApiResult<PageResult<CmsArticleLike>>>(
MODULES_API_URL + '/cms/cms-article-like/page',
{
params
}
);
if (res.data.code === 0) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 查询点赞文章列表
*/
export async function listCmsArticleLike(params?: CmsArticleLikeParam) {
const res = await request.get<ApiResult<CmsArticleLike[]>>(
MODULES_API_URL + '/cms/cms-article-like',
{
params
}
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 添加点赞文章
*/
export async function addCmsArticleLike(data: CmsArticleLike) {
const res = await request.post<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-article-like',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 修改点赞文章
*/
export async function updateCmsArticleLike(data: CmsArticleLike) {
const res = await request.put<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-article-like',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 删除点赞文章
*/
export async function removeCmsArticleLike(id?: number) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-article-like/' + id
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 批量删除点赞文章
*/
export async function removeBatchCmsArticleLike(data: (number | undefined)[]) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-article-like/batch',
{
data
}
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 根据id查询点赞文章
*/
export async function getCmsArticleLike(id: number) {
const res = await request.get<ApiResult<CmsArticleLike>>(
MODULES_API_URL + '/cms/cms-article-like/' + id
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}

View File

@@ -0,0 +1,25 @@
import type { PageParam } from '@/api';
/**
* 点赞文章
*/
export interface CmsArticleLike {
// 主键ID
id?: number;
// 文章ID
articleId?: number;
// 用户ID
userId?: number;
// 租户id
tenantId?: number;
// 创建时间
createTime?: string;
}
/**
* 点赞文章搜索条件
*/
export interface CmsArticleLikeParam extends PageParam {
id?: number;
keywords?: string;
}

View File

@@ -0,0 +1,103 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { CmsContactLead, CmsContactLeadParam, ContactLeadSubmitForm } from './model';
import { MODULES_API_URL } from '@/config/setting';
// 公开 CMS 接口路径(无需登录,走 /api/cms/* 代理)
const CMS_PUBLIC_URL = '/api/cms';
/**
* 提交联系表单(公开接口,无需登录)
*/
export async function submitContactLead(data: ContactLeadSubmitForm) {
const res = await request.post<ApiResult<unknown>>(
CMS_PUBLIC_URL + '/cms-contact-lead/submit',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 分页查询销售线索(后台管理)
*/
export async function pageCmsContactLead(params: CmsContactLeadParam) {
const res = await request.get<ApiResult<PageResult<CmsContactLead>>>(
MODULES_API_URL + '/cms/cms-contact-lead/page',
{ params }
);
if (res.data.code === 0) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 查询销售线索列表(后台管理)
*/
export async function listCmsContactLead(params?: CmsContactLeadParam) {
const res = await request.get<ApiResult<CmsContactLead[]>>(
MODULES_API_URL + '/cms/cms-contact-lead',
{ params }
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 根据id查询销售线索
*/
export async function getCmsContactLead(id: number) {
const res = await request.get<ApiResult<CmsContactLead>>(
MODULES_API_URL + '/cms/cms-contact-lead/' + id
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 修改销售线索(跟进状态等)
*/
export async function updateCmsContactLead(data: CmsContactLead) {
const res = await request.put<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-contact-lead',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 删除销售线索
*/
export async function removeCmsContactLead(id?: number) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-contact-lead/' + id
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 批量删除销售线索
*/
export async function removeBatchCmsContactLead(data: (number | undefined)[]) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-contact-lead/batch',
{ data }
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}

View File

@@ -0,0 +1,54 @@
import type { PageParam } from '@/api';
/**
* 销售线索(联系表单)
*/
export interface CmsContactLead {
// 线索ID
leadId?: number;
// 姓名
name?: string;
// 手机号
phone?: string;
// 单位名称
company?: string;
// 交付方式: saas / private / hybrid
delivery?: string;
// 需求描述
need?: string;
// 来源页(页面 URL
source?: string;
// 客户IP
clientIp?: string;
// 跟进状态: 0待跟进 1跟进中 2已成单 3已放弃
followStatus?: number;
// 跟进备注
followRemark?: string;
// 创建时间
createTime?: string;
// 更新时间
updateTime?: string;
}
/**
* 销售线索搜索条件
*/
export interface CmsContactLeadParam extends PageParam {
leadId?: number;
keywords?: string;
followStatus?: number;
createTimeStart?: string;
createTimeEnd?: string;
}
/**
* 提交联系表单的请求参数
*/
export interface ContactLeadSubmitForm {
name: string;
phone: string;
company: string;
delivery?: string;
need: string;
source?: string;
}

View File

@@ -0,0 +1,106 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { CmsDesign, CmsDesignParam } from './model';
import { MODULES_API_URL } from '@/config/setting';
/**
* 分页查询页面管理记录表
*/
export async function pageCmsDesign(params: CmsDesignParam) {
const res = await request.get<ApiResult<PageResult<CmsDesign>>>(
MODULES_API_URL + '/cms/cms-design/page',
{
params
}
);
if (res.data.code === 0) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 查询页面管理记录表列表
*/
export async function listCmsDesign(params?: CmsDesignParam) {
const res = await request.get<ApiResult<CmsDesign[]>>(
MODULES_API_URL + '/cms/cms-design',
{
params
}
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 添加页面管理记录表
*/
export async function addCmsDesign(data: CmsDesign) {
const res = await request.post<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-design',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 修改页面管理记录表
*/
export async function updateCmsDesign(data: CmsDesign) {
const res = await request.put<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-design',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 删除页面管理记录表
*/
export async function removeCmsDesign(id?: number) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-design/' + id
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 批量删除页面管理记录表
*/
export async function removeBatchCmsDesign(data: (number | undefined)[]) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-design/batch',
{
data
}
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 根据id查询页面管理记录表
*/
export async function getCmsDesign(id: number) {
const res = await request.get<ApiResult<CmsDesign>>(
MODULES_API_URL + '/cms/cms-design/' + id
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}

View File

@@ -0,0 +1,64 @@
import type { PageParam } from '@/api';
/**
* 页面管理记录表
*/
export interface CmsDesign {
pageId?: number;
name?: string;
keywords?: string;
description?: string;
path?: string;
component?: string;
photo?: string;
content?: string;
// 类型
type?: string;
categoryId?: number;
// 宽
width?: string;
// 高
height?: string;
// 页面样式
style?: string;
// 附件
images?: string;
// 用户ID
userId?: number;
// 设为首页
home?: number;
// 排序
sortNumber?: number;
// 备注
description?: string;
// 状态
status?: number;
// 创建时间
createTime?: string;
// 更新时间
updateTime?: string;
// 页面布局
layout?: string;
backgroundColor?: string;
// 关联网站导航ID
navigationId?: number;
showLayout?: boolean;
btn?: any[];
showBanner?: boolean;
showButton?: boolean;
// 是否同步翻译其他语言版本
translation?: boolean;
buyUrl?: string;
demoUrl?: string;
account?: string;
docUrl?: string;
parentId?: number;
}
/**
* 页面管理记录表搜索条件
*/
export interface CmsDesignParam extends PageParam {
pageId?: number;
keywords?: string;
}

View File

@@ -0,0 +1,153 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { CmsDomain, CmsDomainParam } from './model';
import { SERVER_API_URL} from '@/config/setting';
/**
* 分页查询网站域名记录表
*/
export async function pageCmsDomain(params: CmsDomainParam) {
const res = await request.get<ApiResult<PageResult<CmsDomain>>>(
SERVER_API_URL + '/cms/cms-domain/page',
{
params
}
);
if (res.data.code === 0) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 查询网站域名记录表列表
*/
export async function listCmsDomain(params?: CmsDomainParam) {
const res = await request.get<ApiResult<CmsDomain[]>>(
SERVER_API_URL + '/cms/cms-domain',
{
params
}
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 添加网站域名记录表
*/
export async function addCmsDomain(data: CmsDomain) {
const res = await request.post<ApiResult<unknown>>(
SERVER_API_URL + '/cms/cms-domain',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 修改网站域名记录表
*/
export async function updateCmsDomain(data: CmsDomain) {
const res = await request.post<ApiResult<unknown>>(
SERVER_API_URL + '/cms/cms-domain/domain',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 删除网站域名记录表
*/
export async function removeCmsDomain(id?: number) {
const res = await request.delete<ApiResult<unknown>>(
SERVER_API_URL + '/cms/cms-domain/' + id
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 批量删除网站域名记录表
*/
export async function removeBatchCmsDomain(data: (number | undefined)[]) {
const res = await request.delete<ApiResult<unknown>>(
SERVER_API_URL + '/cms/cms-domain/batch',
{
data
}
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 根据id查询网站域名记录表
*/
export async function getCmsDomain(id: number) {
const res = await request.get<ApiResult<CmsDomain>>(
SERVER_API_URL + '/cms/cms-domain/' + id
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 检查IP是否存在
*/
export async function checkExistence(
field: string,
value: string,
id?: number
) {
const res = await request.get<ApiResult<unknown>>(
SERVER_API_URL + '/cms/cms-domain/existence',
{
params: { field, value, id }
}
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
export async function resolvable(id: number) {
const res = await request.get<ApiResult<CmsDomain>>(
SERVER_API_URL + '/cms/cms-domain/resolvable/' + id
);
if (res.data.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 根据授权主域名
*/
export async function getAuthorizedDomain() {
if(!localStorage.getItem('WebsiteId')){
return false;
}
const res = await request.get<ApiResult<CmsDomain>>(
SERVER_API_URL + '/cms/cms-domain/getAuthorizedDomain/' + localStorage.getItem('WebsiteId')
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}

View File

@@ -0,0 +1,43 @@
import type { PageParam } from '@/api';
/**
* 网站域名记录表
*/
export interface CmsDomain {
// ID
id?: number;
// 类型 0赠送域名 1绑定域名
type?: number;
// 域名
domain?: string;
// 主机记录
hostName?: string;
// 记录值
hostValue?: string;
// 状态
status?: number;
// 排序号
sortNumber?: number;
// 网站ID
productId?: number;
// 租户ID
appId?: number;
// 用户ID
userId?: number;
// 是否删除, 0否, 1是
deleted?: number;
// 租户id
tenantId?: number;
// 创建时间
createTime?: string;
// 修改时间
updateTime?: string;
}
/**
* 网站域名记录表搜索条件
*/
export interface CmsDomainParam extends PageParam {
id?: number;
keywords?: string;
}

View File

@@ -0,0 +1,106 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { CmsForm, CmsFormParam } from './model';
import { MODULES_API_URL } from '@/config/setting';
/**
* 分页查询表单设计表
*/
export async function pageCmsForm(params: CmsFormParam) {
const res = await request.get<ApiResult<PageResult<CmsForm>>>(
MODULES_API_URL + '/cms/cms-form/page',
{
params
}
);
if (res.data.code === 0) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 查询表单设计表列表
*/
export async function listCmsForm(params?: CmsFormParam) {
const res = await request.get<ApiResult<CmsForm[]>>(
MODULES_API_URL + '/cms/cms-form',
{
params
}
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 添加表单设计表
*/
export async function addCmsForm(data: CmsForm) {
const res = await request.post<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-form',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 修改表单设计表
*/
export async function updateCmsForm(data: CmsForm) {
const res = await request.put<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-form',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 删除表单设计表
*/
export async function removeCmsForm(id?: number) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-form/' + id
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 批量删除表单设计表
*/
export async function removeBatchCmsForm(data: (number | undefined)[]) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-form/batch',
{
data
}
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 根据id查询表单设计表
*/
export async function getCmsForm(id: number) {
const res = await request.get<ApiResult<CmsForm>>(
MODULES_API_URL + '/cms/cms-form/' + id
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}

View File

@@ -0,0 +1,53 @@
import type { PageParam } from '@/api';
/**
* 表单设计表
*/
export interface CmsForm {
// ID
formId?: number;
// 表单标题
name?: string;
// 顶部图片
photo?: string;
// 背景图片
background?: string;
// 视频文件
video?: string;
// 提交次数
submitNumber?: number;
// 页面布局
layout?: string;
// 是否隐藏顶部图片
hidePhoto?: number;
// 是否隐藏背景图片
hideBackground?: number;
// 是否隐藏视频
hideVideo?: number;
// 背景图片透明度
opacity?: string;
// 用户ID
userId?: number;
// 商户ID
merchantId?: number;
// 排序(数字越小越靠前)
sortNumber?: number;
// 备注
description?: string;
// 状态, 0正常, 1冻结
status?: number;
// 是否删除, 0否, 1是
deleted?: number;
// 租户id
tenantId?: number;
// 创建时间
createTime?: string;
}
/**
* 表单设计表搜索条件
*/
export interface CmsFormParam extends PageParam {
formId?: number;
keywords?: string;
}

View File

@@ -0,0 +1,106 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { CmsFormRecord, CmsFormRecordParam } from './model';
import { MODULES_API_URL } from '@/config/setting';
/**
* 分页查询表单数据记录表
*/
export async function pageCmsFormRecord(params: CmsFormRecordParam) {
const res = await request.get<ApiResult<PageResult<CmsFormRecord>>>(
MODULES_API_URL + '/cms/cms-form-record/page',
{
params
}
);
if (res.data.code === 0) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 查询表单数据记录表列表
*/
export async function listCmsFormRecord(params?: CmsFormRecordParam) {
const res = await request.get<ApiResult<CmsFormRecord[]>>(
MODULES_API_URL + '/cms/cms-form-record',
{
params
}
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 添加表单数据记录表
*/
export async function addCmsFormRecord(data: CmsFormRecord) {
const res = await request.post<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-form-record',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 修改表单数据记录表
*/
export async function updateCmsFormRecord(data: CmsFormRecord) {
const res = await request.put<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-form-record',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 删除表单数据记录表
*/
export async function removeCmsFormRecord(id?: number) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-form-record/' + id
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 批量删除表单数据记录表
*/
export async function removeBatchCmsFormRecord(data: (number | undefined)[]) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-form-record/batch',
{
data
}
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 根据id查询表单数据记录表
*/
export async function getCmsFormRecord(id: number) {
const res = await request.get<ApiResult<CmsFormRecord>>(
MODULES_API_URL + '/cms/cms-form-record/' + id
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}

View File

@@ -0,0 +1,41 @@
import type { PageParam } from '@/api';
/**
* 表单数据记录表
*/
export interface CmsFormRecord {
// ID
formRecordId?: number;
// 手机号
phone?: string;
// 表单数据
formData?: string;
// 表单ID
formId?: number;
// 用户ID
userId?: number;
// 商户ID
merchantId?: number;
// 姓名
name?: string;
// 排序(数字越小越靠前)
sortNumber?: number;
// 备注
description?: string;
// 状态, 0正常, 1冻结
status?: number;
// 是否删除, 0否, 1是
deleted?: number;
// 租户id
tenantId?: number;
// 创建时间
createTime?: string;
}
/**
* 表单数据记录表搜索条件
*/
export interface CmsFormRecordParam extends PageParam {
formRecordId?: number;
keywords?: string;
}

View File

@@ -0,0 +1,106 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { CmsLang, CmsLangParam } from './model';
import { MODULES_API_URL } from '@/config/setting';
/**
* 分页查询国际化
*/
export async function pageCmsLang(params: CmsLangParam) {
const res = await request.get<ApiResult<PageResult<CmsLang>>>(
MODULES_API_URL + '/cms/cms-lang/page',
{
params
}
);
if (res.data.code === 0) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 查询国际化列表
*/
export async function listCmsLang(params?: CmsLangParam) {
const res = await request.get<ApiResult<CmsLang[]>>(
MODULES_API_URL + '/cms/cms-lang',
{
params
}
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 添加国际化
*/
export async function addCmsLang(data: CmsLang) {
const res = await request.post<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-lang',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 修改国际化
*/
export async function updateCmsLang(data: CmsLang) {
const res = await request.put<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-lang',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 删除国际化
*/
export async function removeCmsLang(id?: number) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-lang/' + id
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 批量删除国际化
*/
export async function removeBatchCmsLang(data: (number | undefined)[]) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-lang/batch',
{
data
}
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 根据id查询国际化
*/
export async function getCmsLang(id: number) {
const res = await request.get<ApiResult<CmsLang>>(
MODULES_API_URL + '/cms/cms-lang/' + id
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}

View File

@@ -0,0 +1,35 @@
import type { PageParam } from '@/api';
/**
* 国际化
*/
export interface CmsLang {
// ID
id?: number;
// 名称
name?: string;
// 编码
code?: string;
// 排序(数字越小越靠前)
sortNumber?: number;
// 备注
description?: string;
// 状态, 0已发布, 1待审核 2已驳回 3违规内容
status?: number;
// 是否删除, 0否, 1是
deleted?: number;
// 租户id
tenantId?: number;
// 创建时间
createTime?: string;
// 修改时间
updateTime?: string;
}
/**
* 国际化搜索条件
*/
export interface CmsLangParam extends PageParam {
id?: number;
keywords?: string;
}

View File

@@ -0,0 +1,106 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { CmsLangLog, CmsLangLogParam } from './model';
import { MODULES_API_URL } from '@/config/setting';
/**
* 分页查询国际化记录启用
*/
export async function pageCmsLangLog(params: CmsLangLogParam) {
const res = await request.get<ApiResult<PageResult<CmsLangLog>>>(
MODULES_API_URL + '/cms/cms-lang-log/page',
{
params
}
);
if (res.data.code === 0) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 查询国际化记录启用列表
*/
export async function listCmsLangLog(params?: CmsLangLogParam) {
const res = await request.get<ApiResult<CmsLangLog[]>>(
MODULES_API_URL + '/cms/cms-lang-log',
{
params
}
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 添加国际化记录启用
*/
export async function addCmsLangLog(data: CmsLangLog) {
const res = await request.post<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-lang-log',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 修改国际化记录启用
*/
export async function updateCmsLangLog(data: CmsLangLog) {
const res = await request.put<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-lang-log',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 删除国际化记录启用
*/
export async function removeCmsLangLog(id?: number) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-lang-log/' + id
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 批量删除国际化记录启用
*/
export async function removeBatchCmsLangLog(data: (number | undefined)[]) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-lang-log/batch',
{
data
}
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 根据id查询国际化记录启用
*/
export async function getCmsLangLog(id: number) {
const res = await request.get<ApiResult<CmsLangLog>>(
MODULES_API_URL + '/cms/cms-lang-log/' + id
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}

View File

@@ -0,0 +1,27 @@
import type { PageParam } from '@/api';
/**
* 国际化记录启用
*/
export interface CmsLangLog {
// ID
id?: number;
// 名称
lang?: string;
// 关联ID
langId?: number;
// 编码
code?: string;
// 租户id
tenantId?: number;
// 创建时间
createTime?: string;
}
/**
* 国际化记录启用搜索条件
*/
export interface CmsLangLogParam extends PageParam {
id?: number;
keywords?: string;
}

View File

@@ -0,0 +1,120 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { CmsLink, CmsLinkParam } from './model';
import { MODULES_API_URL } from '@/config/setting';
/**
* 分页查询常用链接
*/
export async function pageCmsLink(params: CmsLinkParam) {
const res = await request.get<ApiResult<PageResult<CmsLink>>>(
MODULES_API_URL + '/cms/cms-link/page',
{
params
}
);
if (res.data.code === 0) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 查询常用链接列表
*/
export async function listCmsLink(params?: CmsLinkParam) {
const res = await request.get<ApiResult<CmsLink[]>>(
MODULES_API_URL + '/cms/cms-link',
{
params
}
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 添加常用链接
*/
export async function addCmsLink(data: CmsLink) {
const res = await request.post<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-link',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 修改常用链接
*/
export async function updateCmsLink(data: CmsLink) {
const res = await request.put<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-link',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 删除常用链接
*/
export async function removeCmsLink(id?: number) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-link/' + id
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 批量修改常用链接
*/
export async function updateBatchCmsLink(data: any) {
const res = await request.put<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-link/batch',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 批量删除常用链接
*/
export async function removeBatchCmsLink(data: (number | undefined)[]) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-link/batch',
{
data
}
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 根据id查询常用链接
*/
export async function getCmsLink(id: number) {
const res = await request.get<ApiResult<CmsLink>>(
MODULES_API_URL + '/cms/cms-link/' + id
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}

View File

@@ -0,0 +1,45 @@
import type { PageParam } from '@/api';
/**
* 常用链接
*/
export interface CmsLink {
// 自增ID
id?: number;
// 链接名称
name?: string;
// 图标
icon?: string;
// 链接地址
url?: string;
// 链接分类
categoryId?: number;
// 应用ID
appId?: number;
// 用户ID
userId?: number;
// 语言
lang?: string;
// 是否推荐
recommend?: number;
// 备注
description?: string;
// 排序(数字越小越靠前)
sortNumber?: number;
// 是否删除, 0否, 1是
deleted?: number;
// 状态, 0正常, 1待确认
status?: number;
// 租户id
tenantId?: number;
// 创建时间
createTime?: string;
}
/**
* 常用链接搜索条件
*/
export interface CmsLinkParam extends PageParam {
id?: number;
keywords?: string;
}

View File

@@ -0,0 +1,106 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { CmsModel, CmsModelParam } from './model';
import { MODULES_API_URL } from '@/config/setting';
/**
* 分页查询模型
*/
export async function pageCmsModel(params: CmsModelParam) {
const res = await request.get<ApiResult<PageResult<CmsModel>>>(
MODULES_API_URL + '/cms/cms-model/page',
{
params
}
);
if (res.data.code === 0) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 查询模型列表
*/
export async function listCmsModel(params?: CmsModelParam) {
const res = await request.get<ApiResult<CmsModel[]>>(
MODULES_API_URL + '/cms/cms-model',
{
params
}
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 添加模型
*/
export async function addCmsModel(data: CmsModel) {
const res = await request.post<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-model',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 修改模型
*/
export async function updateCmsModel(data: CmsModel) {
const res = await request.put<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-model',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 删除模型
*/
export async function removeCmsModel(id?: number) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-model/' + id
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 批量删除模型
*/
export async function removeBatchCmsModel(data: (number | undefined)[]) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-model/batch',
{
data
}
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 根据id查询模型
*/
export async function getCmsModel(id: number) {
const res = await request.get<ApiResult<CmsModel>>(
MODULES_API_URL + '/cms/cms-model/' + id
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}

View File

@@ -0,0 +1,63 @@
import type { PageParam } from '@/api';
/**
* 模型
*/
export interface CmsModel {
// ID
modelId?: number;
// 模型名称
name?: string;
// 唯一标识
model?: string;
// 详情页组件
componentDetail?: string;
// 菜单组件地址, 目录可为空
component?: string;
// 模型banner图片
banner?: string;
// 缩列图
thumb?: string;
// 文件后缀
suffix?: string;
// 封面图宽
imageWidth?: string;
// 封面图高
imageHeight?: string;
// 样式
style?: string;
// Banner上的标题
title?: string;
// Banner上的描述
desc?: string;
// 列表显示方式(10小图展示 20大图展示)
showType?: number;
// 是否禁用
disabled?: boolean;
// 用户ID
userId?: number;
// 排序(数字越小越靠前)
sortNumber?: number;
// 备注
description?: string;
// 状态, 0已发布, 1待审核 2已驳回 3违规内容
status?: number;
// 是否删除, 0否, 1是
deleted?: number;
// 租户id
tenantId?: number;
// 创建时间
createTime?: string;
// 修改时间
updateTime?: string;
label?: string;
value?: string;
}
/**
* 模型搜索条件
*/
export interface CmsModelParam extends PageParam {
modelId?: number;
keywords?: string;
}

View File

@@ -0,0 +1,151 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { CmsNavigation, CmsNavigationParam } from './model';
import { MODULES_API_URL } from '@/config/setting';
/**
* 分页查询网站导航记录表
*/
export async function pageCmsNavigation(params: CmsNavigationParam) {
const res = await request.get<ApiResult<PageResult<CmsNavigation>>>(
MODULES_API_URL + '/cms/cms-navigation/page',
{
params
}
);
if (res.data.code === 0) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 查询网站导航记录表列表
*/
export async function listCmsNavigation(params?: CmsNavigationParam) {
const res = await request.get<ApiResult<CmsNavigation[]>>(
MODULES_API_URL + '/cms/cms-navigation',
{
params
}
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 查询导航列表(树形结构)
*/
export async function treeNavigation(params?: CmsNavigationParam) {
const res = await request.get<ApiResult<CmsNavigation[]>>(
MODULES_API_URL + '/cms/cms-navigation/tree',
{
params
}
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 添加网站导航记录表
*/
export async function addCmsNavigation(data: CmsNavigation) {
const res = await request.post<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-navigation',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 修改网站导航记录表
*/
export async function updateCmsNavigation(data: CmsNavigation) {
const res = await request.put<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-navigation',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 删除网站导航记录表
*/
export async function removeCmsNavigation(id?: number) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-navigation/' + id
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 批量删除网站导航记录表
*/
export async function removeBatchCmsNavigation(data: (number | undefined)[]) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-navigation/batch',
{
data
}
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 根据id查询网站导航记录表
*/
export async function getCmsNavigation(id: number) {
const res = await request.get<ApiResult<CmsNavigation>>(
MODULES_API_URL + '/cms/cms-navigation/' + id
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 根据code查询导航
*/
export async function getByCode(code: string) {
const res = await request.get<ApiResult<CmsNavigation>>(
'/cms/cms-navigation/getByCode/' + code
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 导航批量导入
*/
export async function importCmsNavigation(file: File) {
const formData = new FormData();
formData.append('file', file);
const res = await request.post<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-navigation/import',
formData
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}

View File

@@ -0,0 +1,110 @@
import type { PageParam } from '@/api';
/**
* 网站导航记录表
*/
export interface CmsNavigation {
// ID
navigationId?: number;
// 上级id, 0是顶级
parentId?: number;
// 菜单名称
title?: string;
// 模型
model?: string;
// 标识
code?: string;
// 菜单路由地址
path?: string;
// 菜单组件地址, 目录可为空
component?: string;
componentPath?: string;
// 打开位置
target?: string;
// 菜单图标
icon?: string;
// banner图片
banner?: string;
// 图标颜色
color?: string;
// 是否隐藏, 0否, 1是(仅注册路由不显示在左侧菜单)
hide?: number;
// 可见类型 0所有人 1登录可见 2密码可见
permission?: number;
// 访问密码
password?: string;
// 位置 0不限 1顶部 2底部
position?: number;
// 仅在顶部显示
top?: number;
// 仅在底部显示
bottom?: number;
// 菜单侧栏选中的path
active?: string;
// 其它路由元信息
meta?: string;
// css样式
style?: string;
// 父级栏目路由
parentPath?: string;
// 父级栏目名称
parentName?: string;
// 父级栏目位置
parentPosition?: number;
// 模型名称
modelName?: string;
// 类型(已废弃)
type?: number;
// 绑定的页面(已废弃)
pageId?: number;
// 项目ID
itemId?: number;
// 是否微信小程序菜单
isMpWeixin?: string;
gutter?: number;
span?: number;
readNum?: number;
// 用户ID
userId?: number;
// 国际化语言
lang?: string;
// 设为首页
home?: number;
// 是否推荐
recommend?: boolean;
// 排序(数字越小越靠前)
sortNumber?: number;
// 备注
description?: string;
// 是否删除, 0否, 1是
deleted?: number;
// 状态, 0正常, 1冻结
status?: number;
// 租户id
tenantId?: number;
// 创建时间
createTime?: string;
children?: CmsNavigation[];
disabled?: boolean;
label?: string;
value?: number;
suffix?: string;
showBanner?: boolean;
showLayout?: boolean;
langCategoryId?: number;
}
// Runtime-friendly named export.
// Some build tooling may incorrectly generate value imports for type-only exports.
export const CmsNavigation = {} as const;
/**
* 网站导航记录表搜索条件
*/
export interface CmsNavigationParam extends PageParam {
navigationId?: number;
model?: string;
lang?: string;
recommend?: boolean;
keywords?: string;
}

View File

@@ -0,0 +1,106 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { CmsOrder, CmsOrderParam } from './model';
import { MODULES_API_URL } from '@/config/setting';
/**
* 分页查询订单
*/
export async function pageCmsOrder(params: CmsOrderParam) {
const res = await request.get<ApiResult<PageResult<CmsOrder>>>(
MODULES_API_URL + '/cms/cms-order/page',
{
params
}
);
if (res.data.code === 0) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 查询订单列表
*/
export async function listCmsOrder(params?: CmsOrderParam) {
const res = await request.get<ApiResult<CmsOrder[]>>(
MODULES_API_URL + '/cms/cms-order',
{
params
}
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 添加订单
*/
export async function addCmsOrder(data: CmsOrder) {
const res = await request.post<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-order',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 修改订单
*/
export async function updateCmsOrder(data: CmsOrder) {
const res = await request.put<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-order',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 删除订单
*/
export async function removeCmsOrder(id?: number) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-order/' + id
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 批量删除订单
*/
export async function removeBatchCmsOrder(data: (number | undefined)[]) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-order/batch',
{
data
}
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 根据id查询订单
*/
export async function getCmsOrder(id: number) {
const res = await request.get<ApiResult<CmsOrder>>(
MODULES_API_URL + '/cms/cms-order/' + id
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}

View File

@@ -0,0 +1,66 @@
import type { PageParam } from '@/api';
/**
* 订单
*/
export interface CmsOrder {
// 订单号
orderId?: number;
// 订单标题
title?: string;
// 订单编号
orderNo?: string;
// 订单类型0商城 1询价 2留言
type?: number;
// 关联项目ID配合订单类型使用
itemId?: number;
// 真实姓名
realName?: string;
// 手机号码
phone?: string;
// 电子邮箱
email?: string;
// 收货地址
address?: string;
// 订单内容
content?: string;
// 订单附件
files?: string;
// 订单总额
totalPrice?: string;
// 实际付款
payPrice?: string;
// 报价询价
price?: string;
// 购买数量
totalNum?: number;
// 二维码地址,保存订单号,支付成功后才生成
qrcode?: string;
// 下单渠道0网站 1小程序 2其他
channel?: number;
// 过期时间
expirationTime?: string;
// 订单是否已结算(0未结算 1已结算)
isSettled?: boolean;
// 用户id
userId?: number;
// 备注
description?: string;
// 排序号
sortNumber?: number;
// 是否删除, 0否, 1是
deleted?: number;
// 租户id
tenantId?: number;
// 创建时间
createTime?: string;
}
/**
* 订单搜索条件
*/
export interface CmsOrderParam extends PageParam {
orderId?: number;
isSettled?: number;
keywords?: string;
}

View File

@@ -0,0 +1,106 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { CmsStatistics, CmsStatisticsParam } from './model';
import { MODULES_API_URL } from '@/config/setting';
/**
* 分页查询站点统计信息表
*/
export async function pageCmsStatistics(params: CmsStatisticsParam) {
const res = await request.get<ApiResult<PageResult<CmsStatistics>>>(
MODULES_API_URL + '/cms/cms-statistics/page',
{
params
}
);
if (res.data.code === 0) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 查询站点统计信息表列表
*/
export async function listCmsStatistics(params?: CmsStatisticsParam) {
const res = await request.get<ApiResult<CmsStatistics[]>>(
MODULES_API_URL + '/cms/cms-statistics',
{
params
}
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 添加站点统计信息表
*/
export async function addCmsStatistics(data: CmsStatistics) {
const res = await request.post<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-statistics',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 修改站点统计信息表
*/
export async function updateCmsStatistics(data: CmsStatistics) {
const res = await request.put<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-statistics',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 删除站点统计信息表
*/
export async function removeCmsStatistics(id?: number) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-statistics/' + id
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 批量删除站点统计信息表
*/
export async function removeBatchCmsStatistics(data: (number | undefined)[]) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-statistics/batch',
{
data
}
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 根据id查询站点统计信息表
*/
export async function getCmsStatistics(id: number) {
const res = await request.get<ApiResult<CmsStatistics>>(
MODULES_API_URL + '/cms/cms-statistics/' + id
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}

View File

@@ -0,0 +1,79 @@
import type { PageParam } from '@/api';
/**
* 站点统计信息表
*/
export interface CmsStatistics {
// 自增ID
id?: number;
// 站点ID
productId?: number;
// 用户总数
userCount?: number;
// 订单总数
orderCount?: number;
// 商品总数
productCount?: number;
// 总销售额
totalSales?: number;
// 本月销售额
monthSales?: number;
// 今日销售额
todaySales?: number;
// 昨日销售额
yesterdaySales?: number;
// 本周销售额
weekSales?: number;
// 本年销售额
yearSales?: number;
// 今日订单数
todayOrders?: number;
// 本月订单数
monthOrders?: number;
// 今日新增用户
todayUsers?: number;
// 本月新增用户
monthUsers?: number;
// 今日访问量
todayVisits?: number;
// 总访问量
totalVisits?: number;
// 商户总数
merchantCount?: number;
// 活跃用户数
activeUsers?: number;
// 转化率(%)
conversionRate?: string;
// 平均订单金额
avgOrderAmount?: string;
// 统计日期
statisticsDate?: string;
// 统计类型: 1日统计, 2月统计, 3年统计
statisticsType?: number;
// 运行天数
runDays?: number;
// 排序号
sortNumber?: number;
// 操作用户ID
userId?: number;
// 商户ID
merchantId?: number;
// 状态: 0禁用, 1启用
status?: string;
// 是否删除: 0否, 1是
deleted?: string;
// 租户ID
tenantId?: number;
// 创建时间
createTime?: string;
// 修改时间
updateTime?: string;
}
/**
* 站点统计信息表搜索条件
*/
export interface CmsStatisticsParam extends PageParam {
id?: number;
keywords?: string;
}

View File

@@ -0,0 +1,106 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { CmsTemplate, CmsTemplateParam } from './model';
import { MODULES_API_URL } from '@/config/setting';
/**
* 分页查询网站模版
*/
export async function pageCmsTemplate(params: CmsTemplateParam) {
const res = await request.get<ApiResult<PageResult<CmsTemplate>>>(
MODULES_API_URL + '/cms/cms-template/page',
{
params
}
);
if (res.data.code === 0) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 查询网站模版列表
*/
export async function listCmsTemplate(params?: CmsTemplateParam) {
const res = await request.get<ApiResult<CmsTemplate[]>>(
MODULES_API_URL + '/cms/cms-template',
{
params
}
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 添加网站模版
*/
export async function addCmsTemplate(data: CmsTemplate) {
const res = await request.post<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-template',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 修改网站模版
*/
export async function updateCmsTemplate(data: CmsTemplate) {
const res = await request.put<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-template',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 删除网站模版
*/
export async function removeCmsTemplate(id?: number) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-template/' + id
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 批量删除网站模版
*/
export async function removeBatchCmsTemplate(data: (number | undefined)[]) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-template/batch',
{
data
}
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 根据id查询网站模版
*/
export async function getCmsTemplate(id: number) {
const res = await request.get<ApiResult<CmsTemplate>>(
MODULES_API_URL + '/cms/cms-template/' + id
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}

View File

@@ -0,0 +1,59 @@
import type { PageParam } from '@/api';
/**
* 网站模版
*/
export interface CmsTemplate {
// ID
id?: number;
// 模版名称
name?: string;
// 模版标识
code?: string;
// 缩列图
image?: string;
// 类型 1企业官网 2其他
type?: number;
// 网站关键词
keywords?: string;
// 域名前缀
prefix?: string;
// 预览地址
domain?: string;
// 模版下载地址
downUrl?: string;
// 色系
color?: string;
// 应用版本 10免费版 20授权版 30永久授权
version?: number;
// 行业类型(父级)
industryParent?: string;
// 行业类型(子级)
industryChild?: string;
// 备注
description?: string;
// 是否推荐
recommend?: string;
// 是否共享模板
share?: string;
// 排序号
sortNumber?: number;
// 用户ID
userId?: number;
// 是否删除, 0否, 1是
deleted?: number;
// 租户id
tenantId?: number;
// 创建时间
createTime?: string;
// 修改时间
updateTime?: string;
}
/**
* 网站模版搜索条件
*/
export interface CmsTemplateParam extends PageParam {
id?: number;
keywords?: string;
}

View File

@@ -0,0 +1,314 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { CmsWebsite, CmsWebsiteParam } from './model';
import { MODULES_API_URL, SERVER_API_URL } from '@/config/setting';
/**
* 获取网站信息
*/
export async function getSiteInfo() {
const res = await request.get<ApiResult<CmsWebsite>>(
MODULES_API_URL + '/cms/cms-website/getSiteInfo',
{
params: {}
}
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 分页查询网站信息记录表
*/
export async function pageCmsWebsite(params: CmsWebsiteParam) {
const res = await request.get<ApiResult<PageResult<CmsWebsite>>>(
MODULES_API_URL + '/cms/cms-website/page',
{
params
}
);
if (res.data.code === 0) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 查询网站信息记录表列表
*/
export async function listCmsWebsite(params?: CmsWebsiteParam) {
const res = await request.get<ApiResult<CmsWebsite[]>>(
MODULES_API_URL + '/cms/cms-website',
{
params
}
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 添加网站信息记录表
*/
export async function addCmsWebsite(data: CmsWebsite): Promise<CmsWebsite> {
const res = await request.post<ApiResult<CmsWebsite>>(
MODULES_API_URL + '/cms/cms-website',
data
);
console.log('addCmsWebsite 响应:', res);
// 处理响应数据
const responseData = res.data;
// 检查是否为 ApiResult 格式
if (responseData && typeof responseData === 'object' && 'code' in responseData) {
// 是 ApiResult 格式
if (responseData.code === 0) {
// 确保返回的数据不为空
if (!responseData.data) {
console.warn('addCmsWebsite: 后端返回的data字段为空', responseData);
// 返回一个包含websiteId的默认对象
return {
websiteName: data.websiteName,
websiteCode: data.websiteCode,
websiteType: data.websiteType,
type: data.type,
comments: data.comments
} as CmsWebsite;
}
return responseData.data;
}
return Promise.reject(new Error(responseData.message || '创建失败'));
} else {
// 直接返回 CmsWebsite 对象
console.log('addCmsWebsite: 后端直接返回CmsWebsite对象', responseData);
return responseData as CmsWebsite;
}
}
/**
* 修改网站信息记录表
*/
export async function updateCmsWebsite(data: CmsWebsite) {
const res = await request.put<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-website',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 删除网站信息记录表
*/
export async function removeCmsWebsite(id?: number) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-website/' + id
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 批量删除网站信息记录表
*/
export async function removeBatchCmsWebsite(data: (number | undefined)[]) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-website/batch',
{
data
}
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 根据id查询网站信息记录表
*/
export async function getCmsWebsite(id: number) {
const res = await request.get<ApiResult<CmsWebsite>>(
MODULES_API_URL + '/cms/cms-website/' + id
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 清除缓存
*/
export async function removeSiteInfoCache(key?: string) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-website/clearSiteInfo/' + key
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
export async function pageCmsWebsiteAll(params: CmsWebsiteParam) {
const res = await request.get<ApiResult<PageResult<CmsWebsite>>>(
MODULES_API_URL + '/cms/cms-website/pageAll',
{
params
}
);
if (res.data.code === 0) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 根据id查询网站
*/
export async function getCmsWebsiteAll(id: number) {
const res = await request.get<ApiResult<CmsWebsite>>(
'/cms/cms-website/getAll/' + id
);
if (res.data.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 修改网站信息记录表
*/
export async function updateCmsWebsiteAll(data: CmsWebsite) {
const res = await request.put<ApiResult<unknown>>(
'/cms/cms-website/updateAll',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
// ---- 发布管理 API ----
/**
* 提交上架申请
*/
export async function submitPublishReview(data: {
websiteId: number
priceType: string
price?: number
subscriptionPeriod?: string
appDescription?: string
detailDescription?: string
screenshots?: string
}) {
const res = await request.post<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-website/submitReview',
data
)
if (res.data.code === 0) return res.data.message
return Promise.reject(new Error(res.data.message))
}
/**
* 下架应用
*/
export async function unpublishCmsWebsite(websiteId: number) {
const res = await request.post<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-website/unpublish/' + websiteId
)
if (res.data.code === 0) return res.data.message
return Promise.reject(new Error(res.data.message))
}
/**
* 撤回审核申请
*/
export async function withdrawPublishReview(websiteId: number) {
const res = await request.post<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-website/withdrawReview/' + websiteId
)
if (res.data.code === 0) return res.data.message
return Promise.reject(new Error(res.data.message))
}
/**
* 管理员审核通过
*/
export async function approvePublishReview(websiteId: number) {
const res = await request.post<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-website/approveReview/' + websiteId
)
if (res.data.code === 0) return res.data.message
return Promise.reject(new Error(res.data.message))
}
/**
* 管理员审核拒绝
*/
export async function rejectPublishReview(data: { websiteId: number; rejectReason: string }) {
const res = await request.post<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-website/rejectReview',
data
)
if (res.data.code === 0) return res.data.message
return Promise.reject(new Error(res.data.message))
}
/**
* 获取发布审核记录列表(管理员用)
*/
export async function pagePublishReviews(params: {
page?: number
limit?: number
publishStatus?: string
keywords?: string
}) {
const res = await request.get<ApiResult<PageResult<CmsWebsite>>>(
MODULES_API_URL + '/cms/cms-website/pageReviews',
{ params }
)
if (res.data.code === 0) return res.data.data
return Promise.reject(new Error(res.data.message))
}
/**
* 分页查询应用产品CmsWebsite 表,兼容 product 字段名)
*/
export async function pageAppProductAll(params: any) {
const res = await request.get<ApiResult<PageResult<any>>>(
SERVER_API_URL + '/cms/cms-website/pageAll',
{ params }
)
if (res.data.code === 0) {
// 字段映射website -> product 兼容
const data = res.data.data
if (data?.list) {
data.list = data.list.map((item: any) => ({
...item,
productId: item.websiteId,
productName: item.websiteName,
productCode: item.websiteCode,
productSecret: item.websiteSecret,
icon: item.websiteIcon,
logo: item.websiteLogo,
description: item.comments,
userId: item.userId,
}))
}
return data
}
return Promise.reject(new Error(res.data.message))
}

View File

@@ -0,0 +1,209 @@
import type { PageParam } from '@/api';
import type { CmsWebsiteSetting } from "@/api/cms/cmsWebsiteSetting/model";
import type { CmsNavigation } from "@/api/cms/cmsNavigation/model";
/**
* 网站信息记录表
*/
export interface CmsWebsite {
// 站点ID
websiteId?: number;
// 网站名称
websiteName?: string;
// 网站标识
websiteCode?: string;
// 网站密钥
websiteSecret?: string;
// 网站LOGO
websiteIcon?: string;
// 网站LOGO
websiteLogo?: string;
// 网站LOGO(深色模式)
websiteDarkLogo?: string;
// 网站类型
websiteType?: string;
// 网站截图
files?: string;
// 网站类型
type?: number;
// 网站关键词
keywords?: string;
// 域名前缀
prefix?: string;
// 绑定域名
domain?: string;
// 全局样式
style?: string;
// 后台管理地址
adminUrl?: string;
// 应用版本 10标准版 20专业版 30永久授权
version?: number;
// 允许展示到插件市场
market?: boolean;
// 应用类型 0应用 1插件
plugin?: boolean;
// 默认编辑器
editor?: number,
// 服务到期时间
expirationTime?: string;
// 模版ID
templateId?: number;
// 行业类型
category?: string;
// 行业类型(父级)
industryParent?: string;
// 行业类型(子级)
industryChild?: string;
// 企业ID
companyId?: number;
// 所在国家
country?: string;
// 所在省份
province?: string;
// 所在城市
city?: string;
// 所在辖区
region?: string;
// 经度
longitude?: string;
// 纬度
latitude?: string;
// 街道地址
address?: string;
// 联系电话
phone?: string;
// 电子邮箱
email?: string;
// ICP备案号
icpNo?: string;
// 公安备案
policeNo?: string;
// 备注
comments?: string;
// 是否推荐
recommend?: number;
// 是否官方
official?: boolean;
// 是否运行中
running?: number;
// 状态 0未开通 1运行中 2维护中 3已关闭 4已欠费停机 5违规关停
status?: number;
// 维护说明
statusText?: string;
// 关闭说明
statusClose?: string;
// 全局样式
styles?: string;
// 语言
lang?: string;
// 排序号
sortNumber?: number;
// 用户ID
userId?: number;
// 是否删除, 0否, 1是
deleted?: number;
// 租户id
tenantId?: number;
// 创建时间
createTime?: string;
// 修改时间
updateTime?: string;
// 网站配置
config?: any;
// 短信验证码
smsCode?: string;
// 短信验证码
code?: string;
// 是否记住密码
remember?: boolean;
// 企业名称
companyName?: string;
// 是否注册未超级管理员
isSuperAdmin?: boolean;
// 用户名
username?: string;
// 开发者
developer?: string;
// 网站配置
setting?: CmsWebsiteSetting;
// ---- 发布管理字段 ----
// 发布状态: developing开发中 pending_review待审核 published已上架 rejected审核未通过 deprecated已下架
publishStatus?: 'developing' | 'pending_review' | 'published' | 'rejected' | 'deprecated';
// 定价模式: free免费 one_time一次性 subscription订阅
priceType?: 'free' | 'one_time' | 'subscription';
// 价格(分)
price?: number;
// 订阅周期: month按月 year按年
subscriptionPeriod?: 'month' | 'year';
// 应用简介
appDescription?: string;
// 详细说明
detailDescription?: string;
// 应用截图JSON数组字符串
screenshots?: string;
// 安装次数
installCount?: number;
// 评分1-5
rating?: number;
// 审核拒绝原因
rejectReason?: string;
// 提交审核时间
publishApplyTime?: string;
// 正式发布时间
publishTime?: string;
// 审核人ID
reviewerId?: number;
// 审核时间
reviewTime?: string;
}
export interface AppInfo {
appId?: number;
appName?: string;
description?: string;
keywords?: string;
appCode?: string;
mpQrCode?: string;
title?: string;
logo?: string;
icon?: string;
domain?: string;
running?: number;
version?: number;
expirationTime?: string;
expired?: boolean;
expiredDays?: number;
soon?: number;
statusIcon?: string;
statusText?: string;
config?: Object;
serverTime?: Object;
topNavs?: CmsNavigation[];
bottomNavs?: CmsNavigation[];
setting?: Object;
createTime?: string;
}
/**
* 网站信息记录表搜索条件
*/
export interface CmsWebsiteParam extends PageParam {
websiteId?: number;
type?: number;
status?: number;
plugin?: boolean;
official?: boolean;
market?: boolean;
keywords?: string;
// 按用户过滤(单个)
userId?: number;
// 按用户集合过滤(多个,后端 IN 查询)
userIds?: number[];
// 按 websiteId 集合过滤(后端 IN 查询)
websiteIds?: number[];
// 协作成员userId后端一次联表查出该用户创建的 + 作为成员参与的所有应用
memberUserId?: number;
// 发布状态筛选
publishStatus?: string;
}

View File

@@ -0,0 +1,38 @@
/**
* CMS Website Field API - 网站配置字段
* 从 app 模块获取应用配置信息
*/
import request from '@/utils/request';
export interface Config {
[key: string]: any;
}
/**
* 获取站点配置字段
*/
export function configWebsiteField(tenantId?: number, code?: string) {
return request({
url: '/api/app/product/field/config',
method: 'get',
params: { tenantId, code },
});
}
/**
* 根据code获取应用字段
*/
export function getAppProductFieldByCode(code: string) {
return request({
url: '/api/app/product/field/' + code,
method: 'get',
});
}
// 导出所有方法
const cmsWebsiteFieldApi = {
configWebsiteField,
getAppProductFieldByCode,
};
export default cmsWebsiteFieldApi;

View File

@@ -0,0 +1,169 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type {CmsWebsiteField, CmsWebsiteFieldParam, Config} from './model';
import {MODULES_API_URL, TEMPLATE_ID} from '@/config/setting';
export type { Config } from './model';
/**
* 分页查询应用参数
*/
export async function pageCmsWebsiteField(params: CmsWebsiteFieldParam) {
const res = await request.get<ApiResult<PageResult<CmsWebsiteField>>>(
MODULES_API_URL + '/cms/cms-website-field/page',
{
params
}
);
if (res.data.code === 0) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 查询应用参数列表
*/
export async function listCmsWebsiteField(params?: CmsWebsiteFieldParam) {
const res = await request.get<ApiResult<CmsWebsiteField[]>>(
MODULES_API_URL + '/cms/cms-website-field',
{
params
}
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 添加应用参数
*/
export async function addCmsWebsiteField(data: CmsWebsiteField) {
const res = await request.post<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-website-field',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 修改应用参数
*/
export async function updateCmsWebsiteField(data: CmsWebsiteField) {
const res = await request.put<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-website-field',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 删除应用参数
*/
export async function removeCmsWebsiteField(id?: number) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-website-field/' + id
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 批量删除应用参数
*/
export async function removeBatchCmsWebsiteField(data: (number | undefined)[]) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-website-field/batch',
{
data
}
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 根据id查询应用参数
*/
export async function getCmsWebsiteField(id: number) {
const res = await request.get<ApiResult<CmsWebsiteField>>(
MODULES_API_URL + '/cms/cms-website-field/' + id
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 根据code查询应用参数
*/
export async function getCmsWebsiteFieldByCode(code: string) {
const res = await request.get<ApiResult<CmsWebsiteField>>(
MODULES_API_URL + '/cms/cms-website-field/getByCode/' + code
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 恢复项目参数
*/
export async function undeleteWebsiteField(id?: number) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/website-field/undelete/' + id
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 参数批量导入
*/
export async function importWebsiteField(file: File) {
const formData = new FormData();
formData.append('file', file);
const res = await request.post<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-website-field/import',
formData
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 查询项目参数列表
*/
export async function configWebsiteField(params?: CmsWebsiteFieldParam) {
const res = await request.get<ApiResult<Config>>(
MODULES_API_URL + '/cms/cms-website-field/config',
{
params,
headers: {
TenantId: TEMPLATE_ID
}
}
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}

View File

@@ -0,0 +1,65 @@
import type { PageParam } from '@/api';
/**
* 应用参数
*/
export interface CmsWebsiteField {
// 自增ID
id?: number;
// 类型0文本 1图片 2其他
type?: number;
// 名称
name?: string;
// 默认值
defaultValue?: string;
// 可修改的值 [on|off]
modifyRange?: string;
// 备注
comments?: string;
// css样式
style?: string;
// 名称
value?: any;
// 语言
lang?: string;
// 是否加密
encrypted?: boolean;
// 模板
template?: string;
// 排序(数字越小越靠前)
sortNumber?: number;
// 是否删除, 0否, 1是
deleted?: number;
// 租户id
tenantId?: number;
// 创建时间
createTime?: string;
}
/**
* 应用参数搜索条件
*/
export interface CmsWebsiteFieldParam extends PageParam {
id?: number;
keywords?: string;
}
export interface Config {
siteName?: string;
siteLogo?: string;
domain?: string;
icpNo?: string;
copyright?: string;
loginBgImg?: string;
address?: string;
tel?: string;
kefu2?: string;
kefu1?: string;
email?: string;
loginTitle?: string;
sysLogo?: string;
// 添加API地址配置项
ApiUrl?: string;
// 添加主题配置项
theme?: string;
}

View File

@@ -0,0 +1,106 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { CmsWebsiteSetting, CmsWebsiteSettingParam } from './model';
import { MODULES_API_URL } from '@/config/setting';
/**
* 分页查询网站设置
*/
export async function pageCmsWebsiteSetting(params: CmsWebsiteSettingParam) {
const res = await request.get<ApiResult<PageResult<CmsWebsiteSetting>>>(
MODULES_API_URL + '/cms/cms-website-setting/page',
{
params
}
);
if (res.data.code === 0) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 查询网站设置列表
*/
export async function listCmsWebsiteSetting(params?: CmsWebsiteSettingParam) {
const res = await request.get<ApiResult<CmsWebsiteSetting[]>>(
MODULES_API_URL + '/cms/cms-website-setting',
{
params
}
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 添加网站设置
*/
export async function addCmsWebsiteSetting(data: CmsWebsiteSetting) {
const res = await request.post<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-website-setting',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 修改网站设置
*/
export async function updateCmsWebsiteSetting(data: CmsWebsiteSetting) {
const res = await request.put<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-website-setting',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 删除网站设置
*/
export async function removeCmsWebsiteSetting(id?: number) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-website-setting/' + id
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 批量删除网站设置
*/
export async function removeBatchCmsWebsiteSetting(data: (number | undefined)[]) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-website-setting/batch',
{
data
}
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 根据id查询网站设置
*/
export async function getCmsWebsiteSetting(id: number) {
const res = await request.get<ApiResult<CmsWebsiteSetting>>(
MODULES_API_URL + '/cms/cms-website-setting/' + id
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}

View File

@@ -0,0 +1,55 @@
import type { PageParam } from '@/api';
/**
* 网站设置
*/
export interface CmsWebsiteSetting {
// 自增ID
id?: number;
// 关联网站ID
websiteId?: number;
// 是否官方插件
official?: string;
// 是否展示在插件市场
market?: string;
// 是否允许被搜索
search?: string;
// 是否共享
share?: string;
// 文章是否需要审核
articleReview?: boolean;
// 是否插件 0应用1 插件
plugin?: string;
// 编辑器类型 1 md-editor-v3, 2 tinymce-editor
editor?: number;
// 显示站内搜索
searchBtn?: string;
// 显示登录注册功能
loginBtn?: string;
// 显示悬浮客服工具
floatTool?: boolean;
// 显示版权信息
showCopyright?: boolean;
// 显示版权链接
copyrightLink?: string;
// 导航栏最多显示数量
maxMenuNum?: string;
// 排序号
sortNumber?: number;
// 是否删除, 0否, 1是
deleted?: number;
// 租户id
tenantId?: number;
// 创建时间
createTime?: string;
// 修改时间
updateTime?: string;
}
/**
* 网站设置搜索条件
*/
export interface CmsWebsiteSettingParam extends PageParam {
id?: number;
keywords?: string;
}

113
app/api/cms/link/index.ts Normal file
View File

@@ -0,0 +1,113 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { Link, LinkParam } from './model';
import { MODULES_API_URL } from '@/config/setting';
/**
* 分页查询链接
*/
export async function pageLink(params: LinkParam) {
const res = await request.get<ApiResult<PageResult<Link>>>(
MODULES_API_URL + '/oa/link/page',
{
params
}
);
if (res.data.code === 0) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 查询链接列表
*/
export async function listLink(params?: LinkParam) {
const res = await request.get<ApiResult<Link[]>>(
MODULES_API_URL + '/oa/link',
{
params
}
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 添加链接
*/
export async function addLink(data: Link) {
const res = await request.post<ApiResult<unknown>>(
MODULES_API_URL + '/oa/link',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 修改链接
*/
export async function updateLink(data: Link) {
const res = await request.put<ApiResult<unknown>>(
MODULES_API_URL + '/oa/link',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 删除链接
*/
export async function removeLink(id?: number) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/oa/link/' + id
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 批量删除链接
*/
export async function removeBatchLink(data: (number | undefined)[]) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/oa/link/batch',
{
data
}
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 检查IP是否存在
*/
export async function checkExistence(
field: string,
value: string,
id?: number
) {
const res = await request.get<ApiResult<unknown>>(
MODULES_API_URL + '/oa/link/existence',
{
params: { field, value, id }
}
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}

View File

@@ -0,0 +1,31 @@
import type { PageParam } from '@/api';
/**
* 链接
*/
export interface Link {
id?: number;
name?: string;
icon?: string;
url?: string;
linkType?: string;
appId?: number;
categoryId?: number;
userId?: number;
description?: string;
recommend?: number;
sortNumber?: number;
deleted?: number;
status?: number;
createTime?: number;
}
/**
* 链接搜索条件
*/
export interface LinkParam extends PageParam {
id?: number;
linkType?: string;
categoryId?: number;
name?: string;
}

259
app/api/developer/index.ts Normal file
View File

@@ -0,0 +1,259 @@
import request from '@/utils/request'
// ========== 权限申请接口 ==========
/**
* 获取权限申请列表
*/
export function getPermissionRequests(params?: {
page?: number
size?: number
status?: 'pending' | 'approved' | 'rejected'
}) {
return request.get<{
code: number
message: string
data: {
records: Array<{
id: string | number
repo: string
repoName: string
reason: string
status: 'pending' | 'approved' | 'rejected'
gitUsername: string
createdAt: string
reviewedAt?: string
reviewerName?: string
rejectReason?: string
}>
total: number
}
}>('/api/app/developer/permission-requests', { params })
}
/**
* 提交权限申请
*/
export function createPermissionRequest(data: {
repo: string
reason: string
gitUsername?: string
}) {
return request.post<{
code: number
message: string
data: {
id: string | number
repo: string
repoName: string
reason: string
status: 'pending'
createdAt: string
}
}>('/api/app/developer/permission-requests', data)
}
/**
* 获取权限申请统计
*/
export function getPermissionRequestStats() {
return request.get<{
code: number
message: string
data: {
pending: number
approved: number
rejected: number
total: number
}
}>('/api/app/developer/permission-requests/stats')
}
/**
* 获取可申请的仓库列表
*/
export function getAvailableRepositories() {
return request.get<{
code: number
message: string
data: Array<{
value: string
label: string
description: string
accessLevel?: 'read' | 'write' | 'admin'
isAccessible: boolean
}>
}>('/api/app/developer/permission-requests/available-repos')
}
// ========== Git账号绑定接口 ==========
/**
* 保存Git账号绑定信息
*/
export function saveGitAccount(data: {
username: string
email?: string
remark?: string
}) {
return request.post<{
code: number
message: string
data: {
userId: number
gitUsername: string
email?: string
remark?: string
savedAt: string
status: 'pending' | 'verified' | 'rejected'
}
}>('/api/app/developer/git-account', data)
}
/**
* 获取Git账号绑定状态
*/
export function getGitAccountStatus() {
return request.get<{
code: number
message: string
data: {
username?: string
email?: string
remark?: string
status: 'pending' | 'verified' | 'rejected' | 'not_bound'
lastUpdatedAt?: string
verificationNote?: string
}
}>('/api/app/developer/git-account/status')
}
/**
* 获取Gitea服务器信息
*/
export function getGiteaServerInfo() {
return request.get<{
code: number
message: string
data: {
url: string
version: string
registrationEnabled: boolean
requireEmailConfirmation: boolean
maxRepoCreation: number
}
}>('/api/app/developer/gitea-info')
}
// ========== 管理端 - Git账号审核接口 ==========
export interface GitAccountItem {
id: number
userId: number
username: string
email?: string
remark?: string
status: 'pending' | 'verified' | 'rejected'
verificationNote?: string
createTime: string
updateTime: string
tenantId: number
}
/**
* 分页查询Git账号绑定列表管理端
*/
export function pageGitAccounts(params?: {
page?: number
size?: number
status?: string
keyword?: string
}) {
return request.get<{
code: number
message: string
data: {
records: GitAccountItem[]
total: number
current: number
size: number
}
}>('/api/app/developer/git-account/list', { params })
}
/**
* 审核Git账号绑定 - 通过
*/
export function approveGitAccount(id: number, note?: string) {
return request.put<{
code: number
message: string
}>(`/api/app/developer/git-account/${id}/approve`, { note })
}
/**
* 审核Git账号绑定 - 拒绝
*/
export function rejectGitAccount(id: number, reason: string) {
return request.put<{
code: number
message: string
}>(`/api/app/developer/git-account/${id}/reject`, { reason })
}
// ========== 管理端 - 权限申请审核接口 ==========
export interface PermissionRequestItem {
id: number
userId: number
gitUsername: string
repo: string
repoName: string
reason: string
status: 'pending' | 'approved' | 'rejected'
createdAt: string
reviewedAt?: string
reviewerName?: string
rejectReason?: string
}
/**
* 分页查询权限申请列表(管理端)
*/
export function pagePermissionRequestsAdmin(params?: {
page?: number
size?: number
status?: string
keyword?: string
}) {
return request.get<{
code: number
message: string
data: {
records: PermissionRequestItem[]
total: number
current: number
size: number
}
}>('/api/app/developer/permission-requests/page', { params })
}
/**
* 审核权限申请 - 通过
*/
export function approvePermissionRequest(id: number, note?: string) {
return request.put<{
code: number
message: string
}>(`/api/app/developer/permission-requests/${id}/approve`, { note })
}
/**
* 审核权限申请 - 拒绝
*/
export function rejectPermissionRequest(id: number, reason: string) {
return request.put<{
code: number
message: string
}>(`/api/app/developer/permission-requests/${id}/reject`, { reason })
}

61
app/api/index.ts Normal file
View File

@@ -0,0 +1,61 @@
/**
* 接口统一返回结果
*/
export interface ApiResult<T> {
// 状态码
code: number;
// 状态信息
message?: string;
// 返回数据
data?: T;
}
/**
* 分页查询统一结果
*/
export interface PageResult<T> {
// 返回数据
list: T[];
// 总数量
count: number;
}
/**
* 分页查询基本参数
*/
export interface PageParam {
// 第几页
page?: number;
// 每页多少条
limit?: number;
// 排序字段
sort?: string;
sortNum?: string;
// 排序方式, asc升序, desc降序
order?: string;
// 租户ID
tenantId?: number;
// 企业ID
companyId?: number;
// 商户ID
merchantId?: number;
merchantName?: string;
categoryIds?: any;
// 商品分类
categoryId?: number;
categoryName?: string;
// 搜素关键词
keywords?: string;
// 起始时间
createTimeStart?: string;
// 结束时间
createTimeEnd?: string;
timeStart?: number;
timeEnd?: number;
isExpireTime?: number;
showSoldStatus?: boolean;
dateTime?: string;
sceneType?: string;
userId?: number;
lang?: string;
}

153
app/api/layout/index.ts Normal file
View File

@@ -0,0 +1,153 @@
import request from '@/utils/request';
import type { ApiResult } from '@/api';
import type { User } from '@/api/system/user/model';
import type { UpdatePasswordParam, NoticeResult } from './model';
import {SERVER_API_URL} from '@/config/setting';
import type { Company } from '@/api/system/company/model';
import type { AppProduct } from '@/api/cms/cmsWebsite/model';
import type { Menu } from "@/api/system/menu/model";
/**
* 获取当前登录的用户信息、菜单、权限、角色
*/
export async function getTenantInfo(): Promise<Company> {
const res = await request.get<ApiResult<Company>>(
SERVER_API_URL + '/auth/tenant'
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 获取网站信息 https://websopy-api.websoft.top/api
*/
export async function getSiteInfo() {
const res = await request.get<ApiResult<AppProduct>>(
'/shop/getShopInfo',
{
params: {}
}
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 获取当前登录的用户信息、菜单、权限、角色
*/
export async function getUserInfo(): Promise<User> {
const res = await request.get<ApiResult<User>>(SERVER_API_URL + '/auth/user');
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 修改当前登录用户信息
*/
export async function updateLoginUser(data: User) {
const res = await request.put<ApiResult<unknown>>(
SERVER_API_URL + '/auth/user',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 获取服务器时间(实时)
* @return
*/
export async function getServerTime() {
const res = await request.get<ApiResult<any>>(
'/cms/website/getServerTime'
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 获取未来7天的日期
* @return
*/
export async function getNext7day() {
const res = await request.get<ApiResult<any>>(
'/cms/website/getNext7day'
);
console.log('res.data.code: ', res.data.code);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 向子模块传递token
* @param url
*/
export async function transferToken(url: string): Promise<string> {
const res = await request.get<ApiResult<unknown>>(url);
return Promise.reject(new Error(res.data.message));
}
/**
* 修改当前登录的用户密码
*/
export async function updatePassword(
data: UpdatePasswordParam
): Promise<string> {
const res = await request.put<ApiResult<unknown>>(
SERVER_API_URL + '/auth/password',
data
);
if (res.data.code === 0) {
return res.data.message ?? '修改成功';
}
return Promise.reject(new Error(res.data.message));
}
/**
* 创建完整网站并初始化
*/
export async function createCmsWebSite(data: AppProduct){
const res = await request.post<ApiResult<unknown>>(
SERVER_API_URL + '/superAdminRegister',data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 租户初始化
*/
export async function initialization(roleId?: number) {
const res = await request.get<ApiResult<Menu[]>>(
SERVER_API_URL + '/system/tenant/role-menu/' + roleId
);
if (res.data.code === 0) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 查询未读通知
*/
export async function getUnreadNotice(): Promise<NoticeResult> {
return {
notice: [],
letter: [],
todo: []
};
}

View File

@@ -0,0 +1,74 @@
/**
* 首页布局样式
*/
export interface Layout {
// 内容区域的宽度
width?: string;
// 文字颜色
color?: string;
// 高亮颜色
hover?: string;
// 背景颜色
backgroundColor?: string;
headerStyle?: any;
siteNameStyle?: any;
}
/**
* 修改密码参数
*/
export interface UpdatePasswordParam {
// 新密码
password: string;
// 原始密码
oldPassword: string;
}
/**
* 通知数据格式
*/
export interface NoticeModel {
// 图标颜色
color?: string;
// 图标
icon?: string;
// 标题
title?: string;
// 时间
time?: string;
}
/**
* 私信数据格式
*/
export interface LetterModel {
// 头像
avatar?: string;
// 标题
title?: string;
// 内容
content?: string;
// 时间
time?: string;
}
/**
* 代办数据格式
*/
export interface TodoModel {
// 状态
status?: number;
// 标题
title?: string;
// 描述
description?: string;
}
/**
* 查询未读通知返回结果
*/
export interface NoticeResult {
notice: NoticeModel[];
letter: LetterModel[];
todo: TodoModel[];
}

View File

@@ -0,0 +1,50 @@
import {MODULES_API_URL} from '@/config/setting';
/**
* 小程序码参数
*/
export interface MiniProgramCodeParam {
page?: string;
scene: string;
width?: number;
checkPath?: boolean;
envVersion?: 'release' | 'trial' | 'develop';
}
/**
* 生成小程序码
*/
export async function generateMiniProgramCode(data: MiniProgramCodeParam) {
try {
const url = '/wx-login/getOrderQRCodeUnlimited/' + data.scene;
const fullUrl = MODULES_API_URL + `${url}`;
console.log('生成小程序码URL:', fullUrl);
console.log('小程序码参数:', data);
console.log('scene 参数:', data.scene);
// 直接返回URL让浏览器处理图片加载
// scene 参数中包含了租户ID信息
return fullUrl;
} catch (error: any) {
console.error('生成小程序码失败:', error);
throw new Error(error.message || '生成小程序码失败');
}
}
/**
* 生成邀请小程序码
*/
export async function generateInviteCode(inviterId: number) {
const scene = `uid_${inviterId}`;
console.log('生成邀请小程序码 scene:', scene);
return generateMiniProgramCode({
page: 'pages/index/index',
scene: scene,
width: 180,
checkPath: true,
envVersion: 'trial'
});
}

View File

@@ -0,0 +1,117 @@
import request from '@/utils/request';
import { setToken } from '@/utils/token-util';
import type { ApiResult } from '@/api';
import type {
LoginParam,
LoginResult,
CaptchaResult,
SmsCaptchaResult
} from './model';
import type { User } from '@/api/system/user/model';
import { SERVER_API_URL } from '@/config/setting';
/**
* 登录
*/
export async function login(data: LoginParam) {
const res = await request.post<ApiResult<LoginResult>>(
SERVER_API_URL + '/login',
data
);
if (res.data.code === 0) {
setToken(res.data.data?.access_token, data.remember);
if (res.data.data?.user) {
const user = res.data.data?.user;
localStorage.setItem('TenantId', String(user.tenantId));
localStorage.setItem('UserId', String(user.userId));
}
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 获取验证码
*/
export async function getCaptcha() {
const res = await request.get<ApiResult<CaptchaResult>>(
SERVER_API_URL + '/captcha'
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
export async function loginBySms(data: LoginParam) {
const res = await request.post<ApiResult<LoginResult>>(
SERVER_API_URL + '/loginBySms',
data
);
if (res.data.code === 0) {
setToken(res.data.data?.access_token, data.remember);
if (res.data.data?.user) {
const user = res.data.data?.user;
localStorage.setItem('TenantId', String(user.tenantId));
localStorage.setItem('UserId', String(user.userId));
}
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 发送短信验证码
*/
export async function sendSmsCaptcha(data: LoginParam) {
const res = await request.post<ApiResult<SmsCaptchaResult>>(
SERVER_API_URL + '/sendSmsCaptcha',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 登录
*/
export async function remoteLogin(data: LoginParam) {
const res = await request.post<ApiResult<LoginResult>>(
'https://open.gxwebsoft.com/api/login',
data
);
if (res.data.code === 0) {
setToken(res.data.data?.access_token, data.remember);
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 获取企业微信登录链接
*/
export async function getWxWorkQrConnect(data) {
const res = await request.post<ApiResult<unknown>>(
SERVER_API_URL + '/wx-work',
data
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
export async function registerUser(data: User) {
const res = await request.post<ApiResult<unknown>>(
SERVER_API_URL + '/register',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}

View File

@@ -0,0 +1,46 @@
import type { User } from '@/api/system/user/model';
/**
* 登录参数
*/
export interface LoginParam {
// 账号
username?: string;
// 密码
password?: string;
// 租户id
tenantId?: number;
// 是否记住密码
remember?: boolean;
// 手机号码
phone?: string;
// 短信验证码
code?: string;
}
/**
* 登录返回结果
*/
export interface LoginResult {
// token
access_token?: string;
// 用户信息
user?: User;
}
/**
* 图形验证码返回结果
*/
export interface CaptchaResult {
// 图形验证码base64数据
base64: string;
// 验证码文本
text: string;
}
/**
* 短信验证码返回结果
*/
export interface SmsCaptchaResult {
// 验证码文本
text: string;
}

View File

@@ -0,0 +1,212 @@
import request from '@/utils/request';
import type { ApiResult } from '@/api';
import { SERVER_API_URL } from '@/config/setting';
function isSuccess(code?: number) {
return code === 0 || code === 200;
}
/**
* 二维码生成响应数据
* 后端只返回二维码内容前端负责生成base64二维码图片
*/
export interface QrCodeResponse {
token: string; // 二维码唯一标识token
qrCodeContent: string; // 二维码内容前端用此生成base64 QRCode
expiresIn: number; // 过期时间(秒)
wechatScanUrl?: string; // 微信扫码登录H5页面URL备用
miniprogramPath?: string; // 微信小程序页面路径
miniprogramQrCodeUrl?: string; // 小程序码图片URL已废弃
miniprogramQrCode?: string; // 小程序码Base64图片扫码后直接打开小程序优先使用
}
/**
* 二维码状态响应
*/
export interface QrCodeStatusResponse {
status: 'pending' | 'scanned' | 'bind_phone' | 'confirmed' | 'expired';
accessToken?: string; // 登录成功时返回的JWT token
access_token?: string; // 兼容后端下划线命名
userInfo?: any; // 用户信息
expiresIn?: number; // 剩余过期时间(秒)
tenantId?: string | number; // 租户ID
message?: string;
needBindPhone?: boolean;
}
/**
* 确认登录请求参数
*/
export interface QrLoginConfirmRequest {
token: string; // 二维码token
userId?: number; // 用户ID
platform?: string; // 登录平台
}
/**
* 生成登录二维码
*/
export async function generateQrCode(): Promise<QrCodeResponse> {
const res = await request.post<ApiResult<QrCodeResponse>>(
SERVER_API_URL + '/qr-login/generate',
{}
);
if (isSuccess(res.data.code) && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message || '生成二维码失败'));
}
/**
* 检查二维码状态
*/
export async function checkQrCodeStatus(token: string): Promise<QrCodeStatusResponse> {
const res = await request.get<ApiResult<QrCodeStatusResponse>>(
SERVER_API_URL + `/qr-login/status/${token}`
);
if (isSuccess(res.data.code) && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message || '检查二维码状态失败'));
}
/**
* 扫码确认登录(移动端调用)
*/
export async function confirmQrLogin(requestData: QrLoginConfirmRequest): Promise<QrCodeStatusResponse> {
const res = await request.post<ApiResult<QrCodeStatusResponse>>(
SERVER_API_URL + '/qr-login/confirm',
requestData
);
if (isSuccess(res.data.code) && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message || '确认登录失败'));
}
/**
* 扫码标记(移动端扫码时调用)
*/
export async function scanQrCode(token: string): Promise<boolean> {
const res = await request.post<ApiResult<boolean>>(
SERVER_API_URL + `/qr-login/scan/${token}`
);
if (isSuccess(res.data.code)) {
return res.data.data || true;
}
return Promise.reject(new Error(res.data.message || '扫码失败'));
}
/**
* 微信小程序扫码登录确认
*/
export async function wechatMiniProgramConfirm(requestData: QrLoginConfirmRequest): Promise<QrCodeStatusResponse> {
const res = await request.post<ApiResult<QrCodeStatusResponse>>(
SERVER_API_URL + '/qr-login/wechat-confirm',
requestData
);
if (isSuccess(res.data.code) && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message || '微信小程序登录确认失败'));
}
// ============ 微信扫码登录 H5 相关 ============
/**
* 微信扫码登录响应(用于 H5 页面)
*/
export interface WechatScanResponse {
status: 'success' | 'confirmed' | 'bind_required' | 'bind_phone' | 'not_bound';
accessToken?: string;
access_token?: string;
userInfo?: any;
message?: string;
tenantId?: number;
}
/**
* 微信扫码登录请求
*/
export interface WechatScanRequest {
token: string;
code?: string;
unionId?: string;
openId?: string;
}
/**
* 微信扫码登录确认H5 页面调用)
*/
export async function wechatScanConfirm(requestData: WechatScanRequest): Promise<WechatScanResponse> {
const res = await request.post<ApiResult<WechatScanResponse>>(
SERVER_API_URL + '/qr-login/wechat-scan',
requestData
);
if (isSuccess(res.data.code) && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message || '微信扫码登录失败'));
}
/**
* 获取微信网页授权 URL
*/
export async function getWechatOAuthUrl(token: string): Promise<string> {
const res = await request.get<ApiResult<string>>(
SERVER_API_URL + '/qr-login/wechat-oauth-url',
{ params: { token } }
);
if (isSuccess(res.data.code) && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message || '获取授权链接失败'));
}
/**
* 获取微信带参数二维码图片URL用于扫码关注登录
*/
export async function getWechatQrCodeUrl(token: string): Promise<string> {
const res = await request.get<ApiResult<string>>(
SERVER_API_URL + `/qr-login/wechat-qrcode/${token}`
);
if (isSuccess(res.data.code) && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message || '获取微信二维码失败'));
}
export interface QrLoginBindPhoneRequest {
token: string;
phone: string;
code: string;
}
export async function bindQrLoginPhone(requestData: QrLoginBindPhoneRequest): Promise<QrCodeStatusResponse> {
const res = await request.post<ApiResult<QrCodeStatusResponse>>(
SERVER_API_URL + '/qr-login/bind-phone',
requestData
);
if (isSuccess(res.data.code) && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message || '绑定手机号失败'));
}

293
app/api/payment/index.ts Normal file
View File

@@ -0,0 +1,293 @@
/**
* 支付模块 API 封装
* 支持:微信 JSAPI / 支付宝 / Native / 余额
*/
import request from '@/utils/request'
import type { ApiResult } from '@/api'
import { SERVER_API_URL } from '@/config/setting'
/** 支付方式 */
export type PayType = 'wechat' | 'alipay' | 'native' | 'balance' | number
/** 支付渠道 */
export type PayChannel = 'wechat_jsapi' | 'alipay_wap' | 'wechat_native' | 'balance'
/** 支付参数 */
export interface PayParams {
orderNo: string
orderId?: number
payType: PayChannel
/** 微信 JSAPI 必填:用户 openid */
openId?: string
/** 微信 JSAPI 必填:支付主体类型 */
subject?: string
/** 支付主体描述 */
body?: string
/** 支付金额(分) */
totalAmount?: number
/** 前端回调 URL */
returnUrl?: string
}
/** 微信 JSAPI 支付参数 */
export interface WechatJsapiParams {
orderNo: string
openId: string
subject: string
body?: string
totalAmount?: number
returnUrl?: string
}
/** 支付宝 WAP/Web 支付参数 */
export interface AlipayParams {
orderNo: string
subject: string
body?: string
totalAmount?: number
returnUrl?: string
}
/** Native 支付参数 */
export interface NativeParams {
orderNo: string
subject: string
body?: string
totalAmount?: number
}
/** 支付结果 */
export interface PayResult {
codeUrl?: string // Native 支付二维码链接
qrcode?: string // 二维码内容
paymentUrl?: string // 跳转支付链接
payUrl?: string // 支付链接
prepayId?: string // 预支付订单号
mwebUrl?: string // 微信 H5 支付链接
tradeNo?: string // 交易流水号
orderNo?: string // 订单号
orderId?: number // 订单ID
}
/** 支付状态 */
export interface PayStatus {
paid: boolean
payStatus: number // 0 未支付1 已支付
orderStatus: number // 订单状态
payTime?: string // 支付时间
transactionId?: string // 微信/支付宝交易号
}
/**
* 统一支付接口
* @deprecated 使用具体渠道接口
*/
export async function createPayment(data: Record<string, unknown>): Promise<PayResult> {
const res = await request.post<ApiResult<PayResult>>(
SERVER_API_URL + '/system/payment/create',
data
)
if (res.data.code === 0) {
return res.data.data!
}
return Promise.reject(new Error(res.data.message))
}
/**
* 微信 JSAPI 支付
* 适用于微信内置浏览器 / 公众号 / 小程序环境
*/
export async function createWechatJsapiPay(params: WechatJsapiParams): Promise<PayResult> {
const res = await request.post<ApiResult<PayResult>>(
SERVER_API_URL + '/system/wx-jsapi-pay/unified-order',
params
)
if (res.data.code === 0) {
return res.data.data!
}
return Promise.reject(new Error(res.data.message))
}
/**
* 微信 H5 支付
* 适用于非微信浏览器
*/
export async function createWechatH5Pay(params: { orderNo: string; subject: string; body?: string; totalAmount?: number; returnUrl?: string }): Promise<PayResult> {
const res = await request.post<ApiResult<PayResult>>(
SERVER_API_URL + '/system/wx-h5-pay/unified-order',
params
)
if (res.data.code === 0) {
return res.data.data!
}
return Promise.reject(new Error(res.data.message))
}
/**
* 微信 Native 支付(扫码支付)
*/
export async function createWechatNativePay(params: NativeParams): Promise<PayResult> {
const res = await request.post<ApiResult<PayResult>>(
SERVER_API_URL + '/system/wx-native-pay/unified-order',
params
)
if (res.data.code === 0) {
return res.data.data!
}
return Promise.reject(new Error(res.data.message))
}
/**
* 支付宝 WAP/Web 支付
*/
export async function createAlipayPay(params: AlipayParams): Promise<PayResult> {
const res = await request.post<ApiResult<PayResult>>(
SERVER_API_URL + '/system/alipay/unified-order',
params
)
if (res.data.code === 0) {
return res.data.data!
}
return Promise.reject(new Error(res.data.message))
}
/**
* 查询支付状态
*/
export async function queryPayStatus(orderNo: string): Promise<PayStatus> {
const res = await request.get<ApiResult<PayStatus>>(
SERVER_API_URL + '/system/payment/query-status',
{ params: { orderNo } }
)
if (res.data.code === 0) {
return res.data.data!
}
return Promise.reject(new Error(res.data.message))
}
/**
* 取消订单
*/
export async function cancelOrder(orderId: number): Promise<void> {
const res = await request.post<ApiResult<void>>(
SERVER_API_URL + '/system/order/cancel',
{ orderId }
)
if (res.data.code !== 0) {
return Promise.reject(new Error(res.data.message))
}
}
/**
* 申请退款
*/
export async function applyRefund(orderId: number, reason?: string): Promise<void> {
const res = await request.post<ApiResult<void>>(
SERVER_API_URL + '/system/order/refund',
{ orderId, reason }
)
if (res.data.code !== 0) {
return Promise.reject(new Error(res.data.message))
}
}
/**
* 判断当前环境
*/
export function detectPayEnvironment(): 'wechat' | 'alipay' | 'desktop' | 'mobile' {
const ua = navigator.userAgent.toLowerCase()
// 微信环境
if (/micromessenger/.test(ua)) {
return 'wechat'
}
// 支付宝环境
if (/alipayclient/.test(ua)) {
return 'alipay'
}
// 移动端
if (/mobile|android|iphone|ipad|tablet/i.test(ua)) {
return 'mobile'
}
// 桌面端
return 'desktop'
}
/**
* 检测是否在微信内置浏览器
*/
export function isWechatBrowser(): boolean {
return /micromessenger/.test(navigator.userAgent.toLowerCase())
}
/**
* 检测是否在支付宝内置浏览器
*/
export function isAlipayBrowser(): boolean {
return /alipayclient/.test(navigator.userAgent.toLowerCase())
}
/**
* 调起微信 JSAPI 支付
* 需要先引入微信 JSSDK 并完成签名
*/
export function callWechatJsapi(params: {
appId: string
timestamp: string
nonceStr: string
package: string
signType?: string
paySign: string
}): Promise<'ok'> {
return new Promise((resolve, reject) => {
if (typeof window.WeixinJSBridge === 'undefined') {
// 尝试通过 WeChat JSSDK 调用
if (typeof window.jWeixin !== 'undefined') {
window.jWeixin.chooseWXPay({
...params,
success: () => resolve('ok'),
fail: (err: unknown) => reject(err)
})
} else {
reject(new Error('微信 JSSDK 未加载'))
}
return
}
window.WeixinJSBridge.invoke(
'getBrandWCPayRequest',
{
appId: params.appId,
timeStamp: params.timestamp,
nonceStr: params.nonceStr,
package: params.package,
signType: params.signType || 'MD5',
paySign: params.paySign
},
(res: { err_msg: string }) => {
if (res.err_msg === 'get_brand_wcpay_request:ok') {
resolve('ok')
} else if (res.err_msg === 'get_brand_wcpay_request:cancel') {
reject(new Error('用户取消支付'))
} else {
reject(new Error(res.err_msg))
}
}
)
})
}
// 扩展 Window 类型
declare global {
interface Window {
WeixinJSBridge?: {
invoke: (api: string, params: Record<string, unknown>, callback: (res: { err_msg: string }) => void) => void
}
jWeixin?: {
chooseWXPay: (params: Record<string, unknown> & { success?: () => void; fail?: (err: unknown) => void }) => void
}
}
}

View File

@@ -0,0 +1,105 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { ShopCommissionRole, ShopCommissionRoleParam } from './model';
/**
* 分页查询分红角色
*/
export async function pageShopCommissionRole(params: ShopCommissionRoleParam) {
const res = await request.get<ApiResult<PageResult<ShopCommissionRole>>>(
'/shop/shop-commission-role/page',
{
params
}
);
if (res.data.code === 0) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 查询分红角色列表
*/
export async function listShopCommissionRole(params?: ShopCommissionRoleParam) {
const res = await request.get<ApiResult<ShopCommissionRole[]>>(
'/shop/shop-commission-role',
{
params
}
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 添加分红角色
*/
export async function addShopCommissionRole(data: ShopCommissionRole) {
const res = await request.post<ApiResult<unknown>>(
'/shop/shop-commission-role',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 修改分红角色
*/
export async function updateShopCommissionRole(data: ShopCommissionRole) {
const res = await request.put<ApiResult<unknown>>(
'/shop/shop-commission-role',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 删除分红角色
*/
export async function removeShopCommissionRole(id?: number) {
const res = await request.delete<ApiResult<unknown>>(
'/shop/shop-commission-role/' + id
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 批量删除分红角色
*/
export async function removeBatchShopCommissionRole(data: (number | undefined)[]) {
const res = await request.delete<ApiResult<unknown>>(
'/shop/shop-commission-role/batch',
{
data
}
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 根据id查询分红角色
*/
export async function getShopCommissionRole(id: number) {
const res = await request.get<ApiResult<ShopCommissionRole>>(
'/shop/shop-commission-role/' + id
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}

View File

@@ -0,0 +1,35 @@
import type { PageParam } from '@/api';
/**
* 分红角色
*/
export interface ShopCommissionRole {
//
id?: number;
//
title?: string;
//
provinceId?: number;
//
cityId?: number;
//
regionId?: number;
// 状态, 0正常, 1异常
status?: number;
// 备注
description?: string;
// 租户id
tenantId?: number;
// 创建时间
createTime?: string;
//
sortNumber?: number;
}
/**
* 分红角色搜索条件
*/
export interface ShopCommissionRoleParam extends PageParam {
id?: number;
keywords?: string;
}

View File

@@ -0,0 +1,105 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { ShopCoupon, ShopCouponParam } from './model';
/**
* 分页查询优惠券
*/
export async function pageShopCoupon(params: ShopCouponParam) {
const res = await request.get<ApiResult<PageResult<ShopCoupon>>>(
'/shop/shop-coupon/page',
{
params
}
);
if (res.data.code === 0) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 查询优惠券列表
*/
export async function listShopCoupon(params?: ShopCouponParam) {
const res = await request.get<ApiResult<ShopCoupon[]>>(
'/shop/shop-coupon',
{
params
}
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 添加优惠券
*/
export async function addShopCoupon(data: ShopCoupon) {
const res = await request.post<ApiResult<unknown>>(
'/shop/shop-coupon',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 修改优惠券
*/
export async function updateShopCoupon(data: ShopCoupon) {
const res = await request.put<ApiResult<unknown>>(
'/shop/shop-coupon',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 删除优惠券
*/
export async function removeShopCoupon(id?: number) {
const res = await request.delete<ApiResult<unknown>>(
'/shop/shop-coupon/' + id
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 批量删除优惠券
*/
export async function removeBatchShopCoupon(data: (number | undefined)[]) {
const res = await request.delete<ApiResult<unknown>>(
'/shop/shop-coupon/batch',
{
data
}
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 根据id查询优惠券
*/
export async function getShopCoupon(id: number) {
const res = await request.get<ApiResult<ShopCoupon>>(
'/shop/shop-coupon/' + id
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}

View File

@@ -0,0 +1,71 @@
import type { PageParam } from '@/api/index';
import {ShopCouponApplyCate} from "@/api/shop/shopCouponApplyCate/model";
import {ShopCouponApplyItem} from "@/api/shop/shopCouponApplyItem/model";
/**
* 优惠券
*/
export interface ShopCoupon {
// id
id?: number;
// 优惠券名称
name?: string;
// 优惠券描述
description?: string;
// 优惠券类型(10满减券 20折扣券 30免费劵)
type?: number;
// 满减券-减免金额
reducePrice?: string;
// 折扣券-折扣率(0-100)
discount?: number;
// 最低消费金额
minPrice?: string;
// 到期类型(10领取后生效 20固定时间)
expireType?: number;
// 领取后生效-有效天数
expireDay?: number;
// 有效期开始时间
startTime?: string | Date;
// 有效期结束时间
endTime?: string | Date;
// 适用范围(10全部商品 20指定商品 30指定分类)
applyRange?: number;
// 适用范围配置(json格式)
applyRangeConfig?: string;
// 是否过期(0未过期 1已过期)
isExpire?: number;
// 排序(数字越小越靠前)
sortNumber?: number;
// 状态, 0正常, 1禁用
status?: number;
// 是否删除, 0否, 1是
deleted?: number;
// 创建用户ID
userId?: number;
// 租户id
tenantId?: number;
// 创建时间
createTime?: string | Date;
// 修改时间
updateTime?: string | Date;
// 发放总数量(-1表示无限制)
totalCount?: number;
// 已发放数量
issuedCount?: number;
// 每人限领数量(-1表示无限制)
limitPerUser?: number;
// 是否启用(0禁用 1启用)
enabled?: string;
couponApplyCateList?: ShopCouponApplyCate[];
couponApplyItemList?: ShopCouponApplyItem[];
}
/**
* 优惠券搜索条件
*/
export interface ShopCouponParam extends PageParam {
id?: number;
name?: string;
type?: number;
keywords?: string;
}

View File

@@ -0,0 +1,11 @@
/**
* 优惠券
*/
export interface ShopCouponApplyCate {
id?: number;
couponId?: number;
cateId?: number;
cateLevel?: number;
}

View File

@@ -0,0 +1,11 @@
/**
* 优惠券
*/
export interface ShopCouponApplyItem {
id?: number;
couponId?: number;
type?: number;
pk?: number;
}

View File

@@ -0,0 +1,158 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { ShopDealerApply, ShopDealerApplyParam } from './model';
/**
* 分页查询分销商申请记录表
*/
export async function pageShopDealerApply(params: ShopDealerApplyParam) {
const res = await request.get<ApiResult<PageResult<ShopDealerApply>>>(
'/shop/shop-dealer-apply/page',
{params}
);
if (res.data.code === 0) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 查询分销商申请记录表列表
*/
export async function listShopDealerApply(params?: ShopDealerApplyParam) {
const res = await request.get<ApiResult<ShopDealerApply[]>>(
'/shop/shop-dealer-apply',
{params}
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 添加分销商申请记录表
*/
export async function addShopDealerApply(data: ShopDealerApply) {
const res = await request.post<ApiResult<unknown>>(
'/shop/shop-dealer-apply',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 修改分销商申请记录表
*/
export async function updateShopDealerApply(data: ShopDealerApply) {
const res = await request.put<ApiResult<unknown>>(
'/shop/shop-dealer-apply',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 删除分销商申请记录表
*/
export async function removeShopDealerApply(id?: number) {
const res = await request.delete<ApiResult<unknown>>(
'/shop/shop-dealer-apply/' + id
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 批量删除分销商申请记录表
*/
export async function removeBatchShopDealerApply(data: (number | undefined)[]) {
const res = await request.delete<ApiResult<unknown>>(
'/shop/shop-dealer-apply/batch',
{
data
}
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 根据id查询分销商申请记录表
*/
export async function getShopDealerApply(id: number) {
const res = await request.get<ApiResult<ShopDealerApply>>(
'/shop/shop-dealer-apply/' + id
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 审核通过分销商申请
*/
export async function approveShopDealerApply(id: number) {
const res = await request.put<ApiResult<unknown>>(
`/shop/shop-dealer-apply/${id}/approve`
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 驳回分销商申请
*/
export async function rejectShopDealerApply(id: number, data: { rejectReason: string }) {
const res = await request.put<ApiResult<unknown>>(
`/shop/shop-dealer-apply/${id}/reject`,
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 批量审核通过分销商申请
*/
export async function batchApproveShopDealerApply(ids: number[]) {
const res = await request.put<ApiResult<unknown>>(
'/shop/shop-dealer-apply/batch-approve',
{ ids }
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 导入经销商申请
*/
export async function importShopDealerApplies(file: File) {
const formData = new FormData();
formData.append('file', file);
const res = await request.post<ApiResult<unknown>>(
'/shop/shop-dealer-apply/import',
formData
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}

View File

@@ -0,0 +1,61 @@
import type { PageParam } from '@/api';
/**
* 分销商申请记录表
*/
export interface ShopDealerApply {
// 主键ID
applyId?: number;
// 类型
type?: number;
// 用户ID
userId?: number;
// 昵称
nickName?: string;
// 姓名
realName?: string;
// 经销商名称
dealerName?: string;
// 手机号
mobile?: string;
// 分销比例
rate?: number;
// 推荐人用户ID
refereeId?: number;
// 推荐人姓名
refereeName?: string;
// 申请方式(10需后台审核 20无需审核)
applyType?: number;
// 申请时间
applyTime?: string | number | Date;
// 审核状态 (10待审核 20审核通过 30驳回)
applyStatus?: number;
// 审核时间
auditTime?: string | number | Date;
// 驳回原因
rejectReason?: string;
description?: string;
// 商城ID
tenantId?: number;
// 创建时间
createTime?: string;
// 修改时间
updateTime?: string;
}
/**
* 分销商申请记录表搜索条件
*/
export interface ShopDealerApplyParam extends PageParam {
applyId?: number;
userId?: number;
realName?: string;
dealerName?: string;
mobile?: string;
refereeId?: number;
applyType?: number;
applyStatus?: number;
startTime?: string;
endTime?: string;
keywords?: string;
}

View File

@@ -0,0 +1,105 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { ShopDealerCapital, ShopDealerCapitalParam } from './model';
/**
* 分页查询分销商资金明细表
*/
export async function pageShopDealerCapital(params: ShopDealerCapitalParam) {
const res = await request.get<ApiResult<PageResult<ShopDealerCapital>>>(
'/shop/shop-dealer-capital/page',
{
params
}
);
if (res.data.code === 0) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 查询分销商资金明细表列表
*/
export async function listShopDealerCapital(params?: ShopDealerCapitalParam) {
const res = await request.get<ApiResult<ShopDealerCapital[]>>(
'/shop/shop-dealer-capital',
{
params
}
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 添加分销商资金明细表
*/
export async function addShopDealerCapital(data: ShopDealerCapital) {
const res = await request.post<ApiResult<unknown>>(
'/shop/shop-dealer-capital',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 修改分销商资金明细表
*/
export async function updateShopDealerCapital(data: ShopDealerCapital) {
const res = await request.put<ApiResult<unknown>>(
'/shop/shop-dealer-capital',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 删除分销商资金明细表
*/
export async function removeShopDealerCapital(id?: number) {
const res = await request.delete<ApiResult<unknown>>(
'/shop/shop-dealer-capital/' + id
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 批量删除分销商资金明细表
*/
export async function removeBatchShopDealerCapital(data: (number | undefined)[]) {
const res = await request.delete<ApiResult<unknown>>(
'/shop/shop-dealer-capital/batch',
{
data
}
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 根据id查询分销商资金明细表
*/
export async function getShopDealerCapital(id: number) {
const res = await request.get<ApiResult<ShopDealerCapital>>(
'/shop/shop-dealer-capital/' + id
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}

View File

@@ -0,0 +1,39 @@
import type { PageParam } from '@/api';
/**
* 分销商资金明细表
*/
export interface ShopDealerCapital {
// 主键ID
id?: number;
// 分销商用户ID
userId?: number;
// 订单ID
orderId?: number;
// 订单编号
orderNo?: string;
// 资金流动类型 (10佣金收入 20提现支出 30转账支出 40转账收入)
flowType?: number;
// 金额
money?: string;
// 描述
description?: string;
// 对方用户ID
toUserId?: number;
// 商城ID
tenantId?: number;
// 创建时间
createTime?: string;
// 修改时间
updateTime?: string;
}
/**
* 分销商资金明细表搜索条件
*/
export interface ShopDealerCapitalParam extends PageParam {
id?: number;
userId?: number;
toUserId?: number;
keywords?: string;
}

Some files were not shown because too many files have changed in this diff Show More