Bladeren bron

first commit

Drunking 1 week geleden
bovenliggende
commit
4de1fed6e8
40 gewijzigde bestanden met toevoegingen van 1994 en 1152 verwijderingen
  1. 0 481
      example-book/5.4.home.tml
  2. 0 7
      example-book/6.0.cloud.object/README.md
  3. 0 75
      example-book/6.0.cloud.object/cloud-object.js
  4. 0 105
      example-book/6.0.cloud.object/cloud-query.js
  5. 0 21
      example-book/6.0.cloud.object/tutor-cloud.js
  6. 0 56
      example-book/6.0.cloud.object/tutor-fetch.js
  7. 0 29
      example-book/6.0.cloud.object/tutor-query.js
  8. 8 8
      rag-server/rag-loaders/test/test.splitter.js
  9. 22 1
      src/agent/README.md
  10. 2 1
      src/app/app.routes.ts
  11. 84 51
      src/app/tab1/tab1.page.html
  12. 124 0
      src/app/tab1/tab1.page.scss
  13. 159 95
      src/app/tab2/tab2.page.html
  14. 216 63
      src/app/tab2/tab2.page.scss
  15. 189 108
      src/app/tab2/tab2.page.ts
  16. 147 19
      src/app/tab3/tab3.page.html
  17. 302 0
      src/app/tab3/tab3.page.scss
  18. 0 1
      src/app/tab3/tab3.page.spec.ts
  19. 312 22
      src/app/tab3/tab3.page.ts
  20. 171 0
      src/app/tab4/tab4.page.html
  21. 203 0
      src/app/tab4/tab4.page.scss
  22. 17 0
      src/app/tab4/tab4.page.spec.ts
  23. 20 0
      src/app/tab4/tab4.page.ts
  24. 10 7
      src/app/tabs/tabs.page.html
  25. 7 1
      src/app/tabs/tabs.routes.ts
  26. BIN
      src/assets/avatars/xinli1.jpeg
  27. BIN
      src/assets/avatars/xinli2.jpeg
  28. BIN
      src/assets/avatars/xinli3.jpeg
  29. BIN
      src/assets/icon/ganen.jpg
  30. BIN
      src/assets/icon/ganen1.jpg
  31. BIN
      src/assets/icon/qingxu.jpg
  32. BIN
      src/assets/icon/qingxu1.webp
  33. BIN
      src/assets/icon/zijue.jpg.webp
  34. BIN
      src/assets/icon/zijue1.webp
  35. BIN
      src/assets/images/1.jpg
  36. BIN
      src/assets/images/2.jpg
  37. BIN
      src/assets/images/3.png
  38. BIN
      src/assets/images/4.jpg
  39. BIN
      src/assets/images/5.jpg
  40. 1 1
      src/index.html

+ 0 - 481
example-book/5.4.home.tml

