小程序一些功能更新
This commit is contained in:
64
api/admin/v1/attachment.go
Normal file
64
api/admin/v1/attachment.go
Normal file
@@ -0,0 +1,64 @@
|
||||
package v1
|
||||
|
||||
import "github.com/gogf/gf/v2/frame/g"
|
||||
|
||||
// ============================================================================
|
||||
// 管理端附件管理契约(迭代-2026-09-29):upload / list / delete
|
||||
//
|
||||
// 所有上传(含用户端头像)都会登记到 attachments 表;本模块提供后台统一查看、
|
||||
// 上传日期、删除。删除为「记录软删 + 文件本体按引用检查」:仍被头像/封面等引用
|
||||
// 的文件只移除记录不删文件,返回 removed_file=false 说明这一点。
|
||||
// ============================================================================
|
||||
|
||||
// AdminUploadReq 管理端上传(multipart/form-data,文件字段名 file,表单字段 scene=cover|attachment)
|
||||
type AdminUploadReq struct {
|
||||
g.Meta `path:"/admin/upload" method:"post" mime:"multipart/form-data" tags:"admin" summary:"管理端上传文件"`
|
||||
Scene string `v:"required|in:cover,attachment#请指定上传场景|不支持的上传场景" json:"scene"`
|
||||
}
|
||||
type AdminUploadRes struct {
|
||||
Id int64 `json:"id"` // 附件登记 id(0 = 登记跳过/失败,不影响文件可用)
|
||||
Url string `json:"url"` // 绝对 URL(按 site.base_url 现拼,直接展示用)
|
||||
Path string `json:"path"` // 相对路径(/static/...)—— 商品封面等库内只存这个
|
||||
FileName string `json:"file_name"` // 原始文件名
|
||||
Ext string `json:"ext"` // 扩展名(小写含点)
|
||||
SizeBytes int64 `json:"size_bytes"` // 字节
|
||||
}
|
||||
|
||||
// AdminAttachmentItem 附件列表项(响应 snake_case)
|
||||
type AdminAttachmentItem struct {
|
||||
Id int64 `json:"id"`
|
||||
Scene string `json:"scene"` // avatar / cover / attachment
|
||||
FileName string `json:"file_name"`
|
||||
FilePath string `json:"file_path"`
|
||||
Url string `json:"url"` // 绝对 URL(现拼)
|
||||
Ext string `json:"ext"`
|
||||
SizeBytes int64 `json:"size_bytes"`
|
||||
Md5 string `json:"md5"`
|
||||
UploaderId int64 `json:"uploader_id"`
|
||||
UploaderType string `json:"uploader_type"` // admin / user
|
||||
IsReferenced bool `json:"is_referenced"` // 是否仍被头像/封面/其他记录引用
|
||||
IsImage bool `json:"is_image"` // 是否图片(可缩略预览)
|
||||
CreatedAt string `json:"created_at"` // 上传日期
|
||||
}
|
||||
|
||||
// AdminAttachmentListReq 附件列表
|
||||
type AdminAttachmentListReq struct {
|
||||
g.Meta `path:"/admin/attachment/list" method:"get" tags:"admin" summary:"附件列表"`
|
||||
Keyword string `json:"keyword"` // 文件名模糊
|
||||
Scene string `json:"scene"` // 空=全部;avatar/cover/attachment
|
||||
Page int `json:"page"`
|
||||
PageSize int `json:"pageSize"`
|
||||
}
|
||||
type AdminAttachmentListRes struct {
|
||||
List []AdminAttachmentItem `json:"list"`
|
||||
Total int `json:"total"`
|
||||
}
|
||||
|
||||
// AdminAttachmentDeleteReq 删除附件(记录软删;文件本体无引用时才落盘删除)
|
||||
type AdminAttachmentDeleteReq struct {
|
||||
g.Meta `path:"/admin/attachment/delete" method:"post" tags:"admin" summary:"删除附件"`
|
||||
Id int64 `v:"required" json:"id"`
|
||||
}
|
||||
type AdminAttachmentDeleteRes struct {
|
||||
RemovedFile bool `json:"removed_file"` // false = 文件仍被引用,仅移除了登记记录
|
||||
}
|
||||
89
api/admin/v1/goods.go
Normal file
89
api/admin/v1/goods.go
Normal file
@@ -0,0 +1,89 @@
|
||||
package v1
|
||||
|
||||
import "github.com/gogf/gf/v2/frame/g"
|
||||
|
||||
// ============================================================================
|
||||
// 管理端软件开发服务契约(迭代-2026-09-29):list / detail / save / delete
|
||||
//
|
||||
// 封面 cover_path 库内存相对路径(/static/...);响应里 cover_url 为按
|
||||
// site.base_url 拼接的绝对地址。content_md 为 Markdown 原文,管理端编辑预览、
|
||||
// 小程序端解析渲染(富文本节点),后端只存原文不渲染。
|
||||
// ============================================================================
|
||||
|
||||
// AdminGoodsItem 服务列表项(响应 snake_case,不含 content_md —— 详情接口单独取)
|
||||
type AdminGoodsItem struct {
|
||||
Id int64 `json:"id"`
|
||||
Category int `json:"category"`
|
||||
CategoryName string `json:"category_name"`
|
||||
Title string `json:"title"`
|
||||
Summary string `json:"summary"`
|
||||
CoverPath string `json:"cover_path"`
|
||||
CoverUrl string `json:"cover_url"`
|
||||
PriceCents int64 `json:"price_cents"`
|
||||
PriceNote string `json:"price_note"`
|
||||
Sort int `json:"sort"`
|
||||
IsEnabled int `json:"is_enabled"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
UpdatedAt string `json:"updated_at"`
|
||||
}
|
||||
|
||||
// AdminGoodsListReq 服务列表
|
||||
type AdminGoodsListReq struct {
|
||||
g.Meta `path:"/admin/goods/list" method:"get" tags:"admin" summary:"软件开发服务列表"`
|
||||
Keyword string `json:"keyword"`
|
||||
Category int `json:"category"` // 0=全部
|
||||
IsEnabled *int `json:"isEnabled"`
|
||||
Page int `json:"page"`
|
||||
PageSize int `json:"pageSize"`
|
||||
SortBy string `json:"sortBy"`
|
||||
SortOrder string `json:"sortOrder"` // asc / desc
|
||||
}
|
||||
type AdminGoodsListRes struct {
|
||||
List []AdminGoodsItem `json:"list"`
|
||||
Total int `json:"total"`
|
||||
}
|
||||
|
||||
// AdminGoodsDetailReq 服务详情(编辑回填,含 content_md)
|
||||
type AdminGoodsDetailReq struct {
|
||||
g.Meta `path:"/admin/goods/detail" method:"get" tags:"admin" summary:"软件开发服务详情"`
|
||||
Id int64 `v:"required" json:"id"`
|
||||
}
|
||||
type AdminGoodsDetailRes struct {
|
||||
Id int64 `json:"id"`
|
||||
Category int `json:"category"`
|
||||
CategoryName string `json:"category_name"`
|
||||
Title string `json:"title"`
|
||||
Summary string `json:"summary"`
|
||||
ContentMd string `json:"content_md"`
|
||||
CoverPath string `json:"cover_path"`
|
||||
CoverUrl string `json:"cover_url"`
|
||||
PriceCents int64 `json:"price_cents"`
|
||||
PriceNote string `json:"price_note"`
|
||||
Sort int `json:"sort"`
|
||||
IsEnabled int `json:"is_enabled"`
|
||||
}
|
||||
|
||||
// AdminGoodsSaveReq 新增/编辑服务(id=0 新建)。coverPath 传上传接口返回的 path(相对路径)。
|
||||
type AdminGoodsSaveReq struct {
|
||||
g.Meta `path:"/admin/goods/save" method:"post" tags:"admin" summary:"保存软件开发服务"`
|
||||
Id int64 `json:"id"`
|
||||
Category int `v:"required|in:1,2,3,4#请选择分类|分类不合法" json:"category"`
|
||||
Title string `v:"required#请填写服务名称" json:"title"`
|
||||
Summary string `v:"length:0,500#简介最多 500 字" json:"summary"`
|
||||
ContentMd string `json:"contentMd"`
|
||||
PriceCents int64 `v:"min:0#价格不能为负" json:"priceCents"`
|
||||
PriceNote string `v:"length:0,64#价格备注最多 64 字" json:"priceNote"`
|
||||
CoverPath string `json:"coverPath"`
|
||||
Sort int `json:"sort"`
|
||||
IsEnabled int `json:"isEnabled"`
|
||||
}
|
||||
type AdminGoodsSaveRes struct {
|
||||
Id int64 `json:"id"`
|
||||
}
|
||||
|
||||
// AdminGoodsDeleteReq 删除服务(软删除)
|
||||
type AdminGoodsDeleteReq struct {
|
||||
g.Meta `path:"/admin/goods/delete" method:"post" tags:"admin" summary:"删除软件开发服务"`
|
||||
Id int64 `v:"required" json:"id"`
|
||||
}
|
||||
type AdminGoodsDeleteRes struct{}
|
||||
341
api/admin/v1/project.go
Normal file
341
api/admin/v1/project.go
Normal file
@@ -0,0 +1,341 @@
|
||||
package v1
|
||||
|
||||
import "github.com/gogf/gf/v2/frame/g"
|
||||
|
||||
// ============================================================================
|
||||
// 管理端开发项目契约(迭代-2026-09-30 三期)
|
||||
//
|
||||
// 建单 → 生成绑定小程序码(scene 携带 bind_token)→ 用户扫码绑定;
|
||||
// 阶段/小节点/交付物(原型、UI 设计稿)均为即时保存接口(管理端逐项操作)。
|
||||
// 阶段状态变更 / 交付物上传 / 交付 会向绑定用户推站内信。
|
||||
// ============================================================================
|
||||
|
||||
// AdminProjectPayItem 项目分期
|
||||
type AdminProjectPayItem struct {
|
||||
Id int64 `json:"id"`
|
||||
Seq int `json:"seq"`
|
||||
Percent int `json:"percent"`
|
||||
AmountCents int64 `json:"amount_cents"`
|
||||
Trigger string `json:"trigger"`
|
||||
TriggerText string `json:"trigger_text"`
|
||||
Status int `json:"status"`
|
||||
PaidAt string `json:"paid_at"`
|
||||
PaidNote string `json:"paid_note"`
|
||||
}
|
||||
|
||||
// AdminProjectItem 项目列表项
|
||||
type AdminProjectItem struct {
|
||||
Id int64 `json:"id"`
|
||||
UserId int64 `json:"user_id"`
|
||||
UserNickname string `json:"user_nickname"`
|
||||
Title string `json:"title"`
|
||||
Description string `json:"description"`
|
||||
PriceCents int64 `json:"price_cents"`
|
||||
PriceNote string `json:"price_note"`
|
||||
DueNote string `json:"due_note"`
|
||||
Status int `json:"status"`
|
||||
StatusText string `json:"status_text"`
|
||||
StageTotal int `json:"stage_total"`
|
||||
StageDone int `json:"stage_done"`
|
||||
BindToken string `json:"bind_token"`
|
||||
CodeUrl string `json:"code_url"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
UpdatedAt string `json:"updated_at"`
|
||||
Stages []AdminProjectStageItem `json:"stages"`
|
||||
|
||||
MaintainPlanId int64 `json:"maintain_plan_id"`
|
||||
PayPlanId int64 `json:"pay_plan_id"`
|
||||
MaintainPlanName string `json:"maintain_plan_name"`
|
||||
PayPlanName string `json:"pay_plan_name"`
|
||||
Accepted int `json:"accepted"`
|
||||
AcceptedAt string `json:"accepted_at"`
|
||||
MaintainStartAt string `json:"maintain_start_at"`
|
||||
MaintainPaidUntil string `json:"maintain_paid_until"`
|
||||
MaintainDaysLeft int `json:"maintain_days_left"` // 距下次缴费天数(未启用维护为 -1)
|
||||
Pays []AdminProjectPayItem `json:"pays"`
|
||||
}
|
||||
|
||||
// AdminProjectListReq 项目列表
|
||||
type AdminProjectListReq struct {
|
||||
g.Meta `path:"/admin/service/project/list" method:"get" tags:"admin" summary:"开发项目列表"`
|
||||
Keyword string `json:"keyword"`
|
||||
Status *int `json:"status"`
|
||||
Page int `json:"page"`
|
||||
PageSize int `json:"pageSize"`
|
||||
}
|
||||
type AdminProjectListRes struct {
|
||||
List []AdminProjectItem `json:"list"`
|
||||
Total int `json:"total"`
|
||||
}
|
||||
|
||||
// AdminProjectSaveReq 新增/编辑项目(id=0 新建并生成绑定令牌;userId>0 直接绑定)
|
||||
type AdminProjectSaveReq struct {
|
||||
g.Meta `path:"/admin/service/project/save" method:"post" tags:"admin" summary:"保存开发项目"`
|
||||
Id int64 `json:"id"`
|
||||
Title string `v:"required#请填写项目名称" json:"title"`
|
||||
Description string `v:"length:0,1000#需求描述最多 1000 字" json:"description"`
|
||||
PriceCents int64 `v:"min:0#金额不能为负" json:"priceCents"`
|
||||
PriceNote string `v:"length:0,64#金额备注最多 64 字" json:"priceNote"`
|
||||
DueNote string `v:"length:0,64#交付周期最多 64 字" json:"dueNote"`
|
||||
Status int `v:"in:1,2,3#状态不合法" json:"status"`
|
||||
UserId int64 `json:"userId"` // 编辑时可直接改绑(填 0 = 解绑待扫码)
|
||||
MaintainPlanId int64 `json:"maintainPlanId"` // 维护模板(0=未选)
|
||||
PayPlanId int64 `json:"payPlanId"` // 付款分期模板(0=未选)
|
||||
}
|
||||
type AdminProjectSaveRes struct {
|
||||
Id int64 `json:"id"`
|
||||
BindToken string `json:"bind_token"` // 新建时返回,供前端直接弹码
|
||||
}
|
||||
|
||||
// AdminProjectDeleteReq 删除项目(软删除;阶段/节点/交付物一并硬删)
|
||||
type AdminProjectDeleteReq struct {
|
||||
g.Meta `path:"/admin/service/project/delete" method:"post" tags:"admin" summary:"删除开发项目"`
|
||||
Id int64 `v:"required" json:"id"`
|
||||
}
|
||||
type AdminProjectDeleteRes struct{}
|
||||
|
||||
// AdminProjectStageItem 阶段(含节点与文件,管理端详情用)
|
||||
type AdminProjectStageItem struct {
|
||||
Id int64 `json:"id"`
|
||||
Title string `json:"title"`
|
||||
Status int `json:"status"`
|
||||
StatusText string `json:"status_text"`
|
||||
Sort int `json:"sort"`
|
||||
IsEnabled int `json:"is_enabled"`
|
||||
Nodes []AdminProjectNodeItem `json:"nodes"`
|
||||
Files []AdminProjectFileItem `json:"files"`
|
||||
}
|
||||
|
||||
// AdminProjectNodeItem 小节点
|
||||
type AdminProjectNodeItem struct {
|
||||
Id int64 `json:"id"`
|
||||
Title string `json:"title"`
|
||||
IsDone int `json:"is_done"`
|
||||
Sort int `json:"sort"`
|
||||
}
|
||||
|
||||
// AdminProjectFileItem 交付物(绝对 URL 直显)
|
||||
type AdminProjectFileItem struct {
|
||||
Id int64 `json:"id"`
|
||||
FileName string `json:"file_name"`
|
||||
FileUrl string `json:"file_url"`
|
||||
}
|
||||
|
||||
// AdminProjectDetailReq 项目详情(管理态全量:阶段/节点/文件)
|
||||
type AdminProjectDetailReq struct {
|
||||
g.Meta `path:"/admin/service/project/detail" method:"get" tags:"admin" summary:"开发项目详情"`
|
||||
Id int64 `v:"required" json:"id"`
|
||||
}
|
||||
type AdminProjectDetailRes struct {
|
||||
AdminProjectItem
|
||||
}
|
||||
|
||||
// AdminProjectQrcodeReq 生成/重取绑定小程序码(微信 getUnlimited,scene=项目+令牌)
|
||||
type AdminProjectQrcodeReq struct {
|
||||
g.Meta `path:"/admin/service/project/qrcode" method:"post" tags:"admin" summary:"生成项目绑定小程序码"`
|
||||
Id int64 `v:"required" json:"id"`
|
||||
}
|
||||
type AdminProjectQrcodeRes struct {
|
||||
CodeUrl string `json:"code_url"`
|
||||
}
|
||||
|
||||
// AdminProjectStageSaveReq 新增/编辑阶段
|
||||
type AdminProjectStageSaveReq struct {
|
||||
g.Meta `path:"/admin/service/project/stage/save" method:"post" tags:"admin" summary:"保存项目阶段"`
|
||||
Id int64 `json:"id"`
|
||||
ProjectId int64 `v:"required" json:"projectId"`
|
||||
Title string `v:"required#请填写阶段名称" json:"title"`
|
||||
Status int `v:"in:0,1,2#状态不合法" json:"status"`
|
||||
Sort int `json:"sort"`
|
||||
IsEnabled int `json:"isEnabled"`
|
||||
}
|
||||
type AdminProjectStageSaveRes struct {
|
||||
Id int64 `json:"id"`
|
||||
}
|
||||
|
||||
// AdminProjectStageDeleteReq 删除阶段(其节点与交付物一并删除)
|
||||
type AdminProjectStageDeleteReq struct {
|
||||
g.Meta `path:"/admin/service/project/stage/delete" method:"post" tags:"admin" summary:"删除项目阶段"`
|
||||
Id int64 `v:"required" json:"id"`
|
||||
}
|
||||
type AdminProjectStageDeleteRes struct{}
|
||||
|
||||
// AdminProjectNodeSaveReq 新增/编辑小节点(isDone 变更即时生效)
|
||||
type AdminProjectNodeSaveReq struct {
|
||||
g.Meta `path:"/admin/service/project/node/save" method:"post" tags:"admin" summary:"保存阶段小节点"`
|
||||
Id int64 `json:"id"`
|
||||
StageId int64 `v:"required" json:"stageId"`
|
||||
Title string `v:"required#请填写节点内容" json:"title"`
|
||||
IsDone int `json:"isDone"`
|
||||
Sort int `json:"sort"`
|
||||
}
|
||||
type AdminProjectNodeSaveRes struct {
|
||||
Id int64 `json:"id"`
|
||||
}
|
||||
|
||||
// AdminProjectNodeDeleteReq 删除小节点
|
||||
type AdminProjectNodeDeleteReq struct {
|
||||
g.Meta `path:"/admin/service/project/node/delete" method:"post" tags:"admin" summary:"删除阶段小节点"`
|
||||
Id int64 `v:"required" json:"id"`
|
||||
}
|
||||
type AdminProjectNodeDeleteRes struct{}
|
||||
|
||||
// AdminProjectFileAddReq 登记交付物(文件本体先经 /admin/upload 上传,此处只落 path)
|
||||
type AdminProjectFileAddReq struct {
|
||||
g.Meta `path:"/admin/service/project/file/add" method:"post" tags:"admin" summary:"登记项目交付物"`
|
||||
ProjectId int64 `v:"required" json:"projectId"`
|
||||
StageId int64 `json:"stageId"`
|
||||
FileName string `v:"required#请填写文件名" json:"fileName"`
|
||||
FilePath string `v:"required#缺少文件路径" json:"filePath"`
|
||||
}
|
||||
type AdminProjectFileAddRes struct {
|
||||
Id int64 `json:"id"`
|
||||
}
|
||||
|
||||
// AdminProjectFileDeleteReq 删除交付物登记
|
||||
type AdminProjectFileDeleteReq struct {
|
||||
g.Meta `path:"/admin/service/project/file/delete" method:"post" tags:"admin" summary:"删除项目交付物"`
|
||||
Id int64 `v:"required" json:"id"`
|
||||
}
|
||||
type AdminProjectFileDeleteRes struct{}
|
||||
|
||||
// ---------- 维护模板 ----------
|
||||
|
||||
// AdminMaintainPlanItem 维护模板
|
||||
type AdminMaintainPlanItem struct {
|
||||
Id int64 `json:"id"`
|
||||
Name string `json:"name"`
|
||||
FreeYears int `json:"free_years"`
|
||||
YearlyFeeCents int64 `json:"yearly_fee_cents"`
|
||||
SourceOnly int `json:"source_only"`
|
||||
Sort int `json:"sort"`
|
||||
IsEnabled int `json:"is_enabled"`
|
||||
Remark string `json:"remark"`
|
||||
}
|
||||
|
||||
// AdminMaintainPlanListReq 维护模板列表
|
||||
type AdminMaintainPlanListReq struct {
|
||||
g.Meta `path:"/admin/service/maintain-plan/list" method:"get" tags:"admin" summary:"维护模板列表"`
|
||||
}
|
||||
type AdminMaintainPlanListRes struct {
|
||||
List []AdminMaintainPlanItem `json:"list"`
|
||||
}
|
||||
|
||||
// AdminMaintainPlanSaveReq 保存维护模板
|
||||
type AdminMaintainPlanSaveReq struct {
|
||||
g.Meta `path:"/admin/service/maintain-plan/save" method:"post" tags:"admin" summary:"保存维护模板"`
|
||||
Id int64 `json:"id"`
|
||||
Name string `v:"required#请填写模板名称" json:"name"`
|
||||
FreeYears int `v:"min:0" json:"freeYears"`
|
||||
YearlyFeeCents int64 `v:"min:0" json:"yearlyFeeCents"`
|
||||
SourceOnly int `json:"sourceOnly"`
|
||||
Sort int `json:"sort"`
|
||||
IsEnabled int `json:"isEnabled"`
|
||||
Remark string `v:"length:0,255" json:"remark"`
|
||||
}
|
||||
type AdminMaintainPlanSaveRes struct {
|
||||
Id int64 `json:"id"`
|
||||
}
|
||||
|
||||
// AdminMaintainPlanDeleteReq 删除维护模板
|
||||
type AdminMaintainPlanDeleteReq struct {
|
||||
g.Meta `path:"/admin/service/maintain-plan/delete" method:"post" tags:"admin" summary:"删除维护模板"`
|
||||
Id int64 `v:"required" json:"id"`
|
||||
}
|
||||
type AdminMaintainPlanDeleteRes struct{}
|
||||
|
||||
// ---------- 付款分期模板 ----------
|
||||
|
||||
// AdminPayPlanItem 付款分期模板
|
||||
type AdminPayPlanItem struct {
|
||||
Id int64 `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Schedule string `json:"schedule"` // JSON:[{seq,percent,trigger}]
|
||||
Sort int `json:"sort"`
|
||||
IsEnabled int `json:"is_enabled"`
|
||||
Remark string `json:"remark"`
|
||||
}
|
||||
|
||||
// AdminPayPlanListReq 分期模板列表
|
||||
type AdminPayPlanListReq struct {
|
||||
g.Meta `path:"/admin/service/pay-plan/list" method:"get" tags:"admin" summary:"付款分期模板列表"`
|
||||
}
|
||||
type AdminPayPlanListRes struct {
|
||||
List []AdminPayPlanItem `json:"list"`
|
||||
}
|
||||
|
||||
// AdminPayPlanSaveReq 保存分期模板
|
||||
type AdminPayPlanSaveReq struct {
|
||||
g.Meta `path:"/admin/service/pay-plan/save" method:"post" tags:"admin" summary:"保存付款分期模板"`
|
||||
Id int64 `json:"id"`
|
||||
Name string `v:"required#请填写模板名称" json:"name"`
|
||||
Schedule string `v:"required#请填写分期计划 JSON" json:"schedule"`
|
||||
Sort int `json:"sort"`
|
||||
IsEnabled int `json:"isEnabled"`
|
||||
Remark string `v:"length:0,255" json:"remark"`
|
||||
}
|
||||
type AdminPayPlanSaveRes struct {
|
||||
Id int64 `json:"id"`
|
||||
}
|
||||
|
||||
// AdminPayPlanDeleteReq 删除分期模板
|
||||
type AdminPayPlanDeleteReq struct {
|
||||
g.Meta `path:"/admin/service/pay-plan/delete" method:"post" tags:"admin" summary:"删除付款分期模板"`
|
||||
Id int64 `v:"required" json:"id"`
|
||||
}
|
||||
type AdminPayPlanDeleteRes struct{}
|
||||
|
||||
// ---------- 分期到账 / 维护期 ----------
|
||||
|
||||
// AdminProjectPayMarkReq 标记分期到账(后台确认收款,用户端推站内信)
|
||||
type AdminProjectPayMarkReq struct {
|
||||
g.Meta `path:"/admin/service/project/pay/mark" method:"post" tags:"admin" summary:"标记分期到账"`
|
||||
Id int64 `v:"required" json:"id"`
|
||||
PaidNote string `v:"length:0,64#备注最多 64 字" json:"paidNote"`
|
||||
}
|
||||
type AdminProjectPayMarkRes struct{}
|
||||
|
||||
// AdminProjectPayUnmarkReq 撤销分期到账(误操作回退)
|
||||
type AdminProjectPayUnmarkReq struct {
|
||||
g.Meta `path:"/admin/service/project/pay/unmark" method:"post" tags:"admin" summary:"撤销分期到账"`
|
||||
Id int64 `v:"required" json:"id"`
|
||||
}
|
||||
type AdminProjectPayUnmarkRes struct{}
|
||||
|
||||
// AdminProjectMaintainRenewReq 维护费 +1 年已收(paid_until 顺延一年并通知用户)
|
||||
type AdminProjectMaintainRenewReq struct {
|
||||
g.Meta `path:"/admin/service/project/maintain/renew" method:"post" tags:"admin" summary:"维护费续收一年"`
|
||||
Id int64 `v:"required" json:"id"`
|
||||
}
|
||||
type AdminProjectMaintainRenewRes struct {
|
||||
PaidUntil string `json:"paid_until"`
|
||||
}
|
||||
|
||||
// AdminProjectMaintainAdjustReq 调整维护期起算日(重算已缴至与到期提醒)
|
||||
type AdminProjectMaintainAdjustReq struct {
|
||||
g.Meta `path:"/admin/service/project/maintain/adjust" method:"post" tags:"admin" summary:"调整维护期起算日"`
|
||||
Id int64 `v:"required" json:"id"`
|
||||
StartAt string `v:"required#请选择起算日期" json:"startAt"` // YYYY-MM-DD
|
||||
}
|
||||
type AdminProjectMaintainAdjustRes struct {
|
||||
PaidUntil string `json:"paid_until"`
|
||||
}
|
||||
|
||||
// ---------- 缴费提醒设置 ----------
|
||||
|
||||
// AdminMaintainRemindGetReq 提醒设置读取
|
||||
type AdminMaintainRemindGetReq struct {
|
||||
g.Meta `path:"/admin/service/maintain-remind/get" method:"get" tags:"admin" summary:"维护费提醒设置读取"`
|
||||
}
|
||||
type AdminMaintainRemindGetRes struct {
|
||||
RemindDays int `json:"remind_days"`
|
||||
AdminNotifyUserId int64 `json:"admin_notify_user_id"`
|
||||
}
|
||||
|
||||
// AdminMaintainRemindSaveReq 提醒设置保存
|
||||
type AdminMaintainRemindSaveReq struct {
|
||||
g.Meta `path:"/admin/service/maintain-remind/save" method:"post" tags:"admin" summary:"维护费提醒设置保存"`
|
||||
RemindDays int `v:"min:1|max:90#提醒天数需在 1-90 之间" json:"remindDays"`
|
||||
AdminNotifyUserId int64 `json:"adminNotifyUserId"`
|
||||
}
|
||||
type AdminMaintainRemindSaveRes struct{}
|
||||
181
api/admin/v1/service.go
Normal file
181
api/admin/v1/service.go
Normal file
@@ -0,0 +1,181 @@
|
||||
package v1
|
||||
|
||||
import "github.com/gogf/gf/v2/frame/g"
|
||||
|
||||
// ============================================================================
|
||||
// 管理端软件开发服务二期契约(迭代-2026-09-30):
|
||||
// 介绍页模块(blocks)/ 作品案例(works)/ 报价申请(quotes)
|
||||
//
|
||||
// 图片字段库内只存相对路径(/static/...),响应里 *Url 为按 site.base_url 拼接的
|
||||
// 绝对地址;保存时提交上传接口返回的 path。报价处理(handle)后向用户推站内信。
|
||||
// ============================================================================
|
||||
|
||||
// ---------- 介绍页模块 ----------
|
||||
|
||||
// AdminServiceBlockItem 模块项(响应 snake_case)
|
||||
type AdminServiceBlockItem struct {
|
||||
Id int64 `json:"id"`
|
||||
Kind string `json:"kind"`
|
||||
Title string `json:"title"`
|
||||
Subtitle string `json:"subtitle"`
|
||||
ImagePath string `json:"image_path"`
|
||||
ImageUrl string `json:"image_url"`
|
||||
Images []string `json:"images"` // 相对路径数组(编辑回填用)
|
||||
ImageUrls []string `json:"image_urls"`
|
||||
Content string `json:"content"`
|
||||
Sort int `json:"sort"`
|
||||
IsEnabled int `json:"is_enabled"`
|
||||
UpdatedAt string `json:"updated_at"`
|
||||
}
|
||||
|
||||
// AdminServiceBlockListReq 模块列表(含停用;管理端全部可见)
|
||||
type AdminServiceBlockListReq struct {
|
||||
g.Meta `path:"/admin/service/block/list" method:"get" tags:"admin" summary:"服务介绍页模块列表"`
|
||||
}
|
||||
type AdminServiceBlockListRes struct {
|
||||
List []AdminServiceBlockItem `json:"list"`
|
||||
}
|
||||
|
||||
// AdminServiceBlockSaveReq 新增/编辑模块(id=0 新建)。images 传相对路径数组。
|
||||
type AdminServiceBlockSaveReq struct {
|
||||
g.Meta `path:"/admin/service/block/save" method:"post" tags:"admin" summary:"保存服务介绍页模块"`
|
||||
Id int64 `json:"id"`
|
||||
Kind string `v:"required|in:hero,rich,image_text,image_list,flow,checklist,price,developer,works,goods#请选择模块类型|模块类型不合法" json:"kind"`
|
||||
Title string `v:"length:0,128#标题最多 128 字" json:"title"`
|
||||
Subtitle string `v:"length:0,255#副标题最多 255 字" json:"subtitle"`
|
||||
ImagePath string `json:"imagePath"`
|
||||
Images []string `json:"images"`
|
||||
Content string `json:"content"`
|
||||
Sort int `json:"sort"`
|
||||
IsEnabled int `json:"isEnabled"`
|
||||
}
|
||||
type AdminServiceBlockSaveRes struct {
|
||||
Id int64 `json:"id"`
|
||||
}
|
||||
|
||||
// AdminServiceBlockDeleteReq 删除模块
|
||||
type AdminServiceBlockDeleteReq struct {
|
||||
g.Meta `path:"/admin/service/block/delete" method:"post" tags:"admin" summary:"删除服务介绍页模块"`
|
||||
Id int64 `v:"required" json:"id"`
|
||||
}
|
||||
type AdminServiceBlockDeleteRes struct{}
|
||||
|
||||
// ---------- 作品案例 ----------
|
||||
|
||||
// AdminServiceWorkItem 作品列表项(不含 content_md)
|
||||
type AdminServiceWorkItem struct {
|
||||
Id int64 `json:"id"`
|
||||
Category int `json:"category"`
|
||||
CategoryName string `json:"category_name"`
|
||||
Title string `json:"title"`
|
||||
Summary string `json:"summary"`
|
||||
CoverPath string `json:"cover_path"`
|
||||
CoverUrl string `json:"cover_url"`
|
||||
PriceCents int64 `json:"price_cents"`
|
||||
PriceNote string `json:"price_note"`
|
||||
Sort int `json:"sort"`
|
||||
IsEnabled int `json:"is_enabled"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
}
|
||||
|
||||
// AdminServiceWorkListReq 作品列表
|
||||
type AdminServiceWorkListReq struct {
|
||||
g.Meta `path:"/admin/service/work/list" method:"get" tags:"admin" summary:"软件开发作品列表"`
|
||||
Keyword string `json:"keyword"`
|
||||
Category int `json:"category"`
|
||||
IsEnabled *int `json:"isEnabled"`
|
||||
Page int `json:"page"`
|
||||
PageSize int `json:"pageSize"`
|
||||
}
|
||||
type AdminServiceWorkListRes struct {
|
||||
List []AdminServiceWorkItem `json:"list"`
|
||||
Total int `json:"total"`
|
||||
}
|
||||
|
||||
// AdminServiceWorkDetailReq 作品详情(编辑回填)
|
||||
type AdminServiceWorkDetailReq struct {
|
||||
g.Meta `path:"/admin/service/work/detail" method:"get" tags:"admin" summary:"软件开发作品详情"`
|
||||
Id int64 `v:"required" json:"id"`
|
||||
}
|
||||
type AdminServiceWorkDetailRes struct {
|
||||
Id int64 `json:"id"`
|
||||
Category int `json:"category"`
|
||||
Title string `json:"title"`
|
||||
Summary string `json:"summary"`
|
||||
ContentMd string `json:"content_md"`
|
||||
CoverPath string `json:"cover_path"`
|
||||
CoverUrl string `json:"cover_url"`
|
||||
Images []string `json:"images"`
|
||||
PriceCents int64 `json:"price_cents"`
|
||||
PriceNote string `json:"price_note"`
|
||||
Sort int `json:"sort"`
|
||||
IsEnabled int `json:"is_enabled"`
|
||||
}
|
||||
|
||||
// AdminServiceWorkSaveReq 新增/编辑作品
|
||||
type AdminServiceWorkSaveReq struct {
|
||||
g.Meta `path:"/admin/service/work/save" method:"post" tags:"admin" summary:"保存软件开发作品"`
|
||||
Id int64 `json:"id"`
|
||||
Category int `v:"required|in:1,2,3,4#请选择分类|分类不合法" json:"category"`
|
||||
Title string `v:"required#请填写作品名称" json:"title"`
|
||||
Summary string `v:"length:0,500#简介最多 500 字" json:"summary"`
|
||||
ContentMd string `json:"contentMd"`
|
||||
CoverPath string `json:"coverPath"`
|
||||
Images []string `json:"images"`
|
||||
PriceCents int64 `v:"min:0#价格不能为负" json:"priceCents"`
|
||||
PriceNote string `v:"length:0,64#价格备注最多 64 字" json:"priceNote"`
|
||||
Sort int `json:"sort"`
|
||||
IsEnabled int `json:"isEnabled"`
|
||||
}
|
||||
type AdminServiceWorkSaveRes struct {
|
||||
Id int64 `json:"id"`
|
||||
}
|
||||
|
||||
// AdminServiceWorkDeleteReq 删除作品(软删除)
|
||||
type AdminServiceWorkDeleteReq struct {
|
||||
g.Meta `path:"/admin/service/work/delete" method:"post" tags:"admin" summary:"删除软件开发作品"`
|
||||
Id int64 `v:"required" json:"id"`
|
||||
}
|
||||
type AdminServiceWorkDeleteRes struct{}
|
||||
|
||||
// ---------- 报价申请 ----------
|
||||
|
||||
// AdminServiceQuoteItem 报价申请列表项
|
||||
type AdminServiceQuoteItem struct {
|
||||
Id int64 `json:"id"`
|
||||
UserId int64 `json:"user_id"`
|
||||
UserNickname string `json:"user_nickname"`
|
||||
WorkId int64 `json:"work_id"`
|
||||
WorkTitle string `json:"work_title"`
|
||||
Contact string `json:"contact"`
|
||||
Requirement string `json:"requirement"`
|
||||
Budget string `json:"budget"`
|
||||
Status int `json:"status"`
|
||||
StatusText string `json:"status_text"`
|
||||
QuoteCents int64 `json:"quote_cents"`
|
||||
QuoteNote string `json:"quote_note"`
|
||||
HandledAt string `json:"handled_at"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
}
|
||||
|
||||
// AdminServiceQuoteListReq 报价申请列表
|
||||
type AdminServiceQuoteListReq struct {
|
||||
g.Meta `path:"/admin/service/quote/list" method:"get" tags:"admin" summary:"报价申请列表"`
|
||||
Status *int `json:"status"` // nil=全部
|
||||
Page int `json:"page"`
|
||||
PageSize int `json:"pageSize"`
|
||||
}
|
||||
type AdminServiceQuoteListRes struct {
|
||||
List []AdminServiceQuoteItem `json:"list"`
|
||||
Total int `json:"total"`
|
||||
}
|
||||
|
||||
// AdminServiceQuoteHandleReq 处理报价申请(填报价 + 状态),用户端推站内信
|
||||
type AdminServiceQuoteHandleReq struct {
|
||||
g.Meta `path:"/admin/service/quote/handle" method:"post" tags:"admin" summary:"处理报价申请"`
|
||||
Id int64 `v:"required" json:"id"`
|
||||
Status int `v:"in:0,1,2,3#状态不合法" json:"status"`
|
||||
QuoteCents int64 `v:"min:0#报价不能为负" json:"quoteCents"`
|
||||
QuoteNote string `v:"length:0,500#报价说明最多 500 字" json:"quoteNote"`
|
||||
}
|
||||
type AdminServiceQuoteHandleRes struct{}
|
||||
33
api/admin/v1/setting.go
Normal file
33
api/admin/v1/setting.go
Normal file
@@ -0,0 +1,33 @@
|
||||
package v1
|
||||
|
||||
import "github.com/gogf/gf/v2/frame/g"
|
||||
|
||||
// ============================================================================
|
||||
// 管理端系统配置契约(迭代-2026-09-29)
|
||||
//
|
||||
// 走 settings 表(约定 S9:配置一律走 settings 表,不写 config.yaml);本模块
|
||||
// 只开放白名单键,当前是 site.base_url(图片等静态资源的对外拼接前缀)。
|
||||
// ============================================================================
|
||||
|
||||
// AdminSettingItem 配置项
|
||||
type AdminSettingItem struct {
|
||||
Key string `json:"key"`
|
||||
Value string `json:"value"`
|
||||
Remark string `json:"remark"`
|
||||
}
|
||||
|
||||
// AdminSettingGetReq 读取白名单配置项
|
||||
type AdminSettingGetReq struct {
|
||||
g.Meta `path:"/admin/setting/get" method:"get" tags:"admin" summary:"系统配置读取"`
|
||||
}
|
||||
type AdminSettingGetRes struct {
|
||||
Items []AdminSettingItem `json:"items"`
|
||||
}
|
||||
|
||||
// AdminSettingSaveReq 保存一项配置(key 必须在白名单内)
|
||||
type AdminSettingSaveReq struct {
|
||||
g.Meta `path:"/admin/setting/save" method:"post" tags:"admin" summary:"系统配置保存"`
|
||||
Key string `v:"required" json:"key"`
|
||||
Value string `v:"length:0,255#配置值最多 255 字" json:"value"`
|
||||
}
|
||||
type AdminSettingSaveRes struct{}
|
||||
19
api/user/v1/app_config.go
Normal file
19
api/user/v1/app_config.go
Normal file
@@ -0,0 +1,19 @@
|
||||
package v1
|
||||
|
||||
import "github.com/gogf/gf/v2/frame/g"
|
||||
|
||||
// ============================================================================
|
||||
// C 端应用配置契约(迭代-2026-09-30)
|
||||
//
|
||||
// 首页等界面级配置的轻量下发口。值来自 settings 表,key 对齐小程序端
|
||||
// `config/features.ts` 的 FEATURE_ENTRIES key;未配置的 key 不出现在 map 中。
|
||||
// ============================================================================
|
||||
|
||||
// AppConfigReq 应用配置(首页功能卡背景图等)
|
||||
type AppConfigReq struct {
|
||||
g.Meta `path:"/app/config" method:"get" tags:"app" summary:"应用配置"`
|
||||
}
|
||||
type AppConfigRes struct {
|
||||
// FeatureCovers 首页便捷功能卡背景图:featureKey → 绝对 URL(后端按 site.base_url 拼好)
|
||||
FeatureCovers map[string]string `json:"feature_covers"`
|
||||
}
|
||||
52
api/user/v1/goods.go
Normal file
52
api/user/v1/goods.go
Normal file
@@ -0,0 +1,52 @@
|
||||
package v1
|
||||
|
||||
import "github.com/gogf/gf/v2/frame/g"
|
||||
|
||||
// ============================================================================
|
||||
// C 端软件开发服务契约(迭代-2026-09-29):list / detail
|
||||
//
|
||||
// 仅上架(is_enabled=1)商品可见;封面 url 由后端按 site.base_url 拼成绝对地址,
|
||||
// 小程序端拿到即可直接用于 <image>,无需自行拼接域名。
|
||||
// ============================================================================
|
||||
|
||||
// GoodsItem 服务列表项(响应 snake_case)
|
||||
type GoodsItem struct {
|
||||
Id int64 `json:"id"`
|
||||
Category int `json:"category"` // 1网站 2小程序 3App 4桌面
|
||||
CategoryName string `json:"category_name"` // 分类展示名(服务端映射)
|
||||
Title string `json:"title"`
|
||||
Summary string `json:"summary"`
|
||||
CoverUrl string `json:"cover_url"` // 封面绝对 URL(可能为空 = 无封面)
|
||||
PriceCents int64 `json:"price_cents"` // 0 = 面议
|
||||
PriceNote string `json:"price_note"` // 价格备注(如「起」「/项目」)
|
||||
}
|
||||
|
||||
// GoodsListReq 服务列表(C 端,仅上架)
|
||||
type GoodsListReq struct {
|
||||
g.Meta `path:"/goods/list" method:"get" tags:"goods" summary:"软件开发服务列表"`
|
||||
Category int `json:"category"` // 0=全部
|
||||
Page int `json:"page"`
|
||||
PageSize int `json:"pageSize"`
|
||||
}
|
||||
type GoodsListRes struct {
|
||||
List []GoodsItem `json:"list"`
|
||||
Total int `json:"total"`
|
||||
}
|
||||
|
||||
// GoodsDetailReq 服务详情(C 端,仅上架;含 Markdown 原文,由前端解析渲染)
|
||||
type GoodsDetailReq struct {
|
||||
g.Meta `path:"/goods/detail" method:"get" tags:"goods" summary:"软件开发服务详情"`
|
||||
Id int64 `v:"required" json:"id"`
|
||||
}
|
||||
type GoodsDetailRes struct {
|
||||
Id int64 `json:"id"`
|
||||
Category int `json:"category"`
|
||||
CategoryName string `json:"category_name"`
|
||||
Title string `json:"title"`
|
||||
Summary string `json:"summary"`
|
||||
ContentMd string `json:"content_md"`
|
||||
CoverUrl string `json:"cover_url"`
|
||||
PriceCents int64 `json:"price_cents"`
|
||||
PriceNote string `json:"price_note"`
|
||||
UpdatedAt string `json:"updated_at"`
|
||||
}
|
||||
@@ -93,6 +93,7 @@ type MemberOrderCheckRes struct {
|
||||
type MemberOrdersReq struct {
|
||||
g.Meta `path:"/member/orders" method:"get" tags:"member" summary:"我的会员订单"`
|
||||
Limit int `json:"limit"`
|
||||
Tab int `json:"tab"` // 0全部 1待付款 2已生效 3退款
|
||||
}
|
||||
type MemberOrderOut struct {
|
||||
OutTradeNo string `json:"out_trade_no"`
|
||||
|
||||
47
api/user/v1/message.go
Normal file
47
api/user/v1/message.go
Normal file
@@ -0,0 +1,47 @@
|
||||
package v1
|
||||
|
||||
import "github.com/gogf/gf/v2/frame/g"
|
||||
|
||||
// ============================================================================
|
||||
// C 端站内信契约(迭代-2026-09-30)
|
||||
//
|
||||
// 写入点(后端业务事件统一落 user_messages,见 logic/message.go PushMessage):
|
||||
// 会员开通/次数包到账(发货成功)、报价申请回执、报价处理结果、反馈官方回复。
|
||||
// C 端只读:列表 / 未读数 / 标记已读(单条或全部)。
|
||||
// ============================================================================
|
||||
|
||||
// MessageItem 站内信条目
|
||||
type MessageItem struct {
|
||||
Id int64 `json:"id"`
|
||||
Type string `json:"type"` // order_delivered/quote_submitted/quote_handled/feedback_replied/system
|
||||
Title string `json:"title"`
|
||||
Content string `json:"content"`
|
||||
Link string `json:"link"` // 小程序内跳转路由,空=不跳转
|
||||
IsRead int `json:"is_read"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
}
|
||||
|
||||
// MessageListReq 我的消息(最近 N 条 + 未读数;不自动置已读,已读走 /message/read)
|
||||
type MessageListReq struct {
|
||||
g.Meta `path:"/message/list" method:"get" tags:"message" summary:"我的站内信"`
|
||||
Limit int `json:"limit"`
|
||||
}
|
||||
type MessageListRes struct {
|
||||
List []MessageItem `json:"list"`
|
||||
Unread int `json:"unread"`
|
||||
}
|
||||
|
||||
// MessageUnreadReq 未读消息数(首页 / 我的页徽标)
|
||||
type MessageUnreadReq struct {
|
||||
g.Meta `path:"/message/unread" method:"get" tags:"message" summary:"未读站内信数"`
|
||||
}
|
||||
type MessageUnreadRes struct {
|
||||
Count int `json:"count"`
|
||||
}
|
||||
|
||||
// MessageReadReq 标记已读:Id>0 单条;Id=0 全部
|
||||
type MessageReadReq struct {
|
||||
g.Meta `path:"/message/read" method:"post" tags:"message" summary:"站内信标记已读"`
|
||||
Id int64 `json:"id"`
|
||||
}
|
||||
type MessageReadRes struct{}
|
||||
115
api/user/v1/project.go
Normal file
115
api/user/v1/project.go
Normal file
@@ -0,0 +1,115 @@
|
||||
package v1
|
||||
|
||||
import "github.com/gogf/gf/v2/frame/g"
|
||||
|
||||
// ============================================================================
|
||||
// C 端开发项目契约(迭代-2026-09-30 三期)
|
||||
//
|
||||
// 流程:后台建单(生成绑定令牌)→ 用户扫小程序码进入绑定页 → POST bind 绑定到
|
||||
// 当前用户 → 后台维护阶段/小节点/交付物(原型、UI 设计稿等)→ 用户端只读查看。
|
||||
// ============================================================================
|
||||
|
||||
// ProjectStageItem 项目阶段(含小节点与交付物)
|
||||
type ProjectStageItem struct {
|
||||
Id int64 `json:"id"`
|
||||
Title string `json:"title"`
|
||||
Status int `json:"status"` // 0未开始 1进行中 2已完成
|
||||
StatusText string `json:"status_text"`
|
||||
Nodes []ProjectNodeItem `json:"nodes"`
|
||||
Files []ProjectFileItem `json:"files"`
|
||||
}
|
||||
|
||||
// ProjectNodeItem 阶段小节点
|
||||
type ProjectNodeItem struct {
|
||||
Id int64 `json:"id"`
|
||||
Title string `json:"title"`
|
||||
IsDone int `json:"is_done"`
|
||||
DoneAt string `json:"done_at"`
|
||||
}
|
||||
|
||||
// ProjectFileItem 阶段交付物(图片,绝对 URL)
|
||||
type ProjectFileItem struct {
|
||||
Id int64 `json:"id"`
|
||||
FileName string `json:"file_name"`
|
||||
FileUrl string `json:"file_url"`
|
||||
}
|
||||
|
||||
// ProjectPayItem 项目分期(后台确认到账,用户只读)
|
||||
type ProjectPayItem struct {
|
||||
Id int64 `json:"id"`
|
||||
Seq int `json:"seq"`
|
||||
Percent int `json:"percent"`
|
||||
AmountCents int64 `json:"amount_cents"`
|
||||
Trigger string `json:"trigger"`
|
||||
TriggerText string `json:"trigger_text"`
|
||||
Status int `json:"status"` // 0待支付 1已支付
|
||||
PaidAt string `json:"paid_at"`
|
||||
}
|
||||
|
||||
// ProjectMaintainOut 维护期信息
|
||||
type ProjectMaintainOut struct {
|
||||
PlanName string `json:"plan_name"`
|
||||
FreeYears int `json:"free_years"`
|
||||
YearlyFeeCents int64 `json:"yearly_fee_cents"`
|
||||
SourceOnly int `json:"source_only"` // 1=仅源码无售后
|
||||
Accepted int `json:"accepted"`
|
||||
AcceptedAt string `json:"accepted_at"`
|
||||
StartAt string `json:"start_at"` // 维护期起算日(后台可调)
|
||||
PaidUntil string `json:"paid_until"` // 维护费已缴至(= 下次缴费日)
|
||||
}
|
||||
|
||||
// ProjectItem 项目列表项
|
||||
type ProjectItem struct {
|
||||
Id int64 `json:"id"`
|
||||
Title string `json:"title"`
|
||||
Description string `json:"description"`
|
||||
PriceCents int64 `json:"price_cents"`
|
||||
PriceNote string `json:"price_note"`
|
||||
DueNote string `json:"due_note"`
|
||||
Status int `json:"status"`
|
||||
StatusText string `json:"status_text"`
|
||||
StageTotal int `json:"stage_total"` // 已完成阶段数(输出时算好,前端直接展示进度)
|
||||
StageDone int `json:"stage_done"`
|
||||
CoverUrl string `json:"cover_url"` // 入口图(第一个阶段交付物图片,可能为空)
|
||||
UpdatedAt string `json:"updated_at"`
|
||||
}
|
||||
|
||||
// ProjectMineReq 我的项目(扫码绑定后可见)
|
||||
type ProjectMineReq struct {
|
||||
g.Meta `path:"/service/project/mine" method:"get" tags:"service" summary:"我的开发项目"`
|
||||
}
|
||||
type ProjectMineRes struct {
|
||||
List []ProjectItem `json:"list"`
|
||||
}
|
||||
|
||||
// ProjectDetailReq 项目详情(仅限已绑定用户;含阶段/节点/交付物/分期/维护期)
|
||||
type ProjectDetailReq struct {
|
||||
g.Meta `path:"/service/project/detail" method:"get" tags:"service" summary:"开发项目详情"`
|
||||
Id int64 `v:"required" json:"id"`
|
||||
}
|
||||
type ProjectDetailRes struct {
|
||||
ProjectItem
|
||||
Stages []ProjectStageItem `json:"stages"`
|
||||
Pays []ProjectPayItem `json:"pays"` // 分期付款(进度与到账状态)
|
||||
Maintain *ProjectMaintainOut `json:"maintain"` // 维护期信息(未选模板为 null)
|
||||
CanAccept int `json:"can_accept"` // 1=可点「确认验收」(已交付且未验收)
|
||||
}
|
||||
|
||||
// ProjectAcceptReq 用户确认验收:进入维护期(维护期起点=确认当天,后台可调整)。
|
||||
type ProjectAcceptReq struct {
|
||||
g.Meta `path:"/service/project/accept" method:"post" tags:"service" summary:"确认验收进入维护期"`
|
||||
Id int64 `v:"required" json:"id"`
|
||||
}
|
||||
type ProjectAcceptRes struct {
|
||||
MaintainStartAt string `json:"maintain_start_at"`
|
||||
PaidUntil string `json:"paid_until"`
|
||||
}
|
||||
|
||||
// ProjectBindReq 扫码绑定项目(令牌来自小程序码 scene)
|
||||
type ProjectBindReq struct {
|
||||
g.Meta `path:"/service/project/bind" method:"post" tags:"service" summary:"绑定开发项目"`
|
||||
Token string `v:"required#缺少绑定令牌" json:"token"`
|
||||
}
|
||||
type ProjectBindRes struct {
|
||||
ProjectId int64 `json:"project_id"`
|
||||
}
|
||||
102
api/user/v1/service.go
Normal file
102
api/user/v1/service.go
Normal file
@@ -0,0 +1,102 @@
|
||||
package v1
|
||||
|
||||
import "github.com/gogf/gf/v2/frame/g"
|
||||
|
||||
// ============================================================================
|
||||
// C 端软件开发服务二期契约(迭代-2026-09-30):介绍页模块 / 作品案例 / 报价申请
|
||||
//
|
||||
// - 介绍页模块(service_blocks)由管理端逐块编辑(预设排版布局),C 端按 sort 输出;
|
||||
// - 图片字段库内只存相对路径,输出统一为绝对 URL(同 goods 封面约定);
|
||||
// - 报价申请提交后写站内信回执;处理结果(已报价/成交/关闭)再推站内信。
|
||||
// ============================================================================
|
||||
|
||||
// ServiceBlockOut 介绍页模块(响应 snake_case)
|
||||
type ServiceBlockOut struct {
|
||||
Id int64 `json:"id"`
|
||||
Kind string `json:"kind"` // hero/rich/image_text/image_list/developer/works/goods
|
||||
Title string `json:"title"`
|
||||
Subtitle string `json:"subtitle"`
|
||||
ImageUrl string `json:"image_url"` // 主图绝对 URL(可能为空)
|
||||
Images []string `json:"images"` // 图集绝对 URL(image_list)
|
||||
Content string `json:"content"` // Markdown 原文,前端解析渲染
|
||||
}
|
||||
|
||||
// ServicePageReq 服务介绍页模块列表(仅启用,sort 升序)
|
||||
type ServicePageReq struct {
|
||||
g.Meta `path:"/service/page" method:"get" tags:"service" summary:"软件开发服务介绍页"`
|
||||
}
|
||||
type ServicePageRes struct {
|
||||
List []ServiceBlockOut `json:"list"`
|
||||
}
|
||||
|
||||
// WorkItem 作品列表项
|
||||
type WorkItem struct {
|
||||
Id int64 `json:"id"`
|
||||
Category int `json:"category"`
|
||||
CategoryName string `json:"category_name"`
|
||||
Title string `json:"title"`
|
||||
Summary string `json:"summary"`
|
||||
CoverUrl string `json:"cover_url"`
|
||||
PriceCents int64 `json:"price_cents"` // 0 = 面议
|
||||
PriceNote string `json:"price_note"`
|
||||
}
|
||||
|
||||
// WorksListReq 作品列表(仅上架)
|
||||
type WorksListReq struct {
|
||||
g.Meta `path:"/service/works" method:"get" tags:"service" summary:"软件开发作品列表"`
|
||||
Category int `json:"category"` // 0=全部
|
||||
Page int `json:"page"`
|
||||
PageSize int `json:"pageSize"`
|
||||
}
|
||||
type WorksListRes struct {
|
||||
List []WorkItem `json:"list"`
|
||||
Total int `json:"total"`
|
||||
}
|
||||
|
||||
// WorkDetailReq 作品详情(含图集与 Markdown 详情)
|
||||
type WorkDetailReq struct {
|
||||
g.Meta `path:"/service/works/detail" method:"get" tags:"service" summary:"软件开发作品详情"`
|
||||
Id int64 `v:"required" json:"id"`
|
||||
}
|
||||
type WorkDetailRes struct {
|
||||
WorkItem
|
||||
Images []string `json:"images"` // 详情图集(绝对 URL)
|
||||
ContentMd string `json:"content_md"`
|
||||
UpdatedAt string `json:"updated_at"`
|
||||
}
|
||||
|
||||
// QuoteSubmitReq 提交报价申请(需求 → 站内信回执)
|
||||
type QuoteSubmitReq struct {
|
||||
g.Meta `path:"/service/quote/submit" method:"post" tags:"service" summary:"提交软件开发报价申请"`
|
||||
WorkId int64 `json:"work_id"` // 0 = 通用申请(不关联作品)
|
||||
Contact string `v:"required#请填写联系方式" json:"contact"`
|
||||
Requirement string `v:"required#请描述您的需求" json:"requirement"`
|
||||
Budget string `json:"budget"` // 预算范围文案,可空
|
||||
}
|
||||
type QuoteSubmitRes struct {
|
||||
Id int64 `json:"id"`
|
||||
}
|
||||
|
||||
// QuoteMineItem 我的报价申请条目(含处理结果)
|
||||
type QuoteMineItem struct {
|
||||
Id int64 `json:"id"`
|
||||
WorkId int64 `json:"work_id"`
|
||||
WorkTitle string `json:"work_title"`
|
||||
Requirement string `json:"requirement"`
|
||||
Budget string `json:"budget"`
|
||||
Status int `json:"status"`
|
||||
StatusText string `json:"status_text"`
|
||||
QuoteCents int64 `json:"quote_cents"` // 0=面议/未填
|
||||
QuoteNote string `json:"quote_note"`
|
||||
HandledAt string `json:"handled_at"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
}
|
||||
|
||||
// QuoteMineReq 我的报价申请(最近 N 条)
|
||||
type QuoteMineReq struct {
|
||||
g.Meta `path:"/service/quote/mine" method:"get" tags:"service" summary:"我的报价申请"`
|
||||
Limit int `json:"limit"`
|
||||
}
|
||||
type QuoteMineRes struct {
|
||||
List []QuoteMineItem `json:"list"`
|
||||
}
|
||||
Reference in New Issue
Block a user