前端(uni-app · Vue3)
- 设计系统:uni.scss 品牌令牌(花红 #E8604C / 蜜橙 #F5A65B / 暖米白 #FFF9F5),
App.vue 全局原子类(卡片/按钮/胶囊/单元格/空态/进度)
- 页面:登录、首页(聚合)、周期(花瓣日历+当日记录+预测+概览)、情绪(记录+趋势+日记+疗愈)、
我的(资料/会员/隐私/提醒)、健康报告、会员套餐、内容详情
- 组件:hq-tabbar(自定义底栏)、bloom-calendar(阶段日历)
- 基础层:utils/{config,request,store,api,date}.js(统一 token、401 处理、接口集中定义)
后端(FastAdmin / ThinkPHP 5.0)
- 新增 api 控制器:Home / Cycle / Mood / Content / Member / Setting,User 增补 detail、updateprofile
- 新增服务层:CycleService(四阶段计算、预测、月历、汇总)、MemberService(权益判定)
- 新增表:fa_cycle / fa_cycle_log / fa_symptom_tag / fa_mood_log / fa_content /
fa_content_category / fa_member_plan / fa_member_order / fa_user_setting
- 初始化数据:20 个症状标签、28 条内容(心语/科普/知识/食谱/运动/睡眠/痛经/冥想)、3 档会员
验证(全部通过)
- 接口全链路 48 项断言(登录→周期→首页→情绪→内容→会员→设置→资料)
- 前后端契约静态校验 24 个接口 0 偏差
- Vue SFC 编译 11/11、SCSS 编译 10/10
- 验证脚本见 scripts/verify/,报告见 docs/04-前端设计系统与联调验证.md
92 行
2.8 KiB
PHP
92 行
2.8 KiB
PHP
<?php
|
||
|
||
namespace app\api\controller;
|
||
|
||
use app\common\controller\Api;
|
||
use app\common\service\MemberService;
|
||
use fast\Random;
|
||
use think\Db;
|
||
|
||
/**
|
||
* 会员接口(M6 变现)
|
||
*/
|
||
class Member extends Api
|
||
{
|
||
protected $noNeedLogin = ['plans'];
|
||
protected $noNeedRight = '*';
|
||
|
||
/**
|
||
* 套餐列表(无需登录)
|
||
*/
|
||
public function plans()
|
||
{
|
||
$this->success('', ['list' => MemberService::plans()]);
|
||
}
|
||
|
||
/**
|
||
* 我的会员状态
|
||
*/
|
||
public function status()
|
||
{
|
||
$status = MemberService::status($this->auth->id);
|
||
$orders = Db::name('member_order')
|
||
->where('user_id', $this->auth->id)
|
||
->order('id', 'desc')
|
||
->limit(10)
|
||
->field('order_no,plan_code,amount,pay_status,createtime,start_time,expire_time')
|
||
->select();
|
||
foreach ($orders as &$order) {
|
||
$order['amount'] = (float)$order['amount'];
|
||
$order['create_date'] = $order['createtime'] ? date('Y-m-d H:i', (int)$order['createtime']) : '';
|
||
$order['status_text'] = ['unpaid' => '待支付', 'paid' => '已支付', 'refunded' => '已退款'][$order['pay_status']] ?? $order['pay_status'];
|
||
}
|
||
$this->success('', ['member' => $status, 'orders' => $orders]);
|
||
}
|
||
|
||
/**
|
||
* 创建会员订单
|
||
* POST plan_id=2 pay_type=wechat
|
||
*/
|
||
public function order()
|
||
{
|
||
$userId = $this->auth->id;
|
||
$planId = (int)$this->request->post('plan_id', 0);
|
||
$payType = $this->request->post('pay_type', 'wechat');
|
||
|
||
$plan = Db::name('member_plan')->where('id', $planId)->where('status', 'normal')->find();
|
||
if (!$plan) {
|
||
$this->error('套餐不存在或已下架');
|
||
}
|
||
if (!in_array($payType, ['wechat', 'alipay'])) {
|
||
$this->error('不支持的支付方式');
|
||
}
|
||
|
||
$orderNo = 'HQ' . date('YmdHis') . Random::numeric(4);
|
||
$now = time();
|
||
$id = Db::name('member_order')->insertGetId([
|
||
'order_no' => $orderNo,
|
||
'user_id' => $userId,
|
||
'plan_id' => (int)$plan['id'],
|
||
'plan_code' => $plan['code'],
|
||
'amount' => $plan['price'],
|
||
'pay_type' => $payType,
|
||
'pay_status' => 'unpaid',
|
||
'createtime' => $now,
|
||
'updatetime' => $now,
|
||
]);
|
||
|
||
$this->success('订单已创建', [
|
||
'order_id' => (int)$id,
|
||
'order_no' => $orderNo,
|
||
'amount' => (float)$plan['price'],
|
||
'plan' => [
|
||
'code' => $plan['code'],
|
||
'name' => $plan['name'],
|
||
],
|
||
'pay_type' => $payType,
|
||
'pay_hint' => '支付通道(微信/易支付)待接入,可由后台确认订单后开通权益',
|
||
'pay_status' => 'unpaid',
|
||
]);
|
||
}
|
||
}
|