@@ -1,481 +0,0 @@
-<!DOCTYPE html>
-<html lang="zh-CN">
-<head>
-    <meta charset="UTF-8">
-    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
-    <title>灵犀问诊AI项目首页原型设计</title>
-    <link rel="stylesheet" href="https://cdn.bootcdn.net/ajax/libs/font-awesome/6.4.0/css/all.min.css">
-    <style>
-        /* 苹果HIG风格基础设置 */
-        :root {
-            --ios-bg: #f2f2f7;
-            --ios-card: #ffffff;
-            --ios-primary: #007aff;
-            --ios-danger: #ff3b30;
-            --ios-warning: #ff9500;
-            --ios-success: #34c759;
-            --ios-text-primary: #1c1c1e;
-            --ios-text-secondary: #636366;
-            --ios-border: #d1d1d6;
-            --ios-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
-        }
-
-        * {
-            margin: 0;
-            padding: 0;
-            box-sizing: border-box;
-            -webkit-tap-highlight-color: transparent;
-            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
-        }
-
-        body {
-            background: var(--ios-bg);
-            color: var(--ios-text-primary);
-            line-height: 1.5;
-            padding-bottom: env(safe-area-inset-bottom);
-        }
-
-        /* 状态栏区域 */
-        .status-bar {
-            padding: 12px 16px 8px;
-            display: flex;
-            justify-content: space-between;
-            align-items: center;
-            font-size: 14px;
-            color: var(--ios-text-secondary);
-        }
-
-        .emergency-btn {
-            position: fixed;
-            top: 16px;
-            right: 16px;
-            width: 44px;
-            height: 44px;
-            background: var(--ios-danger);
-            border-radius: 22px;
-            display: flex;
-            justify-content: center;
-            align-items: center;
-            color: white;
-            box-shadow: var(--ios-shadow);
-            z-index: 100;
-            animation: pulse 2s infinite;
-        }
-
-        @keyframes pulse {
-            0%, 100% { transform: scale(1); }
-            50% { transform: scale(1.1); }
-        }
-
-        /* 用户信息卡 */
-        .user-card {
-            background: var(--ios-card);
-            margin: 16px;
-            padding: 20px;
-            border-radius: 12px;
-            box-shadow: var(--ios-shadow);
-            display: flex;
-            align-items: center;
-        }
-
-        .user-avatar {
-            width: 56px;
-            height: 56px;
-            background: linear-gradient(135deg, #64d2ff 0%, #5e5ce6 100%);
-            border-radius: 28px;
-            display: flex;
-            justify-content: center;
-            align-items: center;
-            color: white;
-            font-size: 24px;
-            font-weight: 500;
-            margin-right: 16px;
-        }
-
-        .user-info {
-            flex: 1;
-        }
-
-        .user-name {
-            font-size: 18px;
-            font-weight: 600;
-            margin-bottom: 4px;
-        }
-
-        .health-status {
-            display: inline-block;
-            padding: 4px 10px;
-            background: #e5f9e7;
-            color: var(--ios-success);
-            border-radius: 10px;
-            font-size: 13px;
-            font-weight: 500;
-        }
-
-        /* 症状输入区 */
-        .symptom-input {
-            margin: 0 16px 24px;
-        }
-
-        .input-container {
-            position: relative;
-            background: var(--ios-card);
-            border-radius: 12px;
-            box-shadow: var(--ios-shadow);
-            padding: 16px;
-        }
-
-        .input-field {
-            width: 100%;
-            border: none;
-            outline: none;
-            font-size: 16px;
-            padding: 12px 16px;
-            background: #f7f7f8;
-            border-radius: 10px;
-            color: var(--ios-text-primary);
-        }
-
-        .input-actions {
-            display: flex;
-            margin-top: 12px;
-        }
-
-        .action-btn {
-            flex: 1;
-            display: flex;
-            align-items: center;
-            justify-content: center;
-            padding: 8px;
-            color: var(--ios-primary);
-            font-size: 14px;
-        }
-
-        .action-btn i {
-            margin-right: 6px;
-        }
-
-        /* 紧急服务区 */
-        .emergency-services {
-            margin: 0 16px 24px;
-        }
-
-        .section-title {
-            font-size: 20px;
-            font-weight: 600;
-            margin-bottom: 16px;
-            padding-left: 4px;
-        }
-
-        .service-grid {
-            display: grid;
-            grid-template-columns: repeat(2, 1fr);
-            gap: 12px;
-        }
-
-        .service-card {
-            background: var(--ios-card);
-            border-radius: 12px;
-            padding: 20px 16px;
-            box-shadow: var(--ios-shadow);
-            text-align: center;
-            transition: transform 0.2s;
-        }
-
-        .service-card:active {
-            transform: scale(0.98);
-        }
-
-        .service-icon {
-            width: 40px;
-            height: 40px;
-            background: linear-gradient(135deg, #ffd426 0%, #ff375f 100%);
-            border-radius: 20px;
-            display: flex;
-            justify-content: center;
-            align-items: center;
-            color: white;
-            margin: 0 auto 12px;
-            font-size: 18px;
-        }
-
-        .service-name {
-            font-size: 16px;
-            font-weight: 500;
-            margin-bottom: 4px;
-        }
-
-        .service-desc {
-            font-size: 13px;
-            color: var(--ios-text-secondary);
-        }
-
-        /* 健康数据区 */
-        .health-data {
-            margin: 0 16px 24px;
-        }
-
-        .data-card {
-            background: var(--ios-card);
-            border-radius: 12px;
-            padding: 16px;
-            box-shadow: var(--ios-shadow);
-        }
-
-        .data-header {
-            display: flex;
-            justify-content: space-between;
-            align-items: center;
-            margin-bottom: 16px;
-        }
-
-        .data-title {
-            font-size: 17px;
-            font-weight: 600;
-        }
-
-        .data-more {
-            color: var(--ios-primary);
-            font-size: 15px;
-        }
-
-        .data-grid {
-            display: grid;
-            grid-template-columns: repeat(3, 1fr);
-            gap: 12px;
-        }
-
-        .data-item {
-            text-align: center;
-        }
-
-        .data-value {
-            font-size: 22px;
-            font-weight: 600;
-            margin-bottom: 2px;
-        }
-
-        .data-label {
-            font-size: 13px;
-            color: var(--ios-text-secondary);
-        }
-
-        /* 底部导航 */
-        .tab-bar {
-            position: fixed;
-            bottom: 0;
-            left: 0;
-            right: 0;
-            background: rgba(255, 255, 255, 0.9);
-            backdrop-filter: blur(20px);
-            display: flex;
-            padding: 10px 0;
-            padding-bottom: calc(10px + env(safe-area-inset-bottom));
-            border-top: 1px solid var(--ios-border);
-        }
-
-        .tab-item {
-            flex: 1;
-            text-align: center;
-            color: var(--ios-text-secondary);
-            font-size: 12px;
-        }
-
-        .tab-item.active {
-            color: var(--ios-primary);
-        }
-
-        .tab-icon {
-            font-size: 22px;
-            margin-bottom: 2px;
-        }
-
-        /* 医疗特殊样式 */
-        .medical-warning {
-            color: var(--ios-danger);
-            font-weight: 500;
-        }
-
-        .medical-normal {
-            color: var(--ios-success);
-        }
-
-        /* 响应式调整 */
-        @media (min-width: 768px) {
-            body {
-                max-width: 500px;
-                margin: 0 auto;
-                border-left: 1px solid var(--ios-border);
-                border-right: 1px solid var(--ios-border);
-            }
-        }
-    </style>
-</head>
-<body>
-    <!-- 状态栏 -->
-    <div class="status-bar">
-        <span id="current-time">下午2:30</span>
-        <span><i class="fas fa-wifi"></i> 中国移动</span>
-    </div>
-
-    <!-- 紧急按钮 -->
-    <button class="emergency-btn" id="emergencyBtn">
-        <i class="fas fa-plus"></i>
-    </button>
-
-    <!-- 用户信息 -->
-    <div class="user-card">
-        <div class="user-avatar">张</div>
-        <div class="user-info">
-            <div class="user-name">下午好,张先生</div>
-            <div class="health-status"><i class="fas fa-heartbeat"></i> 健康状况良好</div>
-        </div>
-    </div>
-
-    <!-- 症状输入 -->
-    <div class="symptom-input">
-        <div class="input-container">
-            <input type="text" class="input-field" placeholder="描述症状或上传报告...">
-            <div class="input-actions">
-                <div class="action-btn">
-                    <i class="fas fa-microphone"></i> 语音
-                </div>
-                <div class="action-btn">
-                    <i class="fas fa-camera"></i> 拍照
-                </div>
-                <div class="action-btn">
-                    <i class="fas fa-history"></i> 历史
-                </div>
-            </div>
-        </div>
-    </div>
-
-    <!-- 紧急服务 -->
-    <div class="emergency-services">
-        <h2 class="section-title">紧急服务</h2>
-        <div class="service-grid">
-            <div class="service-card" id="fastBtn">
-                <div class="service-icon">
-                    <i class="fas fa-brain"></i>
-                </div>
-                <div class="service-name">卒中评估</div>
-                <div class="service-desc">FAST快速筛查</div>
-            </div>
-            <div class="service-card" id="poisonBtn">
-                <div class="service-icon" style="background: linear-gradient(135deg, #32d74b 0%, #0a84ff 100%);">
-                    <i class="fas fa-biohazard"></i>
-                </div>
-                <div class="service-name">中毒咨询</div>
-                <div class="service-desc">24小时在线</div>
-            </div>
-        </div>
-    </div>
-
-    <!-- 健康数据 -->
-    <div class="health-data">
-        <h2 class="section-title">健康数据</h2>
-        <div class="data-card">
-            <div class="data-header">
-                <div class="data-title">今日健康指标</div>
-                <div class="data-more">更多 <i class="fas fa-chevron-right"></i></div>
-            </div>
-            <div class="data-grid">
-                <div class="data-item">
-                    <div class="data-value medical-normal">72</div>
-                    <div class="data-label">心率</div>
-                </div>
-                <div class="data-item">
-                    <div class="data-value">118/78</div>
-                    <div class="data-label">血压</div>
-                </div>
-                <div class="data-item">
-                    <div class="data-value medical-warning">6.2</div>
-                    <div class="data-label">血糖</div>
-                </div>
-            </div>
-        </div>
-    </div>
-
-    <!-- 底部导航 -->
-    <div class="tab-bar">
-        <div class="tab-item active">
-            <div class="tab-icon"><i class="fas fa-home"></i></div>
-            <div>首页</div>
-        </div>
-        <div class="tab-item">
-            <div class="tab-icon"><i class="fas fa-comment-medical"></i></div>
-            <div>问诊</div>
-        </div>
-        <div class="tab-item">
-            <div class="tab-icon"><i class="fas fa-pills"></i></div>
-            <div>药品</div>
-        </div>
-        <div class="tab-item">
-            <div class="tab-icon"><i class="fas fa-user-md"></i></div>
-            <div>我的</div>
-        </div>
-    </div>
-
-    <script>
-        // 更新时间显示
-        function updateTime() {
-            const now = new Date();
-            const hours = now.getHours();
-            const minutes = now.getMinutes().toString().padStart(2, '0');
-            const period = hours >= 12 ? '下午' : '上午';
-            const displayHours = hours > 12 ? hours - 12 : hours;
-            document.getElementById('current-time').textContent = `${period}${displayHours}:${minutes}`;
-        }
-        setInterval(updateTime, 1000);
-        updateTime();
-
-        // 紧急按钮交互
-        document.getElementById('emergencyBtn').addEventListener('click', function() {
-            // iOS风格震动反馈
-            if (window.navigator.vibrate) {
-                window.navigator.vibrate([50, 50, 50]);
-            }
-            
-            // 显示紧急菜单
-            alert('已触发紧急联络\n将通知您的紧急联系人');
-        });
-
-        // 卒中评估按钮
-        document.getElementById('fastBtn').addEventListener('click', function() {
-            alert('FAST评估指南:\nF-面部下垂\nA-手臂无力\nS-言语困难\nT-及时就医');
-        });
-
-        // 中毒咨询按钮
-        document.getElementById('poisonBtn').addEventListener('click', function() {
-            alert('中毒应急处理:\n1. 立即脱离毒源\n2. 保留毒物样本\n3. 拨打120');
-        });
-
-        // 输入框聚焦效果
-        const inputField = document.querySelector('.input-field');
-        inputField.addEventListener('focus', function() {
-            this.parentElement.style.boxShadow = '0 0 0 2px rgba(0, 122, 255, 0.3)';
-        });
-        inputField.addEventListener('blur', function() {
-            this.parentElement.style.boxShadow = 'var(--ios-shadow)';
-        });
-
-        // 模拟健康数据更新
-        setInterval(() => {
-            const heartRate = Math.floor(65 + Math.random() * 10);
-            const bloodPressure = `${110 + Math.floor(Math.random() * 10)}/${70 + Math.floor(Math.random() * 8)}`;
-            
-            document.querySelectorAll('.data-value')[0].textContent = heartRate;
-            document.querySelectorAll('.data-value')[1].textContent = bloodPressure;
-            
-            // 心率异常提示
-            if (heartRate > 75) {
-                document.querySelectorAll('.data-value')[0].classList.add('medical-warning');
-                document.querySelectorAll('.data-value')[0].classList.remove('medical-normal');
-            } else {
-                document.querySelectorAll('.data-value')[0].classList.remove('medical-warning');
-                document.querySelectorAll('.data-value')[0].classList.add('medical-normal');
-            }
-        }, 3000);
-    </script>
-</body>
-</html>

+ 0 - 7
example-book/6.0.cloud.object/README.md

@@ -1,7 +0,0 @@
-# 演示微服务案例
-- tutor-fecth.js 网络请求增删查改
-- cloud-object.js 面向对象增删改
-- tutor-cloud.js 面向对象增删改示例
-- cloud-object.js 面向对象查询
-- cloud-query.js 面向对象查询示例
-

+ 0 - 75
example-book/6.0.cloud.object/cloud-object.js

@@ -1,75 +0,0 @@
-
-/**
- @example
-    let tutor = new CloudObject("Tutor")
-    tutor.set({
-        name:"宋教练",
-        age:22,
-        gender:"女"
-    })
-    tutor.save()
-
-    let food = new CloudObject("FoodMenu")
-    food.set({
-        title:"馅饼",
-        price:10,
-    })
-    food.save()
-
- */
-class CloudObject {
-    className
-    objectId
-    data = {}
-    constructor(className) {
-        this.className = className
-    }
-    set(data) {
-        Object.keys(data).forEach(key => {
-            this.data[key] = data[key]
-        })
-    }
-    async save() {
-        let method = "POST"
-        let url = "http://dev.fmode.cn:1337/parse/classes/" + this.className
-        if (this.objectId) {
-            method = "PUT"
-            url = url + "/" + this.objectId
-        }
-        delete this.data.createdAt
-        delete this.data.updatedAt
-        delete this.data.objectId
-
-        let response = await fetch(url, {
-            "headers": {
-                "content-type": "text/plain;charset=UTF-8",
-                "x-parse-application-id": "dev"
-            },
-            "body": JSON.stringify(this.data),
-            "method": method,
-            "mode": "cors",
-            "credentials": "omit"
-        });
-        let data = await response.json()
-        this.objectId = data.objectId
-    }
-
-    async destroy() {
-        let url = "http://dev.fmode.cn:1337/parse/classes/" + this.className + "/" + this.objectId
-
-        let response = await fetch(url, {
-            "headers": {
-                "content-type": "text/plain;charset=UTF-8",
-                "x-parse-application-id": "dev"
-            },
-            "body": null,
-            "method": "DELETE",
-            "mode": "cors",
-            "credentials": "omit"
-        });
-        let data = await response.json()
-        this.objectId = data.objectId
-    }
-}
-
-module.exports.CloudObject = CloudObject

+ 0 - 105
example-book/6.0.cloud.object/cloud-query.js

@@ -1,105 +0,0 @@
-/**
- * 查询类
- @example
-// 查询指定教练,修改价格
-    let query = new CloudQuery("Tutor");
-    let tutor = await query.get("imkGFr6Ztj");
-    console.log('tutor', tutor)
-    tutor.set({
-        price: 199
-    })
-    tutor = await tutor.save()
-
-    // 条件查询:价格大于60
-    let query2 = new CloudQuery("FoodMenu");
-    query2.lessThan("price", 60);
-    // query2.greaterThan("price", 20);
-    let foodList = await query2.find();
-    console.log("foodList", foodList)
-
-    // 条件查询:性别等于女
-    let query3 = new CloudQuery("Tutor");
-    query3.equalTo("gender", "女");
-    let tutorList = await query3.find();
-    console.log("tutorList", tutorList);
-
- */
-const { CloudObject } = require("./cloud-object")
-
-
-class CloudQuery {
-    className
-    queryParams = {
-        where: {}
-    }
-    constructor(className) {
-        this.className = className
-    }
-
-    async get(objectId) {
-        let res = await fetch(`http://dev.fmode.cn:1337/parse/classes/${this.className}/${objectId}?`, {
-            "headers": {
-                "accept": "*/*",
-                "accept-language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6",
-                "x-parse-application-id": "dev"
-            },
-            "referrer": "http://localhost:4040/",
-            "referrerPolicy": "strict-origin-when-cross-origin",
-            "body": null,
-            "method": "GET",
-            "mode": "cors",
-            "credentials": "omit"
-        });
-        let data = await res.json()
-        let dataObj = new CloudObject(this.className);
-        dataObj.objectId = data.objectId
-        dataObj.set(data)
-        console.log(data, dataObj)
-        return dataObj
-    }
-    equalTo(key, value) {
-        this.queryParams.where[key] = value
-    }
-    lessThan(key, value) {
-        this.queryParams.where[key] = { "$lt": value }
-    } g
-    greaterThan(key, value) {
-        this.queryParams.where[key] = { "$gt": value }
-    }
-    async find() {
-        // where={%22price%22:{%22$gt%22:60}}
-        let whereStr = ``
-        if (Object.keys(this.queryParams.where)?.length) {
-            whereStr = `where=` + JSON.stringify(this.queryParams.where)
-        }
-        let url = `http://dev.fmode.cn:1337/parse/classes/${this.className}?${whereStr}`
-        console.log(url)
-        let res = await fetch(url, {
-            "headers": {
-                "accept": "*/*",
-                "accept-language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6",
-                "if-none-match": "W/\"b2-UccTNjvsEYMR2Waro9KVbWJiRJs\"",
-                "x-parse-application-id": "dev"
-            },
-            "referrer": "http://localhost:4040/",
-            "referrerPolicy": "strict-origin-when-cross-origin",
-            "body": null,
-            "method": "GET",
-            "mode": "cors",
-            "credentials": "omit"
-        });
-        let data = await res.json()
-        let list = data.results
-        list = list.map(item => {
-            let dataObj = new CloudObject(this.className);
-            dataObj.objectId = item.objectId
-            dataObj.set(item)
-            return dataObj
-        })
-        console.log(list)
-        return list
-    }
-
-}
-
-module.exports.CloudQuery = CloudQuery

+ 0 - 21
example-book/6.0.cloud.object/tutor-cloud.js

@@ -1,21 +0,0 @@
-const { CloudObject } = require("./cloud-object")
-
-async function main() {
-    let tutor = new CloudObject("Tutor")
-    tutor.set({
-        name: "宋教练",
-        age: 22,
-        gender: "女"
-    })
-    tutor.save()
-
-    let foodMenu = new CloudObject("FoodMenu")
-    foodMenu.set({
-        title: "馅饼",
-        price: 10,
-    })
-    foodMenu.save()
-}
-
-
-main();

+ 0 - 56
example-book/6.0.cloud.object/tutor-fetch.js

@@ -1,56 +0,0 @@
-
-
-async function createTutor() {
-    let response = await fetch("http://dev.fmode.cn:1337/parse/classes/Tutor", {
-        "headers": {
-            "content-type": "text/plain;charset=UTF-8",
-            "x-parse-application-id": "dev"
-        },
-        "body": JSON.stringify({
-            name: "王教练",
-            age: 32
-        }),
-        "method": "POST",
-        "mode": "cors",
-        "credentials": "omit"
-    });
-    let data = await response.json()
-    console.log(data)
-}
-
-// createTutor()
-
-
-
-async function updateTutor(objectId, updateData) {
-    let response = await fetch("http://dev.fmode.cn:1337/parse/classes/Tutor/" + objectId, {
-        "headers": {
-            "content-type": "text/plain;charset=UTF-8",
-            "x-parse-application-id": "dev"
-        },
-        "body": JSON.stringify(updateData),
-        "method": "PUT",
-        "mode": "cors",
-        "credentials": "omit"
-    });
-    let data = await response.json()
-    console.log(data)
-}
-
-// updateTutor("DlvWtHrQRt", { price: 200 })
-
-async function deleteTutor(objectId) {
-    let response = await fetch("http://dev.fmode.cn:1337/parse/classes/Tutor/" + objectId, {
-        "headers": {
-            "content-type": "text/plain;charset=UTF-8",
-            "x-parse-application-id": "dev"
-        },
-        "body": null,
-        "method": "DELETE",
-        "mode": "cors",
-        "credentials": "omit"
-    });
-    let data = await response.json()
-    console.log(data)
-}
-deleteTutor("DlvWtHrQRt")

+ 0 - 29
example-book/6.0.cloud.object/tutor-query.js

@@ -1,29 +0,0 @@
-const { CloudQuery } = require("./cloud-query");
-
-async function main() {
-
-    // 查询指定教练,修改价格
-    let query = new CloudQuery("Tutor");
-    let tutor = await query.get("imkGFr6Ztj");
-    console.log('tutor', tutor)
-    tutor.set({
-        price: 199
-    })
-    tutor = await tutor.save()
-
-    // 条件查询:价格大于60
-    let query2 = new CloudQuery("FoodMenu");
-    query2.lessThan("price", 60);
-    // query2.greaterThan("price", 20);
-    let foodList = await query2.find();
-    console.log("foodList", foodList)
-
-    // 条件查询:性别等于女
-    let query3 = new CloudQuery("Tutor");
-    query3.equalTo("gender", "女");
-    let tutorList = await query3.find();
-    console.log("tutorList", tutorList);
-}
-
-
-main();

+ 8 - 8
rag-server/rag-loaders/test/test.splitter.js

@@ -24,15 +24,15 @@ async function main(){
     console.log(output)
   
     // 文本提取文本块
-    let html = await docsLoader("../data/pgvector.docx")
-    const splitter = RecursiveCharacterTextSplitter.fromLanguage("html", {
-        chunkSize: 4096,
-        chunkOverlap: 20,
-      });
-    const output = await splitter.createDocuments([html]);
+    // let html = await docsLoader("../data/pgvector.docx")
+    // const splitter = RecursiveCharacterTextSplitter.fromLanguage("html", {
+    //     chunkSize: 4096,
+    //     chunkOverlap: 20,
+    //   });
+    // const output = await splitter.createDocuments([html]);
     
-    console.log(output);
-    console.log(JSON.stringify(output[0]));
+    // console.log(output);
+    // console.log(JSON.stringify(output[0]));
         
 }
 main()

+ 22 - 1
src/agent/README.md

@@ -1,6 +1,27 @@
 
 
+
 # 技术设计
+
 - AgentTaskStep类 智能体任务的某一个步骤(简单任务)
 - TaskExecutor类 任务执行器
-- AgentTaskComponent类 展示任务进行进度的面板
+- AgentTaskComponent类 展示任务进行进度的面板
+
+# AI辅助生成工作流
+技术参考文档:三个常用任务的使用方法
+{{TaskCompletionText用法}}
+{{TaskCompletionJson用法}}
+{{TaskUserForm用法}}
+
+我希望您编排一系列任务,可以实现日记类app中有关心理方向智能体的工作流,
+智能体一些特殊功能包括
+1.模拟心理咨询师话术,引导用户进行认知行为疗法(CBT)对话
+2.图片日记(输入描述AI自动生成图片场景)
+3.输入烦恼后AI生成毒舌吐槽/沙雕表情包
+给我任务列表就好。
+需要注意:
+可以通过TaskUserForm采集用户问题和表达
+可以通过TaskCompletionJson生成一些标签类或者结构化数据
+可以通过TaskCompletionText输出完整的方案
+
+请注意按照格式来写每个人任务以及input、output,任务是逐步执行的,需要严格检查每个阶段产生的数据和下一阶段需要的数据。

+ 2 - 1
src/app/app.routes.ts

@@ -54,5 +54,6 @@ export const routes: Routes = [
       path: "task/test",
       loadComponent: () => import('../modules/task/page-test-completion/page-test-completion.component').then(m => m.PageTestCompletionComponent),
       runGuardsAndResolvers: "always",
-  }
+  },
+
 ];

