407 lines
14 KiB
TypeScript
407 lines
14 KiB
TypeScript
import type { BusinessType, PageResult } from '@/types/api'
|
||
import type { Case } from '@/types/business/cases'
|
||
import type {
|
||
Address,
|
||
ChangePasswordParams,
|
||
Feedback,
|
||
FavoritesQuery,
|
||
HelpFaqGroup,
|
||
ListQuery,
|
||
Profile,
|
||
Qualification,
|
||
QualificationInput,
|
||
} from '@/types/business/profile'
|
||
|
||
// TODO(api): 待接口文档到位后,将以下 mock 替换为 request<T> 调用(页面 → store → api 数据流不变)
|
||
|
||
const MOCK_PROFILE: Profile = {
|
||
nickname: '王永志',
|
||
phone: '186****618',
|
||
email: 'yongzh******4@163.com',
|
||
passwordModifiedAt: '15天前',
|
||
}
|
||
|
||
export function getProfile(): Promise<Profile> {
|
||
return Promise.resolve({ ...MOCK_PROFILE })
|
||
}
|
||
|
||
export function updateNickname(name: string): Promise<Profile> {
|
||
MOCK_PROFILE.nickname = name
|
||
return Promise.resolve({ ...MOCK_PROFILE })
|
||
}
|
||
|
||
export function changePassword(params: ChangePasswordParams): Promise<void> {
|
||
MOCK_PROFILE.passwordModifiedAt = '刚刚'
|
||
void params
|
||
return Promise.resolve()
|
||
}
|
||
|
||
export function bindPhone(phone: string, code: string): Promise<Profile> {
|
||
void code
|
||
MOCK_PROFILE.phone = phone
|
||
return Promise.resolve({ ...MOCK_PROFILE })
|
||
}
|
||
|
||
export function bindEmail(email: string, code: string): Promise<Profile> {
|
||
void code
|
||
MOCK_PROFILE.email = email
|
||
return Promise.resolve({ ...MOCK_PROFILE })
|
||
}
|
||
|
||
export function unbindEmail(): Promise<Profile> {
|
||
MOCK_PROFILE.email = ''
|
||
return Promise.resolve({ ...MOCK_PROFILE })
|
||
}
|
||
|
||
export function verifyIdentity(phone: string, code: string): Promise<void> {
|
||
void phone
|
||
void code
|
||
return Promise.resolve()
|
||
}
|
||
|
||
export function deleteAccount(): Promise<void> {
|
||
return Promise.resolve()
|
||
}
|
||
|
||
const MOCK_ADDRESSES: Address[] = [
|
||
{
|
||
id: 'addr-1',
|
||
receiverName: '王永志',
|
||
phone: '18556669516',
|
||
region: '山东省日照市东港区',
|
||
detailAddress: '凌云购物广场三楼',
|
||
isDefault: true,
|
||
},
|
||
{
|
||
id: 'addr-2',
|
||
receiverName: '王永志',
|
||
phone: '18556669516',
|
||
region: '山东省日照市东港区',
|
||
detailAddress: '海曲东路 12 号研发中心 A 座 8 层',
|
||
isDefault: false,
|
||
},
|
||
{
|
||
id: 'addr-3',
|
||
receiverName: '李晓婷',
|
||
phone: '13863331234',
|
||
region: '山东省青岛市市南区',
|
||
detailAddress: '香港中路 76 号 A 座 18 层',
|
||
isDefault: false,
|
||
},
|
||
{
|
||
id: 'addr-4',
|
||
receiverName: '王永志',
|
||
phone: '18556669516',
|
||
region: '山东省济南市历下区',
|
||
detailAddress: '经十路 9999 号舜耕大厦 12 层',
|
||
isDefault: false,
|
||
},
|
||
]
|
||
|
||
function paginate<T>(list: T[], query: ListQuery): PageResult<T> {
|
||
const start = (query.page - 1) * query.pageSize
|
||
return {
|
||
list: list.slice(start, start + query.pageSize),
|
||
total: list.length,
|
||
}
|
||
}
|
||
|
||
export function getAddresses(query: ListQuery): Promise<PageResult<Address>> {
|
||
return Promise.resolve(paginate(MOCK_ADDRESSES, query))
|
||
}
|
||
|
||
export function createAddress(input: Omit<Address, 'id' | 'isDefault'>): Promise<Address> {
|
||
const created: Address = {
|
||
...input,
|
||
id: `addr-${Date.now()}`,
|
||
isDefault: MOCK_ADDRESSES.length === 0,
|
||
}
|
||
MOCK_ADDRESSES.push(created)
|
||
return Promise.resolve({ ...created })
|
||
}
|
||
|
||
export function updateAddress(id: string, input: Omit<Address, 'id' | 'isDefault'>): Promise<Address> {
|
||
const found = MOCK_ADDRESSES.find((item) => item.id === id)
|
||
if (!found) return Promise.reject(new Error('地址不存在'))
|
||
Object.assign(found, input)
|
||
return Promise.resolve({ ...found })
|
||
}
|
||
|
||
export function deleteAddress(id: string): Promise<void> {
|
||
const index = MOCK_ADDRESSES.findIndex((item) => item.id === id)
|
||
if (index >= 0) MOCK_ADDRESSES.splice(index, 1)
|
||
return Promise.resolve()
|
||
}
|
||
|
||
export function setDefaultAddress(id: string): Promise<Address[]> {
|
||
for (const item of MOCK_ADDRESSES) {
|
||
item.isDefault = item.id === id
|
||
}
|
||
return Promise.resolve(MOCK_ADDRESSES.map((item) => ({ ...item })))
|
||
}
|
||
|
||
const MOCK_FAVORITES: Case[] = [
|
||
{
|
||
id: 'fav-1',
|
||
title: '自动化生产线升级改造项目',
|
||
category: 'manufacturing',
|
||
cover: '',
|
||
finishDate: '2026/8/10',
|
||
teamSize: 50,
|
||
scale: '300万',
|
||
industry: '自动化',
|
||
duration: '150个工作日',
|
||
clientType: '企业',
|
||
sections: [
|
||
{ title: '项目背景', content: '<p>传统产线效率低、人工依赖高,客户需要通过自动化升级提升产能与品控水平。</p>' },
|
||
{ title: '客户痛点', content: '<p>1、产线依赖人工巡检,异常响应慢;2、设备数据孤岛,缺乏统一监控;3、工艺参数无法追溯。</p>' },
|
||
{ title: '需求描述', content: '<p>建设产线数据采集与监控平台,完成关键工位自动化改造,打通 MES 系统接口。</p>' },
|
||
{ title: '交付物', content: '<p>1、产线自动化改造方案;2、PLC 控制程序与上位机软件;3、数据看板与运维手册;4、培训与质保服务。</p>' },
|
||
],
|
||
video: '',
|
||
isFavorite: true,
|
||
favoriteCount: 0,
|
||
},
|
||
{
|
||
id: 'fav-2',
|
||
title: '智能工厂物联网整体解决方案',
|
||
category: 'iot',
|
||
cover: '',
|
||
finishDate: '2026/8/10',
|
||
teamSize: 30,
|
||
scale: '500万',
|
||
industry: '工厂服务',
|
||
duration: '200个工作日',
|
||
clientType: '企业',
|
||
sections: [
|
||
{ title: '项目背景', content: '<p>园区工厂多系统独立运行,能耗与设备管理粗放,需要整体数字化升级。</p>' },
|
||
{ title: '客户痛点', content: '<p>1、门禁/监控/能耗子系统数据不互通;2、能源浪费缺乏精细监测;3、决策缺少实时数据支撑。</p>' },
|
||
{ title: '需求描述', content: '<p>构建 IoT 平台接入设备数据,建设综合驾驶舱,实现能耗监测与智能告警。</p>' },
|
||
{ title: '交付物', content: '<p>1、IoT 接入平台;2、综合驾驶舱大屏;3、能耗分析系统;4、集成联调与培训服务。</p>' },
|
||
],
|
||
video: '',
|
||
isFavorite: true,
|
||
favoriteCount: 0,
|
||
},
|
||
{
|
||
id: 'fav-3',
|
||
title: '智能穿戴设备PCB设计与量产',
|
||
category: 'hardware',
|
||
cover: '',
|
||
finishDate: '2026/8/10',
|
||
teamSize: 50,
|
||
scale: '10-50万',
|
||
industry: '智能设备',
|
||
duration: '30个工作日',
|
||
clientType: '企业',
|
||
sections: [
|
||
{ title: '项目背景', content: '<p>客户推出新一代智能穿戴产品,需要高集成度低功耗 PCB 设计并快速量产。</p>' },
|
||
{ title: '客户痛点', content: '<p>1、板载空间受限,器件布局密集;2、功耗要求严格;3、量产良率需爬坡。</p>' },
|
||
{ title: '需求描述', content: '<p>完成原理图与 PCB 设计、打样验证、SMT 贴片与整机装配量产。</p>' },
|
||
{ title: '交付物', content: '<p>1、原理图与 PCB 设计文件;2、样板与测试报告;3、量产良率报告;4、BOM 与工艺文件。</p>' },
|
||
],
|
||
video: '',
|
||
isFavorite: true,
|
||
favoriteCount: 0,
|
||
},
|
||
{
|
||
id: 'fav-4',
|
||
title: '智能园区综合管理平台开发',
|
||
category: 'internet',
|
||
cover: '',
|
||
finishDate: '2026/8/10',
|
||
teamSize: 20,
|
||
scale: '200万',
|
||
industry: '园区服务',
|
||
duration: '200个工作日',
|
||
clientType: '企业',
|
||
sections: [
|
||
{ title: '项目背景', content: '<p>传统园区管理普遍"数据孤岛",安防、能耗、物业、招商等系统独立运行,缺乏联动,管理手段依赖人工巡检和纸质流程。</p>' },
|
||
{ title: '客户痛点', content: '<p>1、运营效率低下:安保依赖人工巡逻;2、系统孤岛严重:门禁、监控、停车、能耗等子系统独立建设;3、能源浪费突出;4、服务体验欠佳;5、决策缺乏依据;6、安全隐患犹存。</p>' },
|
||
{ title: '需求描述', content: '<p>打造集"感知、预警、分析、决策、服务"于一体的智能园区综合管理平台,打通园区各子系统壁垒,实现全场景数字化覆盖。</p>' },
|
||
{ title: '交付物', content: '<p>1、Web 端管理平台(驾驶舱/安防/能源/物业);2、移动端服务门户;3、IoT 平台与数据大屏;4、全套技术文档;5、培训与不少于1年免费质保。</p>' },
|
||
],
|
||
video: '',
|
||
isFavorite: true,
|
||
favoriteCount: 0,
|
||
},
|
||
]
|
||
|
||
export function getFavorites(query: FavoritesQuery): Promise<PageResult<Case>> {
|
||
const filtered = MOCK_FAVORITES.filter((item) => {
|
||
if (query.category !== 'all' && item.category !== query.category) return false
|
||
if (query.keyword && !item.title.includes(query.keyword)) return false
|
||
return true
|
||
})
|
||
const start = (query.page - 1) * query.pageSize
|
||
return Promise.resolve({
|
||
list: filtered.slice(start, start + query.pageSize).map((item) => ({ ...item })),
|
||
total: filtered.length,
|
||
})
|
||
}
|
||
|
||
export function getCaseCounts(): Promise<Partial<Record<BusinessType, number>>> {
|
||
const counts: Partial<Record<BusinessType, number>> = {
|
||
internet: 1,
|
||
hardware: 1,
|
||
iot: 1,
|
||
manufacturing: 1,
|
||
}
|
||
return Promise.resolve(counts)
|
||
}
|
||
|
||
const MOCK_QUALIFICATIONS: Qualification[] = [
|
||
{
|
||
id: 'qual-1',
|
||
type: '体系认证',
|
||
certName: 'ISO9001 质量管理体系认证证书',
|
||
certNo: 'ISO202609080075',
|
||
issuer: '中国质量认证中心',
|
||
validFrom: '2026-9-10',
|
||
validTo: '2027-9-10',
|
||
status: '已认证',
|
||
attachments: [
|
||
{ name: '体系认证证书', size: 1_048_576, uploadTime: '2026-09-10', url: '' },
|
||
],
|
||
},
|
||
{
|
||
id: 'qual-2',
|
||
type: '营业执照',
|
||
certName: '营业执照',
|
||
certNo: '91371102MA3XX8876Q',
|
||
issuer: '日照市东港区市场监督管理局',
|
||
validFrom: '2020-3-15',
|
||
validTo: '2030-3-14',
|
||
status: '审核中',
|
||
attachments: [
|
||
{ name: '营业执照', size: 820_000, uploadTime: '2026-09-12', url: '' },
|
||
],
|
||
},
|
||
{
|
||
id: 'qual-3',
|
||
type: '检测报告',
|
||
certName: '智能终端产品第三方检测报告',
|
||
certNo: 'WT20260512001',
|
||
issuer: '山东省产品质量检验研究院',
|
||
validFrom: '2026-5-12',
|
||
validTo: '2027-5-12',
|
||
status: '未通过',
|
||
attachments: [
|
||
{ name: '检测报告', size: 2_097_152, uploadTime: '2026-05-15', url: '' },
|
||
],
|
||
},
|
||
{
|
||
id: 'qual-4',
|
||
type: '生产许可证',
|
||
certName: '全国工业产品生产许可证',
|
||
certNo: 'XK06-123-45678',
|
||
issuer: '山东省市场监督管理局',
|
||
validFrom: '2024-1-8',
|
||
validTo: '2029-1-7',
|
||
status: '已认证',
|
||
attachments: [
|
||
{ name: '生产许可证', size: 1_258_291, uploadTime: '2024-01-10', url: '' },
|
||
],
|
||
},
|
||
]
|
||
|
||
export function getQualifications(query: ListQuery): Promise<PageResult<Qualification>> {
|
||
return Promise.resolve(paginate(MOCK_QUALIFICATIONS, query))
|
||
}
|
||
|
||
export function createQualification(input: QualificationInput): Promise<Qualification> {
|
||
const created: Qualification = {
|
||
...input,
|
||
id: `qual-${Date.now()}`,
|
||
status: '审核中',
|
||
}
|
||
MOCK_QUALIFICATIONS.unshift(created)
|
||
return Promise.resolve({ ...created })
|
||
}
|
||
|
||
export function updateQualification(id: string, input: QualificationInput): Promise<Qualification> {
|
||
const found = MOCK_QUALIFICATIONS.find((item) => item.id === id)
|
||
if (!found) return Promise.reject(new Error('资质不存在'))
|
||
found.type = input.type
|
||
found.certName = input.certName
|
||
found.certNo = input.certNo
|
||
found.issuer = input.issuer
|
||
found.validFrom = input.validFrom
|
||
found.validTo = input.validTo
|
||
found.attachments = input.attachments
|
||
if (found.status === '未通过') found.status = '审核中'
|
||
return Promise.resolve({ ...found })
|
||
}
|
||
|
||
export function deleteQualification(id: string): Promise<void> {
|
||
const index = MOCK_QUALIFICATIONS.findIndex((item) => item.id === id)
|
||
if (index >= 0) MOCK_QUALIFICATIONS.splice(index, 1)
|
||
return Promise.resolve()
|
||
}
|
||
|
||
export function submitFeedback(feedback: Feedback): Promise<void> {
|
||
void feedback
|
||
return Promise.resolve()
|
||
}
|
||
|
||
/** TODO(api): 后端帮助中心接口就绪后改为 request 调用;暂用设计稿假数据 */
|
||
export function getHelpFaqs(): Promise<HelpFaqGroup[]> {
|
||
return Promise.resolve([
|
||
{
|
||
title: '账户与登录',
|
||
items: [
|
||
{
|
||
q: '如何注册账号?',
|
||
a: '打开APP后点击“注册”,输入手机号获取验证码,设置登录密码即可完成注册。',
|
||
},
|
||
{
|
||
q: '忘记密码怎么办?',
|
||
a: '在登录页面点击“忘记密码”,输入注册手机号获取验证码,验证通过后即可重置新密码。',
|
||
},
|
||
{
|
||
q: '一个账号可以多端登录吗?',
|
||
a: '同一账号仅允许在 1 台设备上保持在线,超出将自动踢出最早登录的设备。',
|
||
},
|
||
{
|
||
q: '如何修改绑定手机号?',
|
||
a: '进入「我的 -> 设置 -> 账户安全 -> 更换手机号」,验证原手机号后即可绑定新号码。',
|
||
},
|
||
],
|
||
},
|
||
{
|
||
title: '功能使用指南',
|
||
items: [
|
||
{
|
||
q: '如何提交报修/工单?',
|
||
a: '首页点击「报修」 -> 选择报修类型 -> 填写问题描述并上传图片 -> 提交。提交后可在「我的 -> 我的工单」中查看处理进度。',
|
||
},
|
||
{
|
||
q: '如何预约会议室?',
|
||
a: '进入「服务 -> 会议室预订」,选择日期、时间段及会议室,确认后提交预约,预约成功将收到消息通知。',
|
||
},
|
||
{
|
||
q: '如何查看我的消息通知?',
|
||
a: '首页右上角铃铛图标进入消息中心,支持按“全部 / 未读 / 系统通知 / 业务提醒”分类查看。',
|
||
},
|
||
],
|
||
},
|
||
{
|
||
title: '系统与权限',
|
||
items: [
|
||
{
|
||
q: 'APP提示“无权限”怎么办?',
|
||
a: '部分功能需要管理员授权后方可使用,请联系贵司系统管理员为您分配对应角色权限。',
|
||
},
|
||
{
|
||
q: '为什么收不到推送通知?',
|
||
a: '请检查:①手机系统设置中是否允许本APP发送通知;②APP内「我的 -> 设置 -> 消息推送」是否已开启。',
|
||
},
|
||
{
|
||
q: 'APP支持哪些系统版本?',
|
||
a: 'iOS 13.0 及以上版本,Android 8.0 及以上版本。建议使用最新系统版本以获得最佳体验。',
|
||
},
|
||
],
|
||
},
|
||
])
|
||
}
|