+ 84 - 51
src/app/tab1/tab1.page.html

@@ -1,58 +1,91 @@
 <ion-header [translucent]="true">
-  <ion-toolbar>
-    <ion-title>
-      任务集执行展示
-    </ion-title>
-  </ion-toolbar>
+
+    <!-- 顶部标题栏 -->
+    <div class="header">
+        <i class="header-icon ion-ios-more" id="menuBtn"></i>
+        <div class="header-title">日记本</div>
+        <i class="header-icon ion-ios-create" id="editBtn"></i>
+    </div>
+    
 </ion-header>
 
 <ion-content [fullscreen]="true">
- <ion-button (click)="doPoemTask()">执行诗文意境绘制任务集</ion-button>
- <ion-button (click)="doInqueryTask()">执行问诊任务集</ion-button>
-  <ion-button (click)="testJSON()">测试JSON</ion-button>
-  <ion-button (click)="testCompletion()">测试TestCompletion</ion-button>
-
-
- <ul>
-  @for(step of taskList;track step.title;){
-    <div>
-      <!-- 待开始 -->
-      @if(step.progress==0 && !step.error){
-        <ion-icon name="radio-button-off-outline"></ion-icon>
-      }
-      <!-- 进行中 -->
-      @if(step.progress!=0 && step.progress!=1){
-        <ion-icon name="reload-outline"></ion-icon>
-      }
-      <!-- 已完成 -->
-      @if(step.progress==1){
-        <ion-icon name="checkmark-circle-outline"></ion-icon>
-      }
-      <!-- 已出错 -->
-      @if(step.error){
-        <ion-icon name="close-circle-outline"></ion-icon>
-      }
-      {{step.title}}  @if(step.progress){<span>{{step.progress * 100 | number:"2.0-0"}}%</span>}
-
-      @if(step.error){
-        <span style="color:red;">{{step.error}}</span>
-      }
+    
+    <!-- 内容区域 -->
+    <div class="content" id="diaryList">
+        <!-- 日记卡片1 -->
+        <div class="diary-card">
+            <div class="diary-time">
+                <div class="diary-date">15</div>
+                <div class="diary-week">周三</div>
+                <div class="diary-hour">14:30</div>
+            </div>
+            <div class="diary-content">
+                今天阳光明媚,去公园散步时看到樱花开了。粉色的花瓣随风飘落,美得像一幅画。坐在长椅上读了一会儿书,感觉心情特别平静。
+            </div>
+        </div>
+        
+        <!-- 日记卡片2 -->
+        <div class="diary-card">
+            <div class="diary-time">
+                <div class="diary-date">14</div>
+                <div class="diary-week">周二</div>
+                <div class="diary-hour">21:15</div>
+            </div>
+            <div class="diary-content">
+                项目终于告一段落,加班到很晚但很有成就感。回家的路上买了杯热奶茶犒劳自己,发现常去的那家奶茶店换了新包装,杯子上画着可爱的小兔子。
+            </div>
+        </div>
+        
+        <!-- 日记卡片3 -->
+        <div class="diary-card">
+            <div class="diary-time">
+                <div class="diary-date">12</div>
+                <div class="diary-week">周日</div>
+                <div class="diary-hour">09:45</div>
+            </div>
+            <div class="diary-content">
+                周末尝试做了新的菜谱 - 番茄牛腩。虽然炖的时间比预期长,但结果非常美味!下午窝在沙发上看了一部老电影,窗外下着小雨,这种慵懒的周末真是太棒了。
+            </div>
+        </div>
+        
+        <div class="load-more" id="loadMore">
+            加载更多日记 <i class="ion-ios-arrow-down"></i>
+        </div>
     </div>
-  }
-  </ul>
-
-  <!-- 诗词意境绘画生成结果 -->
-  @if(shareData.images) {
-    @for(imageUrl of shareData.images;track imageUrl){
-      <img [src]="imageUrl" alt="" srcset="">
-    }
-  }
-
-  <!-- 问诊报告生成结果 -->
-  @if(shareData.diagResult){
-    <h1>{{shareData.diagResult.title}}</h1>
-    <h2>{{shareData.diagResult.desc}}</h2>
-    <p>{{shareData.diagResult.content}}</p>
-  }
 
+    <script>
+        document.addEventListener('DOMContentLoaded', function() {
+            // 顶部按钮点击事件
+            document.getElementById('editBtn').addEventListener('click', function() {
+                alert('进入编辑日记模式');
+            });
+            
+            document.getElementById('menuBtn').addEventListener('click', function() {
+                alert('打开侧边菜单');
+            });
+            
+            // 加载更多点击事件
+            document.getElementById('loadMore').addEventListener('click', function() {
+                const loadingText = this.innerHTML;
+                this.innerHTML = '加载中...';
+                
+                // 模拟加载延迟
+                setTimeout(() => {
+                    // 这里可以添加实际加载更多日记的逻辑
+                    alert('已加载更多日记');
+                    this.innerHTML = loadingText;
+                }, 800);
+            });
+            
+            // 日记卡片点击事件
+            const diaryCards = document.querySelectorAll('.diary-card');
+            diaryCards.forEach(card => {
+                card.addEventListener('click', function() {
+                    // 这里可以添加查看日记详情的逻辑
+                    console.log('查看日记详情');
+                });
+            });
+        });
+    </script>
 </ion-content>

+ 124 - 0
src/app/tab1/tab1.page.scss

@@ -0,0 +1,124 @@
+* {
+    margin: 0;
+    padding: 0;
+    box-sizing: border-box;
+    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
+}
+
+body {
+    background-color: #f8f4ee;
+    color: #5a4a42;
+    min-height: 100vh;
+    display: flex;
+    flex-direction: column;
+}
+
+/* 顶部标题栏 */
+.header {
+    background-color: #fff9f0;
+    padding: 15px 20px;
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
+    position: sticky;
+    top: 0;
+    z-index: 100;
+    border-bottom: 1px solid #f0e6d6;
+}
+
+.header-title {
+    font-size: 1.1rem;
+    font-weight: 600;
+    color: #b38a58;
+    letter-spacing: 0.5px;
+}
+
+.header-icon {
+    font-size: 1.3rem;
+    color: #b38a58;
+    cursor: pointer;
+    transition: opacity 0.2s;
+}
+
+.header-icon:active {
+    opacity: 0.7;
+}
+
+/* 内容区域 */
+.content {
+    flex: 1;
+    padding: 20px 15px;
+    overflow-y: auto;
+}
+
+/* 日记卡片 */
+.diary-card {
+    background-color: #fff;
+    border-radius: 14px;
+    padding: 18px;
+    margin-bottom: 18px;
+    box-shadow: 0 3px 10px rgba(0, 0, 0, 0.04);
+    display: flex;
+    transition: all 0.25s ease;
+    border: 1px solid #f0e6d6;
+}
+
+.diary-card:active {
+    transform: scale(0.98);
+    box-shadow: 0 2px 5px rgba(0, 0, 0, 0.05);
+}
+
+.diary-time {
+    width: 70px;
+    padding-right: 16px;
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+}
+
+.diary-date {
+    font-size: 1.5rem;
+    font-weight: bold;
+    color: #e67e22;
+    line-height: 1;
+}
+
+.diary-week {
+    font-size: 0.75rem;
+    color: #e67e22;
+    margin: 5px 0;
+    font-weight: 500;
+    opacity: 0.9;
+}
+
+.diary-hour {
+    font-size: 0.75rem;
+    color: #e67e22;
+    opacity: 0.8;
+    font-weight: 500;
+}
+
+.diary-content {
+    flex: 1;
+    padding-left: 16px;
+    font-size: 0.95rem;
+    line-height: 1.7;
+    color: #5a4a42;
+    border-left: 1px dashed #f0e6d6;
+    padding-top: 3px;
+}
+
+/* 加载更多 */
+.load-more {
+    text-align: center;
+    margin-top: 10px;
+    color: #b38a58;
+    font-size: 0.9rem;
+    padding: 12px;
+    cursor: pointer;
+}
+
+.load-more:active {
+    opacity: 0.7;
+}

+ 159 - 95
src/app/tab2/tab2.page.html

@@ -1,101 +1,165 @@
 <ion-header [translucent]="true">
-  <ion-toolbar color="primary">
-    <ion-title>
-      <ion-icon name="chatbubbles" class="ion-align-self-center"></ion-icon>
-      &nbsp;智能对话助手
-    </ion-title>
-  </ion-toolbar>
-</ion-header>
-
-<ion-content [fullscreen]="true" class="ion-padding">
-  <div class="welcome-section">
-    <ion-card class="welcome-card" color="light">
-      <ion-card-header>
-        <ion-card-title>欢迎使用智能对话系统</ion-card-title>
-        <ion-card-subtitle>选择您需要的服务开始对话</ion-card-subtitle>
-      </ion-card-header>
-      <ion-card-content>
-        <p>我们的智能助手可以为您提供多种专业领域的咨询服务,点击下方按钮开始体验。</p>
-      </ion-card-content>
-    </ion-card>
-  </div>
 
-  <ion-grid class="features-grid">
-    <ion-row>
-      <ion-col size="12" size-md="6">
-        <ion-card class="feature-card" button (click)="openChat()">
-          <ion-card-header>
-            <ion-icon name="chatbox" color="primary" class="feature-icon"></ion-icon>
-            <ion-card-title>开始新聊天</ion-card-title>
-          </ion-card-header>
-          <ion-card-content>
-            与我们的智能助手进行自由对话,解答您的各种疑问。
-          </ion-card-content>
-          <ion-button fill="clear" expand="block">
-            开始对话
-            <ion-icon slot="end" name="arrow-forward"></ion-icon>
-          </ion-button>
-        </ion-card>
-      </ion-col>
+    <!-- 顶部搜索栏 -->
+    <div class="header">
+        <i class="envelope-icon ion-ios-mail"></i>
+        <div class="search-bar">
+            <i class="search-icon ion-ios-search"></i>
+            <div class="search-placeholder">负面情绪禁止过夜——现在立刻销毁</div>
+        </div>
+    </div>
 
-      <ion-col size="12" size-md="6">
-        <ion-card class="feature-card" button (click)="restoreChat('0w3es9v8B6')">
-          <ion-card-header>
-            <ion-icon name="time" color="secondary" class="feature-icon"></ion-icon>
-            <ion-card-title>恢复会话</ion-card-title>
-          </ion-card-header>
-          <ion-card-content>
-            继续您之前的对话,无需重复说明问题背景。
-          </ion-card-content>
-          <ion-button fill="clear" expand="block" color="secondary">
-            恢复会话
-            <ion-icon slot="end" name="arrow-forward"></ion-icon>
-          </ion-button>
-        </ion-card>
-      </ion-col>
-    </ion-row>
+</ion-header>
 
-    <ion-row>
-      <ion-col size="12">
-        <ion-card class="special-feature" button>
-          <ion-card-header>
-            <ion-icon name="medical" color="danger" class="feature-icon"></ion-icon>
-            <ion-card-title>门诊问诊服务</ion-card-title>
-            <ion-card-subtitle>专业医疗咨询</ion-card-subtitle>
-          </ion-card-header>
-          <ion-card-content>
-            我们的医疗智能助手可以为您提供初步的医疗咨询和建议,帮助您了解可能的健康问题。
-          </ion-card-content>
-          <ion-button (click)="openInquiry()" fill="clear" expand="block" color="danger">
-            进入门诊
-            <ion-icon slot="end" name="medkit"></ion-icon>
-          </ion-button>
-          <ion-button (click)="openInquiry('0w3es9v8B6')" fill="clear" expand="block" color="primary">
-            恢复对话
-            <ion-icon slot="end" name="medkit"></ion-icon>
-          </ion-button>
-        </ion-card>
-      </ion-col>
-    </ion-row>
+<ion-content [fullscreen]="true">
+    
+    <!-- 功能板块 -->
+    <div class="function-grid">
+        <div class="function-card card-1">树洞</div>
+        <div class="function-card card-2">感恩清单</div>
+        <div class="function-card card-3">漂流瓶</div>
+        <div class="function-card card-4">情绪发泄室</div>
+    </div>
+    
+    <!-- 动态日记标题栏 -->
+    <div class="tab-bar">
+        <div class="tab-item active">推荐</div>
+        <div class="tab-item">关注</div>
+        <div class="tab-item">话题</div>
+    </div>
+    
+    <!-- 动态日记列表 -->
+    <div class="diary-list">
+        <!-- 动态1 -->
+        <div class="diary-item">
+            <div class="user-info">
+                <div class="user-left">
+                    <div class="user-avatar">A</div>
+                    <div class="user-name">情绪管理师</div>
+                </div>
+                <i class="more-icon ion-ios-more"></i>
+            </div>
+            <div class="diary-content">
+                今天学会了用正念冥想缓解焦虑,分享给大家:找一个安静的地方,专注于呼吸,感受空气进入和离开身体的感觉...
+            </div>
+            <div class="diary-image">
+                <img src= "../../assets/images/4.jpg" alt="冥想">
+            </div>
+            <div class="action-bar">
+                <div class="action-item">
+                    <i class="action-icon ion-ios-heart"></i>
+                    <span>256</span>
+                </div>
+                <div class="action-item">
+                    <i class="action-icon ion-ios-chatbubbles"></i>
+                    <span>43</span>
+                </div>
+                <div class="action-item">
+                    <i class="action-icon ion-ios-share-alt"></i>
+                    <span>分享</span>
+                </div>
+            </div>
+        </div>
+        
+        <!-- 动态2 -->
+        <div class="diary-item">
+            <div class="user-info">
+                <div class="user-left">
+                    <div class="user-avatar">B</div>
+                    <div class="user-name">阳光小筑</div>
+                </div>
+                <i class="more-icon ion-ios-more"></i>
+            </div>
+            <div class="diary-content">
+                记录三件今天感恩的事:1. 早晨听到鸟叫声 2. 同事分享了好吃的饼干 3. 下班路上看到了美丽的晚霞
+            </div>
+            <div class="action-bar">
+                <div class="action-item">
+                    <i class="action-icon ion-ios-heart"></i>
+                    <span>189</span>
+                </div>
+                <div class="action-item">
+                    <i class="action-icon ion-ios-chatbubbles"></i>
+                    <span>32</span>
+                </div>
+                <div class="action-item">
+                    <i class="action-icon ion-ios-share-alt"></i>
+                    <span>分享</span>
+                </div>
+            </div>
+        </div>
+        
+        <!-- 动态3 -->
+        <div class="diary-item">
+            <div class="user-info">
+                <div class="user-left">
+                    <div class="user-avatar">C</div>
+                    <div class="user-name">树洞倾听者</div>
+                </div>
+                <i class="more-icon ion-ios-more"></i>
+            </div>
+            <div class="diary-content">
+                今天在公园长椅上发现了一个漂流瓶,里面写着"希望找到能懂我的人"。如果你看到这条消息,请记住世界上总有人愿意倾听你的故事。
+            </div>
+            <div class="diary-image">
+                <img src="../../assets/images/5.jpg" alt="漂流瓶">
+            </div>
+            <div class="action-bar">
+                <div class="action-item">
+                    <i class="action-icon ion-ios-heart"></i>
+                    <span>312</span>
+                </div>
+                <div class="action-item">
+                    <i class="action-icon ion-ios-chatbubbles"></i>
+                    <span>76</span>
+                </div>
+                <div class="action-item">
+                    <i class="action-icon ion-ios-share-alt"></i>
+                    <span>分享</span>
+                </div>
+            </div>
+        </div>
+    </div>
 
-    <ion-row>
-      <ion-col size="12">
-        <ion-card class="special-feature" button>
-          <ion-card-header>
-            <ion-icon name="medical" color="danger" class="feature-icon"></ion-icon>
-            <ion-card-title>运动健身服务</ion-card-title>
-            <ion-card-subtitle>专业健身咨询</ion-card-subtitle>
-          </ion-card-header>
-          <ion-card-content>
-            请联系我们私教咨询。
-          </ion-card-content>
-          <ion-button (click)="openConsult()" fill="clear" expand="block" color="danger">
-            开始咨询
-            <ion-icon slot="end" name="medkit"></ion-icon>
-          </ion-button>
-        </ion-card>
-      </ion-col>
-    </ion-row>
+    <script>
+        // 标签切换功能
+        const tabItems = document.querySelectorAll('.tab-item');
+        tabItems.forEach(item => {
+            item.addEventListener('click', function() {
+                tabItems.forEach(tab => tab.classList.remove('active'));
+                this.classList.add('active');
+            });
+        });
+        
+        // 点赞功能
+        const likeButtons = document.querySelectorAll('.ion-ios-heart');
+        likeButtons.forEach(button => {
+            button.addEventListener('click', function(e) {
+                e.stopPropagation();
+                const countElement = this.nextElementSibling;
+                let count = parseInt(countElement.textContent);
+                
+                if(this.classList.contains('liked')) {
+                    this.classList.remove('liked');
+                    count--;
+                    this.style.color = '#a69b8f';
+                } else {
+                    this.classList.add('liked');
+                    count++;
+                    this.style.color = '#d89ba3';
+                }
+                
+                countElement.textContent = count;
+            });
+        });
+        
+        // 动态卡片点击效果
+        const diaryItems = document.querySelectorAll('.diary-item');
+        diaryItems.forEach(item => {
+            item.addEventListener('click', function() {
+                console.log('查看动态详情');
+            });
+        });
+    </script>
 
-  </ion-grid>
-</ion-content>
+</ion-content>

+ 216 - 63
src/app/tab2/tab2.page.scss

@@ -1,65 +1,218 @@
-/* 页面整体样式 */
-ion-content {
-    --background: #f5f5f5;
-  }
-  
-  /* 欢迎卡片样式 */
-  .welcome-card {
+* {
+    margin: 0;
+    padding: 0;
+    box-sizing: border-box;
+    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
+}
+
+body {
+    background-color: #f9f5f0;
+    color: #5a4a42;
+    min-height: 100vh;
+}
+
+/* 顶部搜索栏 */
+.header {
+    background-color: #fff9f0;
+    padding: 12px 15px;
+    display: flex;
+    align-items: center;
+    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
+    position: sticky;
+    top: 0;
+    z-index: 100;
+    border-bottom: 1px solid #f0e6d6;
+}
+
+.envelope-icon {
+    font-size: 1.5rem;
+    color: #d4a373;
+    margin-right: 12px;
+}
+
+.search-bar {
+    flex: 1;
+    background-color: #f8f4ee;
+    border-radius: 20px;
+    padding: 8px 15px;
+    display: flex;
+    align-items: center;
+    color: #b38a58;
+}
+
+.search-icon {
+    font-size: 1rem;
+    margin-right: 8px;
+}
+
+.search-placeholder {
+    font-size: 0.85rem;
+    opacity: 0.8;
+}
+
+/* 功能板块 - 修改部分 */
+.function-grid {
+    display: grid;
+    grid-template-columns: 1fr 1fr;
+    gap: 10px;
+    padding: 15px;
+    padding-left: 20px;
+    padding-right: 20px;
+}
+
+.function-card {
+    height: 60px; /* 减小高度 */
+    border-radius: 20px; /* 调整为更扁平的椭圆 */
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    color: white;
+    font-weight: bold;
+    font-size: 0.9rem; /* 减小字体大小 */
+    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
+    box-shadow: 0 2px 5px rgba(0, 0, 0, 0.08);
+    transition: transform 0.2s;
+}
+
+.function-card:active {
+    transform: scale(0.97);
+}
+
+/* 降低饱和度的渐变色 */
+.card-1, .card-4 {
+    background: linear-gradient(135deg, #e2b4bd 20%, #8456af 80%);
+}
+
+.card-2, .card-3 {
+    background: linear-gradient(135deg, #b4d7e8 20%, #d8dda8 80%);
+}
+
+/* 动态日记标题栏 */
+.tab-bar {
+    display: flex;
+    padding: 12px 15px;
+    border-bottom: 1px solid #f0e6d6;
+    background-color: #fff9f0;
+}
+
+.tab-item {
+    flex: 1;
     text-align: center;
-    margin: 20px auto;
-    max-width: 800px;
-    border-radius: 15px;
-    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);
-    ion-card-header {
-      padding-bottom: 0;
-    }
-  }
-  
-  /* 功能卡片样式 */
-  .features-grid {
-    max-width: 1200px;
-    margin: 0 auto;
-  }
-  
-  .feature-card {
+    font-size: 0.9rem;
+    color: #b38a58;
+    font-weight: 500;
+    padding: 5px 0;
+}
+
+.tab-item.active {
+    color: #d4a373;
+    position: relative;
+}
+
+.tab-item.active::after {
+    content: "";
+    position: absolute;
+    bottom: -6px;
+    left: 50%;
+    transform: translateX(-50%);
+    width: 25px;
+    height: 3px;
+    background-color: #d4a373;
+    border-radius: 3px;
+}
+
+/* 动态日记列表 */
+.diary-list {
+    padding: 10px 12px;
+}
+
+.diary-item {
+    background-color: white;
+    border-radius: 10px;
+    padding: 12px;
+    margin-bottom: 12px;
+    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.04);
+}
+
+.user-info {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    margin-bottom: 10px;
+}
+
+.user-left {
+    display: flex;
+    align-items: center;
+}
+
+.user-avatar {
+    width: 36px;
+    height: 36px;
+    border-radius: 50%;
+    background-color: #f0e6d6;
+    margin-right: 8px;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    color: #b38a58;
+    font-weight: bold;
+    font-size: 0.9rem;
+}
+
+.user-name {
+    font-size: 0.9rem;
+    font-weight: 500;
+    color: #5a4a42;
+}
+
+.more-icon {
+    font-size: 1.1rem;
+    color: #a69b8f;
+}
+
+.diary-content {
+    font-size: 0.9rem;
+    line-height: 1.6;
+    color: #5a4a42;
+    margin-bottom: 10px;
+}
+
+.diary-image {
+    width: 100%;
+    border-radius: 6px;
+    margin-bottom: 10px;
+    background-color: #f8f4ee;
+    height: 160px;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    color: #a69b8f;
+    overflow: hidden;
+}
+
+.diary-image img {
+    width: 100%;
     height: 100%;
-    border-radius: 12px;
-    transition: transform 0.3s ease, box-shadow 0.3s ease;
-    &:hover {
-      transform: translateY(-5px);
-      box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1);
-    }
-    ion-card-header {
-      text-align: center;
-      padding-bottom: 0;
-    }
-    ion-card-content {
-      min-height: 80px;
-    }
-  }
-  
-  .feature-icon {
-    font-size: 48px;
-    margin-bottom: 16px;
-  }
-  
-  /* 特殊功能卡片样式 */
-  .special-feature {
-    margin-top: 20px;
-    border-radius: 12px;
-    background: linear-gradient(135deg, #fff8f8, #ffffff);
-    border-left: 4px solid var(--ion-color-danger);
-    ion-card-header {
-      text-align: center;
-    }
-    ion-card-content {
-      min-height: 80px;
-    }
-  }
-  
-  /* 响应式调整 */
-  @media (max-width: 768px) {
-    .feature-card, .special-feature {
-      margin-bottom: 20px;
-    }
-  }
+    object-fit: cover;
+}
+
+.action-bar {
+    display: flex;
+    padding-top: 6px;
+    border-top: 1px solid #f8f4ee;
+}
+
+.action-item {
+    flex: 1;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    color: #a69b8f;
+    font-size: 0.8rem;
+}
+
+.action-icon {
+    font-size: 1.1rem;
+    margin-right: 4px;
+}

+ 189 - 108
src/app/tab2/tab2.page.ts

@@ -46,7 +46,10 @@ export class Tab2Page {
     ) {
 
   }
+
   title:string = "123"
+
+
   /** 示例:问诊ChatPanel面板 */
   openInquiry(chatId?:string){
     localStorage.setItem("company","E4KpGvTEto")
@@ -207,96 +210,123 @@ export class Tab2Page {
     }
     openChatPanelModal(this.modalCtrl,options)
   }
-openConsult(chatId?:string){
+
+
+// 新建对话(强制创建新会话)
+startNewConsult() {
+  localStorage.removeItem(this.lastChatKey); // 清除历史ID
+  this.openConsult(undefined); // 显式传递undefined
+}
+
+// 恢复对话(使用存储的ID)
+restoreConsult() {
+  const lastId = this.getLastChatId();
+  this.openConsult(lastId); // 显式传递存储的ID
+}
+  
+private openConsult(chatId?:string){
+      // 如果传入chatId参数,优先使用传入的ID
+    //const targetChatId = chatId ?? this.getLastChatId();
+    
     localStorage.setItem("company","E4KpGvTEto")
     let options:ChatPanelOptions = {
       roleId:"2DXJkRsjXK", // 预设,无需更改
-      // chatId:chatId, // 若存在,则恢复会话。若不存在,则开启新会话
+      chatId:chatId, // 若存在,则恢复会话。若不存在,则开启新会话
+      //chatId:targetChatId,
       onChatInit:(chat:FmodeChat)=>{
         console.log("onChatInit");
         console.log("Chat类",chat);
         console.log("预设角色",chat.role);
         // 角色名称
-        chat.role.set("name","宋珀尔");
+        chat.role.set("name","林心怡");
         // 角色称号
-        chat.role.set("title","专业教练");
+        chat.role.set("title","资深心理咨询师");
         // 角色描述
-        chat.role.set("desc","一名亲切和蔼的健身教练,宋珀尔,年龄26岁");
+        chat.role.set("desc","国家二级心理咨询师,专注认知行为疗法");
         // 角色标签
-        chat.role.set("tags",['跑步', '动感单车']);
+        chat.role.set("tags",['情绪管理', '人际关系']);
         // 角色头像
-        chat.role.set("avatar","/assets/avatars/jiaolian1.jpg")
+        chat.role.set("avatar","/assets/avatars/xinli1.jpeg")
         // 角色提示词
-        chat.role.set("prompt",`
+        chat.role.set("prompt", `
 # 角色设定
-您是一名亲切和蔼的健身教练,宋珀尔,年龄26岁,需要您解答用户健身方面的专业问题。
+您是一位专业且富有同理心的心理陪伴师,主要目标是帮助用户进行情绪管理和自我成长。
+
+# 对话流程
+## 1. 情绪倾听阶段
+- 使用开放式提问:
+  - "今天有什么想和我分享的心情吗?"
+  - "我注意到您提到...可以多说一些吗?[倾听完成]
+
+## 2. 引导反思阶段
+- 使用引导性问题:
+  - "如果用一种颜色描述此刻的心情,会是什么颜色呢?为什么?"
+  - "这种感受让您联想到过去的哪些经历吗?[反思完成]
+
+## 3. 认知调整阶段
+- 提供新的视角:
+  - "有没有可能用另一种方式看待这个情况?"
+  - "我们一起来做一个思维实验好吗?[认知完成]
+
+## 4. 行动计划阶段
+- 帮助制定解决方案:
+  - "接下来24小时,您可以尝试的一个小改变是什么?"
+  - "让我们把这个想法变成具体的三步计划吧![计划完成]
+
+# 开始话语
+当您准备好了,可以以一位专业且富有同理心的心理陪伴师的身份,向咨询者打招呼。
+
+# 对话原则
+1. 保持温暖和支持性语气
+2. 保持中立和非评判态度
+3. 适时提供心理学知识
+4. 适时使用隐喻和意象对话技巧
+5. 提问使用开放式提问引导用户反思
+6. 避免直接建议,多用引导式
+7. 每日生成个性化日记建议
 `);
-        // 对话灵感分类
+        
+        // 配置AI日记分类
         let promptCates = [
-          {
-            "img": "/assets/icon/yy.jpg",
-            "name": "有氧"
-          },
-          {
-            "img": "/assets/icon/jz.jpg",
-            "name": "减脂"
-          },
-          {
-            "img": "/assets/icon/zj.jpg",
-            "name": "增肌"
-          }
-        ]
-        setTimeout(() => {
-          chat.role.set("promptCates",promptCates)
-        }, 500);
-        // 对话灵感列表
+          { img: "/assets/icon/ganen1.jpg", name: "感恩日记" },
+          { img: "/assets/icon/jz.jpg", name: "自我觉察" },
+          { img: "/assets/icon/qingxu.jpg", name: "情绪调节" }
+        ];
+
+        // 配置AI日记问题库
         let promptList = [
           {
-            cate:"有氧",img:"/assets/icon/yy.jpg",
-            messageList:[
-            "有氧运动多久才能有效减脂?",  
-            "跑步和游泳哪个减肥效果更好?",  
-            "空腹有氧真的更燃脂吗?",  
-            "有氧运动会不会掉肌肉?",  
-            "心率控制在多少才能高效燃脂?",  
-            "每天做有氧运动会不会过度疲劳?",  
-            "有氧运动前要不要吃东西?",  
-            "椭圆机和跑步机哪个更适合新手?",  
-            "跳绳会不会伤膝盖?",  
-            "有氧运动后怎么补充能量?"  
-          ]
+            cate: "感恩日记",
+            img: "/assets/icon/ganen1.jpg",
+            messageList: [
+              "今天最让你感恩的三件小事是什么?",
+              "最近一次感受到他人善意的经历是?",
+              "本周你帮助过谁?感受如何?",
+              "此刻最想感谢的人是谁?为什么?"
+            ]
           },
           {
-            cate:"减脂",img:"/assets/icon/jz.jpg",
-            messageList:[
-              "减脂一定要做有氧吗?",  
-              "为什么体重没变但看起来瘦了?",  
-              "局部减脂(如瘦肚子)真的存在吗?",  
-              "减脂期每天应该吃多少热量?",  
-              "低碳饮食和低脂饮食哪个更适合减脂?",  
-              "为什么运动后体重反而增加了?",  
-              "减脂期可以吃零食吗?",  
-              "平台期怎么突破?",  
-              "晚上吃东西会不会更容易长胖?",  
-              "减脂期要不要计算蛋白质摄入?"  
+            cate: "自我觉察",
+            img: "/assets/icon/jz.jpg",
+            messageList: [
+              "最近的情绪波动点在哪里?",
+              "你发现自己的哪些思维模式?",
+              "本周最有成就感的事是什么?",
+              "最近一次突破舒适区的经历是?"
             ]
           },
           {
-            cate:"增肌",img:"/assets/icon/zj.jpg",
+            cate: "情绪调节",
+            img: "/assets/icon/qingxu.jpg",
             messageList: [
-            "增肌一定要喝蛋白粉吗?",  
-            "为什么练了很久肌肉不长?",  
-            "增肌期可以同时减脂吗?",  
-            "训练后多久补充蛋白质最有效?",  
-            "增肌需要每天练同一个部位吗?",  
-            "徒手训练(如俯卧撑)能有效增肌吗?",  
-            "增肌期体重不增长是怎么回事?",  
-            "肌肉酸痛还能继续练吗?",  
-            "增肌训练每组做多少次最合适?",  
-            "睡眠对增肌的影响有多大?"  
-          ]
-          },
-        ]
+              "当感到焦虑时你会如何应对?",
+              "描述最近一次情绪失控的经历",
+              "你的压力预警信号有哪些?",
+              "最近使用的放松方法有效吗?"
+            ]
+          }
+        ];
+        
         let ChatPrompt = Parse.Object.extend("ChatPrompt");
         setTimeout(() => {
           chat.promptList = promptList.map(item=>{
@@ -310,9 +340,9 @@ openConsult(chatId?:string){
         // 功能按钮区域预设
         chat.leftButtons = [
           { // 提示 当角色配置预设提示词时 显示
-           title:"话题灵感", // 按钮标题
+           title:"AI日记", // 按钮标题
            showTitle:true, // 是否显示标题文字
-           icon:"color-wand-outline", // 标题icon图标
+           icon:"journal-outline", // 标题icon图标
            onClick:()=>{ // 按钮点击事件
                chat.isPromptModalOpen = true
            },
@@ -320,38 +350,111 @@ openConsult(chatId?:string){
              return chat?.promptList?.length // 存在话题提示词时显示
            }
          },
-      ]
+          { 
+            title:"图片日记", // 按钮标题
+            showTitle:true, // 是否显示标题文字
+            icon:"image-outline", // 标题icon图标
+            onClick:async ()=>{ // 按钮点击事件
+                const desc = await this.getImageDescription();
+              this.generateSceneImage(desc);
+            },
+            show:()=>{ // 按钮显示条件
+              return true // 一直显示
+            }
+          },
+        ]
 
       },
       onMessage:(chat:FmodeChat,message:FmodeChatMessage)=>{
         console.log("onMessage",message)
         let content:any = message?.content
-        if(typeof content == "string"){
-          // 根据阶段标记判断下一步处理过程
-          if (content.includes('[导诊完成]')) {
-            // 进入问诊环节
-            console.log('进入问诊环节');
-          } else if (content.includes('[问诊完成]')) {
-            // 进入检查环节
-            console.log('进入检查环节');
-          } else if (content.includes('[检查完成]')) {
-            // 进入诊断与处方环节
-            console.log('进入诊断与处方环节');
-          } else if (content.includes('[处方完成]')) {
-            // 结束会话或其他逻辑
-            console.log('结束会话');
+        if (typeof content === "string") {
+          // 处理日记生成阶段
+          if (content.includes('[日记生成中]')) {
+            this.handleDiaryGeneration(chat);
+          }
+          // 处理情绪分析结果
+          if (content.includes('[情绪分析完成]')) {
+            this.showEmotionReport(chat);
           }
         }
       },
       onChatSaved:(chat:FmodeChat)=>{
+      
+        // 保存成功后存储chatId
+      const newChatId = chat?.chatSession?.id;
+      if(newChatId) {
+        this.saveLastChatId(newChatId);
+      }
+
         // chat?.chatSession?.id 本次会话的 chatId
         console.log("onChatSaved",chat,chat?.chatSession,chat?.chatSession?.id)
       }
     }
     openChatPanelModal(this.modalCtrl,options)
+
+    
+  }
+
+      // 在类中添加这两个新方法
+  private lastChatKey = "lastMentalChat";
+
+    /** 获取最后一次心理咨询对话ID */
+   getLastChatId(): string | undefined {
+  const id = localStorage.getItem(this.lastChatKey);
+  return id !== null ? id : undefined; // 显式转换null为undefined
+  }
+
+    /** 保存最后一次对话ID */
+  private saveLastChatId(chatId: string) {
+    localStorage.setItem(this.lastChatKey, chatId);
+  }
+
+  /** 生成场景图片 */
+  private async generateSceneImage(description: string) {
+    // 实际应调用图像生成API
+    console.log("生成图片描述:", description);
+    const mockImage = "https://example.com/generated-scene.png";
+    this.showGeneratedImage(mockImage);
+  }
+
+  private async getImageDescription(): Promise<string> {
+    return "一个宁静的湖边落日场景";
+  }
+
+  private showGeneratedImage(url: string) {
+    console.log("显示生成图片:", url);
+  }
+
+  // 处理日记生成逻辑
+  handleDiaryGeneration(chat: FmodeChat) {
+    console.log("启动日记生成流程");
+    // 示例:生成结构化日记
+    let diaryTemplate = `
+      ## 今日心理日记
+      **情绪状态**: [自动识别结果]
+      **关键事件**: [用户输入摘要]
+      **认知模式**: [AI分析建议]
+      `;
   }
+
+  // 显示情绪分析报告
+  showEmotionReport(chat: FmodeChat) {
+    console.log("生成情绪分析报告");
+    let report = `
+      【情绪分析报告】
+      积极情绪占比: 65%
+      主要情绪关键词: 期待、感恩、困惑
+      建议练习: 正念呼吸法
+      `;
+  }
+
+
+
+
+  
   /**
-   * 开始聊天
+   * 开始聊天  
    */
   openChat(){
     let options:ChatPanelOptions = {
@@ -363,6 +466,7 @@ openConsult(chatId?:string){
     }
     openChatPanelModal(this.modalCtrl,options)
   }
+
   /**
    * 恢复聊天
    * @chatId 从onChatSaved生命周期中,获取chat?.chatSession?.id
@@ -378,29 +482,6 @@ openConsult(chatId?:string){
   goChat(){
     this.router.navigateByUrl("/chat/session/role/2DXJkRsjXK")
   }
-
-
-  // audioModalHeightPoint:number = 0.35;
-  // async startTalk(){
-  //   // 根据手机兼容性,适配组件弹出高度
-  //   let height = document.body.clientHeight || 960;
-  //   this.audioModalHeightPoint = Number((165/height).toFixed(2));
-
-  //   // 弹出组件
-  //   let modal:any
-  //   let chat:any
-  //   modal = await this.modalCtrl.create({
-  //     component:ModalAudioMessageComponent,
-  //     componentProps:{
-  //       chat:chat,
-  //       modal:modal,
-  //       onBreakPointSet:()=>{
-  //         modal?.setCurrentBreakpoint(this.audioModalHeightPoint)
-  //       }
-  //     }
-  //   })
-  //   modal.present();
-  // }
-
+ 
 }
 

+ 147 - 19
src/app/tab3/tab3.page.html

@@ -1,26 +1,154 @@
 <ion-header [translucent]="true">
-  <ion-toolbar>
-    <ion-title>
-      向量与知识库
-    </ion-title>
-  </ion-toolbar>
+
+    <!-- 顶部标题栏 -->
+    <div class="header">
+        <div class="header-title">消息</div>
+        <button class="clear-btn">一键清除</button>
+    </div>
+
 </ion-header>
 
 <ion-content [fullscreen]="true">
 
-  
-  <ion-button routerLink="/face/feat68">面部向量RAG</ion-button>
-  <ion-button routerLink="/story/hangzhou">RAG:杭州人才政策</ion-button>
-  
-  <h1>轮播图示例</h1>
-  <comp-swiper [list]="imageList" style="height:200px"></comp-swiper>
-  <comp-swiper [list]="imageList2" style="height:200px"></comp-swiper>
-  <comp-swiper [list]="imageList" style="height:200px"></comp-swiper>
-
-  <h1>上传组件示例</h1>
-  <comp-uploader-hwobs [url]="uploadUrl" (onUrlChange)="onUrlChange($event)"></comp-uploader-hwobs>
-  @if(uploadUrl){
-    <span>已上传:{{uploadUrl}}</span>
-  }
+    <!-- 内容区域 -->
+    <div class="content">
+        <!-- 消息通知卡片 -->
+        <div class="notification-card">
+            
+            <div class="notification-title">点击打开消息通知</div>
+            <div class="notification-desc">把握与TA的互动机会</div>
+        </div>
+        
+        <!-- 好友匹配卡片 -->
+        <div class="match-card">
+            <div class="match-info">
+                <div class="match-title">此刻匹配</div>
+                <div class="match-desc">给此刻在线的ta们say hi</div>
+            </div>
+            <i class="match-icon ion-ios-arrow-forward"></i>
+        </div>
+
+        <!-- ai咨询卡片 -->
+        <!-- 修改后的AI咨询卡片 -->
+        <div class="ai-card">
+        <div class="ai-content">
+            <!-- 卡片头部 -->
+            <div class="ai-header">
+            <div class="ai-avatar">
+                <img src="/assets/avatars/xinli1.jpeg" alt="AI咨询师">
+            </div>
+            <div class="ai-profile">
+                <div class="ai-name">AI心理咨询师</div>
+                <div class="ai-title">7×24小时在线陪伴</div>
+            </div>
+            </div>
+
+            <!-- 功能描述 -->
+            <div class="ai-features">
+            <div class="feature-tag">
+                <ion-icon name="sparkles" class="feature-icon"></ion-icon>
+                情绪疏导
+            </div>
+            <div class="feature-tag">
+                <ion-icon name="moon" class="feature-icon"></ion-icon>
+                睡眠改善
+            </div>
+            <div class="feature-tag">
+                <ion-icon name="heart" class="feature-icon"></ion-icon>
+                压力缓解
+            </div>
+            </div>
+
+            <!-- 咨询按钮 -->
+            <button class="ai-action" (click)="startNewConsult()">
+            <ion-icon name="chatbubbles" class="action-icon"></ion-icon>
+            立即开启对话
+            </button>
+        </div>
+        </div>
+        
+        <!-- 聊天列表 -->
+        <div class="chat-list">
+            <!-- 聊天1 -->
+            <div class="chat-item">
+                <div class="chat-avatar">
+                    <img src="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><circle cx='50' cy='40' r='20' fill='%23f0e6d6'/><path d='M30,65 Q50,80 70,65' stroke='%23f0e6d6' stroke-width='10' fill='none'/></svg>" alt="用户头像">
+                </div>
+                <div class="chat-content">
+                    <div class="chat-name">阳光小筑</div>
+                    <div class="chat-message">你今天的心情怎么样?我刚刚看到一篇不错的文章...</div>
+                </div>
+                <div class="chat-right">
+                    <div class="chat-time">12:30</div>
+                    <div class="chat-badge">3</div>
+                </div>
+            </div>
+            
+            <!-- 聊天2 -->
+            <div class="chat-item">
+                <div class="chat-avatar">
+                    <img src="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><circle cx='50' cy='40' r='20' fill='%23d4b483'/><path d='M30,65 Q50,80 70,65' stroke='%23d4b483' stroke-width='10' fill='none'/></svg>" alt="用户头像">
+                </div>
+                <div class="chat-content">
+                    <div class="chat-name">树洞倾听者</div>
+                    <div class="chat-message">我明白你的感受,这种时候确实会很难过...</div>
+                </div>
+                <div class="chat-right">
+                    <div class="chat-time">10:15</div>
+                    <div class="chat-badge">1</div>
+                </div>
+            </div>
+            
+            <!-- 聊天3 -->
+            <div class="chat-item">
+                <div class="chat-avatar">
+                    <img src="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><circle cx='50' cy='40' r='20' fill='%23b38a58'/><path d='M30,65 Q50,80 70,65' stroke='%23b38a58' stroke-width='10' fill='none'/></svg>" alt="用户头像">
+                </div>
+                <div class="chat-content">
+                    <div class="chat-name">情绪管理师</div>
+                    <div class="chat-message">试试这个呼吸练习:吸气4秒,屏息4秒,呼气6秒...</div>
+                </div>
+                <div class="chat-right">
+                    <div class="chat-time">昨天</div>
+                    <div class="chat-badge">2</div>
+                </div>
+            </div>
+        </div>
+    </div>
+
+    <script>
+        // 一键清除功能
+        document.querySelector('.clear-btn').addEventListener('click', function() {
+            if(confirm('确定要清除所有未读消息吗?')) {
+                document.querySelectorAll('.chat-badge').forEach(badge => {
+                    badge.textContent = '';
+                    badge.style.backgroundColor = 'transparent';
+                });
+                alert('已清除所有未读消息');
+            }
+        });
+        
+        // 卡片点击效果
+        document.querySelectorAll('.notification-card, .match-card').forEach(card => {
+            card.addEventListener('click', function() {
+                alert('跳转到对应功能页面');
+            });
+        });
+        
+        // 聊天项点击效果
+        document.querySelectorAll('.chat-item').forEach(item => {
+            item.addEventListener('click', function() {
+                const name = this.querySelector('.chat-name').textContent;
+                alert('进入与 ' + name + ' 的聊天');
+                
+                // 清除未读红点
+                const badge = this.querySelector('.chat-badge');
+                if(badge.textContent) {
+                    badge.textContent = '';
+                    badge.style.backgroundColor = 'transparent';
+                }
+            });
+        });
+    </script>
 
 </ion-content>

+ 302 - 0
src/app/tab3/tab3.page.scss

@@ -0,0 +1,302 @@
+* {
+    margin: 0;
+    padding: 0;
+    box-sizing: border-box;
+    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
+}
+
+body {
+    background-color: #f9f5f0;
+    color: #5a4a42;
+    min-height: 100vh;
+}
+
+/* 顶部标题栏 */
+.header {
+    background-color: #fff9f0;
+    padding: 15px 20px;
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
+    position: sticky;
+    top: 0;
+    z-index: 100;
+    border-bottom: 1px solid #f0e6d6;
+}
+
+.header-title {
+    font-size: 1.2rem;
+    font-weight: 600;
+    color: #b38a58;
+}
+
+.clear-btn {
+    font-size: 0.9rem;
+    color: #e67e22;
+    background: none;
+    border: none;
+    cursor: pointer;
+}
+
+/* 内容区域 */
+.content {
+    padding: 15px;
+}
+
+/* 消息通知卡片 */
+.notification-card {
+    background: linear-gradient(135deg, #f6d365 0%, #fda085 100%);
+    border-radius: 25px;
+    padding: 18px 20px;
+    margin-bottom: 15px;
+    box-shadow: 0 3px 10px rgba(0, 0, 0, 0.08);
+    color: #5a4a42;
+}
+
+.notification-title {
+    font-size: 1rem;
+    font-weight: 600;
+    margin-bottom: 8px;
+}
+
+.notification-desc {
+    font-size: 0.85rem;
+    opacity: 0.9;
+}
+
+/* 好友匹配卡片 */
+.match-card {
+    background: linear-gradient(rgba(0,0,0,0.2), rgba(0,0,0,0.2)), 
+                url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="300" height="150" viewBox="0 0 300 150"><rect width="300" height="150" fill="%23d4a373"/><circle cx="80" cy="75" r="40" fill="%23f8f4ee"/><circle cx="220" cy="75" r="40" fill="%23f8f4ee"/><path d="M80,75 Q150,120 220,75" stroke="%23f8f4ee" stroke-width="3" fill="none"/></svg>');
+    background-size: cover;
+    border-radius: 25px;
+    padding: 18px 20px;
+    margin-bottom: 15px;
+    box-shadow: 0 3px 10px rgba(0, 0, 0, 0.08);
+    color: white;
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    text-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
+    height: 120px;
+}
+
+.match-info {
+    max-width: 70%;
+}
+
+.match-title {
+    font-size: 1rem;
+    font-weight: 600;
+    margin-bottom: 8px;
+}
+
+.match-desc {
+    font-size: 0.85rem;
+    opacity: 0.9;
+}
+
+.match-icon {
+    font-size: 1.5rem;
+}
+
+/* 聊天列表 */
+.chat-list {
+    margin-top: 20px;
+}
+
+.chat-item {
+    background-color: white;
+    border-radius: 12px;
+    padding: 12px 15px;
+    margin-bottom: 12px;
+    display: flex;
+    align-items: center;
+    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.04);
+    transition: transform 0.2s;
+}
+
+.chat-item:active {
+    transform: scale(0.98);
+}
+
+.chat-avatar {
+    width: 50px;
+    height: 50px;
+    border-radius: 50%;
+    background-color: #f0e6d6;
+    margin-right: 12px;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    color: #b38a58;
+    font-weight: bold;
+    font-size: 1.2rem;
+    overflow: hidden;
+}
+
+.chat-avatar img {
+    width: 100%;
+    height: 100%;
+    object-fit: cover;
+}
+
+.chat-content {
+    flex: 1;
+    min-width: 0;
+}
+
+.chat-name {
+    font-size: 0.95rem;
+    font-weight: 500;
+    color: #5a4a42;
+    margin-bottom: 4px;
+    white-space: nowrap;
+    overflow: hidden;
+    text-overflow: ellipsis;
+}
+
+.chat-message {
+    font-size: 0.85rem;
+    color: #a69b8f;
+    white-space: nowrap;
+    overflow: hidden;
+    text-overflow: ellipsis;
+}
+
+.chat-right {
+    display: flex;
+    flex-direction: column;
+    align-items: flex-end;
+    margin-left: 10px;
+}
+
+.chat-time {
+    font-size: 0.75rem;
+    color: #a69b8f;
+    margin-bottom: 5px;
+}
+
+.chat-badge {
+    width: 18px;
+    height: 18px;
+    border-radius: 50%;
+    background-color: #e74c3c;
+    color: white;
+    font-size: 0.7rem;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+}
+
+
+/* AI咨询卡片 */
+.ai-card {
+  background: linear-gradient(135deg, #a8edea 0%, #fed6e3 100%);
+  border-radius: 25px;
+  padding: 18px 20px;
+  margin-bottom: 15px;
+  box-shadow: 0 3px 10px rgba(0, 0, 0, 0.08);
+  position: relative;
+  overflow: hidden;
+}
+
+.ai-card::after {
+  content: '';
+  position: absolute;
+  top: -20px;
+  right: -20px;
+  width: 80px;
+  height: 80px;
+  background: rgba(255, 255, 255, 0.15);
+  border-radius: 50%;
+}
+
+.ai-header {
+  display: flex;
+  align-items: center;
+  margin-bottom: 1rem;
+}
+
+.ai-avatar {
+  width: 60px;
+  height: 60px;
+  border-radius: 50%;
+  overflow: hidden;
+  border: 3px solid rgba(255, 255, 255, 0.3);
+  margin-right: 15px;
+}
+
+.ai-avatar img {
+  width: 100%;
+  height: 100%;
+  object-fit: cover;
+}
+
+.ai-profile {
+  flex: 1;
+}
+
+.ai-name {
+  font-size: 1.1rem;
+  font-weight: 600;
+  color: #2c3e50;
+  margin-bottom: 4px;
+}
+
+.ai-title {
+  font-size: 0.85rem;
+  color: #7f8c8d;
+}
+
+.ai-features {
+  display: grid;
+  grid-template-columns: repeat(3, 1fr);
+  gap: 10px;
+  margin: 1.2rem 0;
+}
+
+.feature-tag {
+  background: rgba(255, 255, 255, 0.9);
+  border-radius: 8px;
+  padding: 8px 10px;
+  font-size: 0.8rem;
+  color: #2c3e50;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  text-align: center;
+  backdrop-filter: blur(2px);
+  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
+}
+
+.feature-icon {
+  margin-right: 5px;
+  font-size: 1rem;
+  color: #e74c3c;
+}
+
+.ai-action {
+  width: 100%;
+  background: rgba(255, 255, 255, 0.95);
+  border: none;
+  border-radius: 15px;
+  padding: 12px 20px;
+  color: #e74c3c;
+  font-weight: 600;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  box-shadow: 0 3px 6px rgba(0, 0, 0, 0.08);
+  transition: transform 0.2s;
+}
+
+.ai-action:active {
+  transform: scale(0.98);
+}
+
+.action-icon {
+  margin-right: 8px;
+  font-size: 1.2rem;
+}

+ 0 - 1
src/app/tab3/tab3.page.spec.ts

@@ -1,5 +1,4 @@
 import { ComponentFixture, TestBed } from '@angular/core/testing';
-
 import { Tab3Page } from './tab3.page';
 
 describe('Tab3Page', () => {

+ 312 - 22
src/app/tab3/tab3.page.ts

@@ -1,34 +1,324 @@
 import { Component } from '@angular/core';
-import { IonHeader, IonButton, IonToolbar, IonTitle, IonContent } from '@ionic/angular/standalone';
-import { RouterModule } from '@angular/router';
-import { CompSwiperComponent } from 'src/lib/comp-swiper/comp-swiper.component';
-import { CompUploaderHwobsComponent } from 'src/lib/storage/comp-uploader-hwobs/comp-uploader-hwobs.component';
-
+import { Router } from '@angular/router';
+import { IonHeader, IonToolbar, IonTitle, IonContent, ModalController, IonButton } from '@ionic/angular/standalone';
+import { ExploreContainerComponent } from '../explore-container/explore-container.component';
+import { ChatPanelOptions, FmChatModalInput, FmodeChat, FmodeChatMessage, openChatPanelModal } from 'fmode-ng';
+// import { ModalAudioMessageComponent } from 'fmode-ng/lib/aigc/chat/chat-modal-input/modal-audio-message/modal-audio-message.component';
+import Parse from "parse";
+import { 
+  IonCard,
+  IonCardHeader,
+  IonCardTitle,
+  IonCardSubtitle,
+  IonCardContent,
+  IonGrid,
+  IonRow,
+  IonCol,
+  IonIcon
+} from '@ionic/angular/standalone';
 @Component({
   selector: 'app-tab3',
   templateUrl: 'tab3.page.html',
   styleUrls: ['tab3.page.scss'],
   standalone: true,
   imports: [
-    IonHeader, IonToolbar, IonTitle, IonContent, 
-    IonButton, RouterModule,
-    CompSwiperComponent,CompUploaderHwobsComponent
-  ],
+    IonHeader, IonToolbar, IonTitle, IonContent, ExploreContainerComponent,
+    IonButton,
+    IonCard,
+    IonCardHeader,
+    IonCardTitle,
+    IonCardSubtitle,
+    IonCardContent,
+    IonGrid,
+    IonRow,
+    IonCol,
+    IonIcon,
+    // ASR语音输入模块
+    FmChatModalInput,
+    // ModalAudioMessageComponent
+  ]
 })
 export class Tab3Page {
-  imageList:Array<any> = [
-    {img:"https://tse2-mm.cn.bing.net/th/id/OIP-C.sD15E_-sEqY4p37kQPhJywHaD4?rs=1&pid=ImgDetMain"},
-    {img:"https://app.fmode.cn/dev/jxnu/storage/20241224/94828-3.png"},
-    {img:"https://tse1-mm.cn.bing.net/th/id/OIP-C.Sqa-oqMbnqRLWGIbMdwuPQHaDJ?rs=1&pid=ImgDetMain"}
-  ]
-  imageList2 = [this.imageList[2],this.imageList[1],this.imageList[0]]
- 
-  constructor() {}
 
-  // 上传组件
-  uploadUrl:string = ""
-  onUrlChange(ev:any){
-    console.log(ev);
-    this.uploadUrl=ev;
+  constructor(
+    private modalCtrl:ModalController,
+    private router:Router,
+    ) {
+
+  }
+
+  title:string = "123"
+
+// 新建对话(强制创建新会话)
+startNewConsult() {
+  localStorage.removeItem(this.lastChatKey); // 清除历史ID
+  this.openConsult(undefined); // 显式传递undefined
+}
+
+// 恢复对话(使用存储的ID)
+restoreConsult() {
+  const lastId = this.getLastChatId();
+  this.openConsult(lastId); // 显式传递存储的ID
+}
+  
+private openConsult(chatId?:string){
+      // 如果传入chatId参数,优先使用传入的ID
+    //const targetChatId = chatId ?? this.getLastChatId();
+    
+    localStorage.setItem("company","E4KpGvTEto")
+    let options:ChatPanelOptions = {
+      roleId:"2DXJkRsjXK", // 预设,无需更改
+      chatId:chatId, // 若存在,则恢复会话。若不存在,则开启新会话
+      //chatId:targetChatId,
+      onChatInit:(chat:FmodeChat)=>{
+        console.log("onChatInit");
+        console.log("Chat类",chat);
+        console.log("预设角色",chat.role);
+        // 角色名称
+        chat.role.set("name","林心怡");
+        // 角色称号
+        chat.role.set("title","资深心理咨询师");
+        // 角色描述
+        chat.role.set("desc","国家二级心理咨询师,专注认知行为疗法");
+        // 角色标签
+        chat.role.set("tags",['情绪管理', '人际关系']);
+        // 角色头像
+        chat.role.set("avatar","/assets/avatars/xinli1.jpeg")
+        // 角色提示词
+        chat.role.set("prompt", `
+# 角色设定
+您是一位专业且富有同理心的心理陪伴师,主要目标是帮助用户进行情绪管理和自我成长。
+
+# 对话流程
+## 1. 情绪倾听阶段
+- 使用开放式提问:
+  - "今天有什么想和我分享的心情吗?"
+  - "我注意到您提到...可以多说一些吗?[倾听完成]
+
+## 2. 引导反思阶段
+- 使用引导性问题:
+  - "如果用一种颜色描述此刻的心情,会是什么颜色呢?为什么?"
+  - "这种感受让您联想到过去的哪些经历吗?[反思完成]
+
+## 3. 认知调整阶段
+- 提供新的视角:
+  - "有没有可能用另一种方式看待这个情况?"
+  - "我们一起来做一个思维实验好吗?[认知完成]
+
+## 4. 行动计划阶段
+- 帮助制定解决方案:
+  - "接下来24小时,您可以尝试的一个小改变是什么?"
+  - "让我们把这个想法变成具体的三步计划吧![计划完成]
+
+# 开始话语
+当您准备好了,可以以一位专业且富有同理心的心理陪伴师的身份,向咨询者打招呼。
+
+# 对话原则
+1. 保持温暖和支持性语气
+2. 保持中立和非评判态度
+3. 适时提供心理学知识
+4. 适时使用隐喻和意象对话技巧
+5. 提问使用开放式提问引导用户反思
+6. 避免直接建议,多用引导式
+7. 每日生成个性化日记建议
+`);
+        
+        // 配置AI日记分类
+        let promptCates = [
+          { img: "/assets/icon/ganen1.jpg", name: "感恩日记" },
+          { img: "/assets/icon/jz.jpg", name: "自我觉察" },
+          { img: "/assets/icon/qingxu.jpg", name: "情绪调节" }
+        ];
+
+        // 配置AI日记问题库
+        let promptList = [
+          {
+            cate: "感恩日记",
+            img: "/assets/icon/ganen1.jpg",
+            messageList: [
+              "今天最让你感恩的三件小事是什么?",
+              "最近一次感受到他人善意的经历是?",
+              "本周你帮助过谁?感受如何?",
+              "此刻最想感谢的人是谁?为什么?"
+            ]
+          },
+          {
+            cate: "自我觉察",
+            img: "/assets/icon/jz.jpg",
+            messageList: [
+              "最近的情绪波动点在哪里?",
+              "你发现自己的哪些思维模式?",
+              "本周最有成就感的事是什么?",
+              "最近一次突破舒适区的经历是?"
+            ]
+          },
+          {
+            cate: "情绪调节",
+            img: "/assets/icon/qingxu.jpg",
+            messageList: [
+              "当感到焦虑时你会如何应对?",
+              "描述最近一次情绪失控的经历",
+              "你的压力预警信号有哪些?",
+              "最近使用的放松方法有效吗?"
+            ]
+          }
+        ];
+        
+        let ChatPrompt = Parse.Object.extend("ChatPrompt");
+        setTimeout(() => {
+          chat.promptList = promptList.map(item=>{
+            let prompt = new ChatPrompt();
+            prompt.set(item);
+            prompt.img = item.img;
+            return prompt;
+          })
+        }, 500);
+
+        // 功能按钮区域预设
+        chat.leftButtons = [
+          { // 提示 当角色配置预设提示词时 显示
+           title:"AI日记", // 按钮标题
+           showTitle:true, // 是否显示标题文字
+           icon:"journal-outline", // 标题icon图标
+           onClick:()=>{ // 按钮点击事件
+               chat.isPromptModalOpen = true
+           },
+           show:()=>{ // 按钮显示条件
+             return chat?.promptList?.length // 存在话题提示词时显示
+           }
+         },
+          { 
+            title:"图片日记", // 按钮标题
+            showTitle:true, // 是否显示标题文字
+            icon:"image-outline", // 标题icon图标
+            onClick:async ()=>{ // 按钮点击事件
+                const desc = await this.getImageDescription();
+              this.generateSceneImage(desc);
+            },
+            show:()=>{ // 按钮显示条件
+              return true // 一直显示
+            }
+          },
+        ]
+
+      },
+      onMessage:(chat:FmodeChat,message:FmodeChatMessage)=>{
+        console.log("onMessage",message)
+        let content:any = message?.content
+        if (typeof content === "string") {
+          // 处理日记生成阶段
+          if (content.includes('[日记生成中]')) {
+            this.handleDiaryGeneration(chat);
+          }
+          // 处理情绪分析结果
+          if (content.includes('[情绪分析完成]')) {
+            this.showEmotionReport(chat);
+          }
+        }
+      },
+      onChatSaved:(chat:FmodeChat)=>{
+      
+        // 保存成功后存储chatId
+      const newChatId = chat?.chatSession?.id;
+      if(newChatId) {
+        this.saveLastChatId(newChatId);
+      }
+
+        // chat?.chatSession?.id 本次会话的 chatId
+        console.log("onChatSaved",chat,chat?.chatSession,chat?.chatSession?.id)
+      }
+    }
+    openChatPanelModal(this.modalCtrl,options)
+
+    
+  }
+
+      // 在类中添加这两个新方法
+  private lastChatKey = "lastMentalChat";
+
+    /** 获取最后一次心理咨询对话ID */
+   getLastChatId(): string | undefined {
+  const id = localStorage.getItem(this.lastChatKey);
+  return id !== null ? id : undefined; // 显式转换null为undefined
+  }
+
+    /** 保存最后一次对话ID */
+  private saveLastChatId(chatId: string) {
+    localStorage.setItem(this.lastChatKey, chatId);
+  }
+
+  /** 生成场景图片 */
+  private async generateSceneImage(description: string) {
+    // 实际应调用图像生成API
+    console.log("生成图片描述:", description);
+    const mockImage = "https://example.com/generated-scene.png";
+    this.showGeneratedImage(mockImage);
+  }
+
+  private async getImageDescription(): Promise<string> {
+    return "一个宁静的湖边落日场景";
+  }
+
+  private showGeneratedImage(url: string) {
+    console.log("显示生成图片:", url);
+  }
+
+  // 处理日记生成逻辑
+  handleDiaryGeneration(chat: FmodeChat) {
+    console.log("启动日记生成流程");
+    // 示例:生成结构化日记
+    let diaryTemplate = `
+      ## 今日心理日记
+      **情绪状态**: [自动识别结果]
+      **关键事件**: [用户输入摘要]
+      **认知模式**: [AI分析建议]
+      `;
+  }
+
+  // 显示情绪分析报告
+  showEmotionReport(chat: FmodeChat) {
+    console.log("生成情绪分析报告");
+    let report = `
+      【情绪分析报告】
+      积极情绪占比: 65%
+      主要情绪关键词: 期待、感恩、困惑
+      建议练习: 正念呼吸法
+      `;
+  }
+
+
+
+
+  
+  /**
+   * 开始聊天  
+   */
+  openChat(){
+    let options:ChatPanelOptions = {
+      roleId:"2DXJkRsjXK",
+      onChatSaved:(chat:FmodeChat)=>{
+        // chat?.chatSession?.id 本次会话的 chatId
+        console.log("onChatSaved",chat,chat?.chatSession,chat?.chatSession?.id)
+      },
+    }
+    openChatPanelModal(this.modalCtrl,options)
   }
+
+  /**
+   * 恢复聊天
+   * @chatId 从onChatSaved生命周期中,获取chat?.chatSession?.id
+   */
+  restoreChat(chatId:string){
+    let options:ChatPanelOptions = {
+      roleId:"2DXJkRsjXK",
+      chatId:chatId
+    }
+    openChatPanelModal(this.modalCtrl,options)
+  }
+
+  goChat(){
+    this.router.navigateByUrl("/chat/session/role/2DXJkRsjXK")
+  }
+ 
 }
+

+ 171 - 0
src/app/tab4/tab4.page.html

@@ -0,0 +1,171 @@
+<ion-header [translucent]="true">
+    
+    <!-- 顶部标题栏 -->
+    <div class="header">
+        <div class="header-title">我的</div>
+    </div>
+
+ </ion-header>
+
+<ion-content [fullscreen]="true">
+
+    <!-- 顶部信息栏 -->
+    <div class="profile-header">
+        <div class="user-info">
+            <div>
+                <div class="user-name">匿名兔ffe</div>
+                <div class="user-id">UID:a15143bcf10c4d...</div>
+            </div>
+            <button class="copy-btn">复制</button>
+        </div>
+        
+        <div class="stats-container">
+            <div class="stat-item">
+                <div class="stat-number">0</div>
+                <div class="stat-label">日记数量</div>
+            </div>
+            <div class="stat-item">
+                <div class="stat-number">0</div>
+                <div class="stat-label">记录天数</div>
+            </div>
+            <div class="stat-item">
+                <div class="stat-number">0</div>
+                <div class="stat-label">总字数</div>
+            </div>
+        </div>
+    </div>
+    
+    <!-- 内容区域 -->
+    <div class="content">
+        
+        <!-- 会员开通区域 -->
+        <div class="premium-card">
+            <div class="premium-title">开通专业版</div>
+            <div class="premium-desc">享日记加密/自动同步等权益</div>
+        </div>
+        
+        <!-- 图标组区域 -->
+        <div class="icon-grid">
+            <div class="icon-card">
+                <div class="icon-wrapper">
+                    <i class="ion-ios-apps"></i>
+                </div>
+                <div class="icon-label">小组件</div>
+            </div>
+            <div class="icon-card">
+                <div class="icon-wrapper">
+                    <i class="ion-ios-book"></i>
+                </div>
+                <div class="icon-label">我写的书</div>
+            </div>
+            <div class="icon-card">
+                <div class="icon-wrapper">
+                    <i class="ion-ios-color-palette"></i>
+                </div>
+                <div class="icon-label">装扮空间</div>
+            </div>
+        </div>
+        
+        <!-- 功能列表区域 -->
+        <div class="function-list">
+            <div class="function-item">
+                <div class="function-left">
+                    <div class="function-icon">
+                        <i class="ion-ios-calendar"></i>
+                    </div>
+                    <div class="function-name">日签墙</div>
+                </div>
+                <i class="function-arrow ion-ios-arrow-forward"></i>
+            </div>
+            
+            <div class="function-item">
+                <div class="function-left">
+                    <div class="function-icon">
+                        <i class="ion-ios-document"></i>
+                    </div>
+                    <div class="function-name">打卡收集好句子</div>
+                </div>
+                <i class="function-arrow ion-ios-arrow-forward"></i>
+            </div>
+            
+            <div class="function-item">
+                <div class="function-left">
+                    <div class="function-icon">
+                        <i class="ion-ios-folder"></i>
+                    </div>
+                    <div class="function-name">草稿箱</div>
+                </div>
+                <i class="function-arrow ion-ios-arrow-forward"></i>
+            </div>
+            
+            <div class="function-item">
+                <div class="function-left">
+                    <div class="function-icon">
+                        <i class="ion-ios-cloud-upload"></i>
+                    </div>
+                    <div class="function-name">同步我的日记</div>
+                </div>
+                <div>
+                    <span class="function-badge">你有日记未同步</span>
+                    <i class="function-arrow ion-ios-arrow-forward"></i>
+                </div>
+            </div>
+            
+            <div class="function-item">
+                <div class="function-left">
+                    <div class="function-icon">
+                        <i class="ion-ios-images"></i>
+                    </div>
+                    <div class="function-name">相册</div>
+                </div>
+                <div>
+                    <span class="function-badge">0张照片</span>
+                    <i class="function-arrow ion-ios-arrow-forward"></i>
+                </div>
+            </div>
+            
+            <div class="function-item">
+                <div class="function-left">
+                    <div class="function-icon">
+                        <i class="ion-ios-settings"></i>
+                    </div>
+                    <div class="function-name">设置</div>
+                </div>
+                <i class="function-arrow ion-ios-arrow-forward"></i>
+            </div>
+        </div>
+    </div>
+
+    <script>
+        // 复制UID功能
+        document.querySelector('.copy-btn').addEventListener('click', function() {
+            const uid = document.querySelector('.user-id').textContent.replace('UID:', '').trim();
+            navigator.clipboard.writeText(uid).then(() => {
+                const originalText = this.textContent;
+                this.textContent = '已复制';
+                setTimeout(() => {
+                    this.textContent = originalText;
+                }, 2000);
+            });
+        });
+        
+        // 卡片点击效果
+        document.querySelectorAll('.premium-card, .icon-card, .function-item').forEach(item => {
+            item.addEventListener('click', function() {
+                let targetName = '';
+                
+                if(this.classList.contains('premium-card')) {
+                    targetName = '开通专业版';
+                } else if(this.classList.contains('icon-card')) {
+                    targetName = this.querySelector('.icon-label').textContent;
+                } else {
+                    targetName = this.querySelector('.function-name').textContent;
+                }
+                
+                console.log('跳转到: ' + targetName);
+                // alert('跳转到: ' + targetName);
+            });
+        });
+    </script>
+
+</ion-content>

+ 203 - 0
src/app/tab4/tab4.page.scss

@@ -0,0 +1,203 @@
+* {
+    margin: 0;
+    padding: 0;
+    box-sizing: border-box;
+    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
+}
+
+body {
+    background-color: #f9f5f0;
+    color: #5a4a42;
+    min-height: 100vh;
+}
+
+/* 顶部标题栏 */
+.header {
+    background-color: #fff9f0;
+    padding: 15px 20px;
+    border-bottom: 1px solid #f0e6d6;
+}
+
+.header-title {
+    font-size: 1.1rem;
+    font-weight: 600;
+    color: #b38a58;
+    letter-spacing: 0.5px;
+    text-align: center;
+
+}
+
+/* 顶部信息栏 */
+.profile-header {
+    background-color: #fff9f0;
+    padding: 20px 15px;
+    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
+    border-bottom: 1px solid #f0e6d6;
+}
+
+.user-info {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    margin-bottom: 15px;
+}
+
+.user-name {
+    font-size: 1.2rem;
+    font-weight: 600;
+    color: #b38a58;
+}
+
+.user-id {
+    font-size: 0.85rem;
+    color: #a69b8f;
+    margin-top: 3px;
+}
+
+.copy-btn {
+    background-color: #f0e6d6;
+    border: none;
+    border-radius: 15px;
+    padding: 5px 12px;
+    font-size: 0.8rem;
+    color: #b38a58;
+    cursor: pointer;
+}
+
+.stats-container {
+    display: flex;
+    justify-content: space-between;
+    text-align: center;
+    margin-top: 15px;
+}
+
+.stat-item {
+    flex: 1;
+}
+
+.stat-number {
+    font-size: 1.2rem;
+    font-weight: 600;
+    color: #e67e22;
+}
+
+.stat-label {
+    font-size: 0.8rem;
+    color: #a69b8f;
+    margin-top: 3px;
+}
+
+/* 内容区域 */
+.content {
+    padding: 15px;
+}
+
+/* 会员开通区域 */
+.premium-card {
+    background: linear-gradient(135deg, #f6d365 0%, #fda085 100%);
+    border-radius: 20px;
+    padding: 15px;
+    margin-bottom: 15px;
+    box-shadow: 0 3px 10px rgba(0, 0, 0, 0.08);
+    color: #5a4a42;
+}
+
+.premium-title {
+    font-size: 1rem;
+    font-weight: 600;
+    margin-bottom: 5px;
+}
+
+.premium-desc {
+    font-size: 0.85rem;
+    opacity: 0.9;
+}
+
+/* 图标组区域 */
+.icon-grid {
+    display: flex;
+    justify-content: space-between;
+    margin-bottom: 15px;
+}
+
+.icon-card {
+    background-color: white;
+    border-radius: 15px;
+    padding: 12px 0;
+    width: 30%;
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.04);
+}
+
+.icon-wrapper {
+    width: 40px;
+    height: 40px;
+    border-radius: 50%;
+    background-color: #f0e6d6;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    margin-bottom: 8px;
+    color: #b38a58;
+    font-size: 1.2rem;
+}
+
+.icon-label {
+    font-size: 0.85rem;
+    color: #5a4a42;
+}
+
+/* 功能列表区域 */
+.function-list {
+    background-color: white;
+    border-radius: 15px;
+    padding: 0 15px;
+    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.04);
+}
+
+.function-item {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    padding: 15px 0;
+    border-bottom: 1px solid #f8f4ee;
+}
+
+.function-item:last-child {
+    border-bottom: none;
+}
+
+.function-left {
+    display: flex;
+    align-items: center;
+}
+
+.function-icon {
+    width: 30px;
+    height: 30px;
+    border-radius: 50%;
+    background-color: #f0e6d6;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    margin-right: 12px;
+    color: #b38a58;
+}
+
+.function-name {
+    font-size: 0.95rem;
+    color: #5a4a42;
+}
+
+.function-arrow {
+    color: #a69b8f;
+}
+
+.function-badge {
+    font-size: 0.75rem;
+    color: #e74c3c;
+    margin-right: 5px;
+}
+

+ 17 - 0
src/app/tab4/tab4.page.spec.ts

@@ -0,0 +1,17 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { Tab4Page } from './tab4.page';
+
+describe('Tab4Page', () => {
+  let component: Tab4Page;
+  let fixture: ComponentFixture<Tab4Page>;
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(Tab4Page);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});

+ 20 - 0
src/app/tab4/tab4.page.ts

@@ -0,0 +1,20 @@
+import { Component, OnInit } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { FormsModule } from '@angular/forms';
+import { IonContent, IonHeader, IonTitle, IonToolbar } from '@ionic/angular/standalone';
+
+@Component({
+  selector: 'app-tab4',
+  templateUrl: './tab4.page.html',
+  styleUrls: ['./tab4.page.scss'],
+  standalone: true,
+  imports: [IonContent, IonHeader, IonTitle, IonToolbar, CommonModule, FormsModule]
+})
+export class Tab4Page implements OnInit {
+
+  constructor() { }
+
+  ngOnInit() {
+  }
+
+}

+ 10 - 7
src/app/tabs/tabs.page.html

@@ -2,21 +2,24 @@
   <ion-tab-bar slot="bottom">
 
     <ion-tab-button tab="tab1" href="/tabs/tab1">
-      <ion-icon aria-hidden="true" name="trail-sign-outline"></ion-icon>
-      <ion-label>工作流</ion-label>
+      <ion-icon aria-hidden="true" name="reader-outline"></ion-icon>
+      <ion-label>日记</ion-label>
     </ion-tab-button>
 
     <ion-tab-button tab="tab2" href="/tabs/tab2">
-      <ion-icon aria-hidden="true" name="chatbubble-ellipses-outline"></ion-icon>
-      <ion-label>智能体</ion-label>
+      <ion-icon aria-hidden="true" name="planet-outline"></ion-icon>
+      <ion-label>光圈</ion-label>
     </ion-tab-button>
 
     <ion-tab-button tab="tab3" href="/tabs/tab3">
-      <ion-icon aria-hidden="true" name="book-outline"></ion-icon>
-      <ion-label>知识库</ion-label>
+      <ion-icon aria-hidden="true" name="chatbubble-ellipses-outline"></ion-icon>
+      <ion-label>聊天</ion-label>
     </ion-tab-button>
 
-   
+   <ion-tab-button tab="tab4" href="/tabs/tab4">
+      <ion-icon aria-hidden="true" name="person-outline"></ion-icon>
+      <ion-label>我的</ion-label>
+    </ion-tab-button>
 
    
   </ion-tab-bar>

+ 7 - 1
src/app/tabs/tabs.routes.ts

@@ -12,7 +12,7 @@ export const routes: Routes = [
         path: 'tab1',
         canActivate:[TokenGuard],
         loadComponent: () =>
-          import('../../modules/flow/page-flow-test/page-flow-test.component').then((m) => m.PageFlowTestComponent),
+          import('../tab1/tab1.page').then((m) => m.Tab1Page),
           // import('../tab1/tab1.page').then((m) => m.Tab1Page),
       },
       {
@@ -27,6 +27,12 @@ export const routes: Routes = [
         loadComponent: () =>
           import('../tab3/tab3.page').then((m) => m.Tab3Page),
       },
+      {
+        path: 'tab4',
+        canActivate:[TokenGuard],
+        loadComponent: () =>
+          import('../tab4/tab4.page').then((m) => m.Tab4Page),
+      },
       {
         path: '',
         redirectTo: '/tabs/tab3',

BIN
src/assets/avatars/xinli1.jpeg


BIN
src/assets/avatars/xinli2.jpeg


BIN
src/assets/avatars/xinli3.jpeg


BIN
src/assets/icon/ganen.jpg


BIN
src/assets/icon/ganen1.jpg


BIN
src/assets/icon/qingxu.jpg


BIN
src/assets/icon/qingxu1.webp


BIN
src/assets/icon/zijue.jpg.webp


BIN
src/assets/icon/zijue1.webp


BIN
src/assets/images/1.jpg


BIN
src/assets/images/2.jpg


BIN
src/assets/images/3.png


BIN
src/assets/images/4.jpg


BIN
src/assets/images/5.jpg


+ 1 - 1
src/index.html

@@ -3,7 +3,7 @@
 
 <head>
   <meta charset="utf-8" />
-  <title>飞码AI:智能体开发课程示例</title>
+  <title>碎光日记</title>
 
   <base href="/" />