Bladeren bron

feat: consult for law agent

Midnight 3 weken geleden
bovenliggende
commit
4852f3bbb7

File diff suppressed because it is too large
+ 637 - 16
myapp/package-lock.json


+ 1 - 0
myapp/package.json

@@ -27,6 +27,7 @@
     "@capacitor/keyboard": "7.0.1",
     "@capacitor/status-bar": "7.0.1",
     "@ionic/angular": "^8.0.0",
+    "fmode-ng": "^0.0.82",
     "ionicons": "^7.0.0",
     "rxjs": "~7.8.0",
     "tslib": "^2.3.0",

+ 15 - 2
myapp/src/app/app.module.ts

@@ -7,10 +7,23 @@ import { IonicModule, IonicRouteStrategy } from '@ionic/angular';
 import { AppRoutingModule } from './app-routing.module';
 import { AppComponent } from './app.component';
 
+import { HttpClientModule } from '@angular/common/http';
+import { Diagnostic } from '@awesome-cordova-plugins/diagnostic/ngx';
+// 设置Parse服务属性
+import Parse from "parse";
+Parse.initialize("ncloudmaster");
+Parse.serverURL = "https://server.fmode.cn/parse";
+localStorage.setItem("NOVA_APIG_SERVER", 'aHR0cHMlM0ElMkYlMkZzZXJ2ZXIuZm1vZGUuY24lMkZhcGklMkZhcGlnJTJG')
+
+
 @NgModule({
   declarations: [AppComponent],
-  imports: [BrowserModule, IonicModule.forRoot(), AppRoutingModule],
-  providers: [{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy }],
+  imports: [HttpClientModule,BrowserModule, IonicModule.forRoot(), AppRoutingModule],
+  providers: [
+    { provide: RouteReuseStrategy, useClass: IonicRouteStrategy },
+    
+    Diagnostic,
+  ],
   bootstrap: [AppComponent],
 })
 export class AppModule {}

+ 31 - 72
myapp/src/app/tab2/tab2.page.html

@@ -1,82 +1,41 @@
 <ion-header [translucent]="true">
-  <meta charset="UTF-8">
-  <meta name="viewport" content="width=device-width, initial-scale=1.0">
-  <title>明律通 - AI法律顾问</title>
-  <!-- 引入国内CDN资源 -->
-  <link href="https://cdn.bootcdn.net/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
-
+  <ion-toolbar>
+    <ion-title>
+      法律咨询
+    </ion-title>
+  </ion-toolbar>
+</ion-header>
 
 <ion-content [fullscreen]="true">
-  <!-- 咨询主页 -->
-  <div class="page" id="consult-home-page">
-
-    <div class="header">
-      <div class="logo">
-        <i class="fas fa-arrow-left"></i>
-      </div>
-      <div class="logo">
-        <span>法律咨询</span>
+  <ion-card class="lawyer-card">
+  <div class="card-header">
+    <div class="avatar-container">
+      <img src="/assets/lin.jpg" alt="林正鸿律师" class="lawyer-avatar">
     </div>
-      <div class="user-avatar">
-          <i class="fas fa-user"></i>
-      </div>
+    <div class="header-text">
+      <h2>林正鸿</h2>
+      <p class="title">国正律师事务所 创始合伙人</p>
     </div>
-    
-    <div style="margin: 20px 0;">
-        <h3 style="margin-bottom: 15px;">选择咨询类型</h3>
-        <div class="consult-types">
-            <div class="consult-type">
-                <div class="consult-icon">
-                    <i class="fas fa-briefcase"></i>
-                </div>
-                <div class="consult-title">劳动纠纷</div>
-                <div class="consult-desc">劳动合同、工资拖欠、工伤赔偿等问题</div>
-            </div>
-            <div class="consult-type">
-                <div class="consult-icon">
-                    <i class="fas fa-heart"></i>
-                </div>
-                <div class="consult-title">婚姻家庭</div>
-                <div class="consult-desc">离婚财产分割、抚养权、继承等问题</div>
-            </div>
-            <div class="consult-type">
-                <div class="consult-icon">
-                    <i class="fas fa-file-contract"></i>
-                </div>
-                <div class="consult-title">合同纠纷</div>
-                <div class="consult-desc">合同审查、违约赔偿、协议起草等问题</div>
-            </div>
-            <div class="consult-type">
-                <div class="consult-icon">
-                    <i class="fas fa-user-shield"></i>
-                </div>
-                <div class="consult-title">侵权责任</div>
-                <div class="consult-desc">人身损害、名誉权、隐私权等问题</div>
-            </div>
-        </div>
+  </div>
+
+  <ion-card-content>
+    <div class="specialty-tags">
+      <ion-chip color="primary">刑事辩护</ion-chip>
+      <ion-chip color="primary">婚姻家庭</ion-chip>
+      <ion-chip color="primary">合同纠纷</ion-chip>
     </div>
     
-    <div class="faq-section">
-        <h3 class="section-title">常见问题</h3>
-        <div class="faq-container">
-            <div class="faq-item">
-                <i class="fas fa-question-circle"></i>
-                公司拖欠工资怎么办?
-            </div>
-            <div class="faq-item">
-                <i class="fas fa-question-circle"></i>
-                离婚后财产如何分割?
-            </div>
-            <div class="faq-item">
-                <i class="fas fa-question-circle"></i>
-                合同违约如何索赔?
-            </div>
-            <div class="faq-item">
-                <i class="fas fa-question-circle"></i>
-                交通事故责任认定标准是什么?
-            </div>
-        </div>
+    <div class="profile-desc">
+      <p><ion-icon name="school-outline"></ion-icon> 全国优秀律师 | 全国律协刑事专业委员会副主任</p>
+      <p><ion-icon name="document-text-outline"></ion-icon> 擅长经济犯罪辩护、企业合规及司法政策研究</p>
+      <p><ion-icon name="ribbon-outline"></ion-icon> 参与多项最高法司法解释制定工作</p>
     </div>
-</div>
+  </ion-card-content>
+
+  <ion-button (click)="openConsult()" expand="block" color="primary" class="consult-btn">
+    <ion-icon name="chatbubble-ellipses-outline" slot="start"></ion-icon>
+    立即咨询
+  </ion-button>
+</ion-card>
 
 </ion-content>

+ 67 - 130
myapp/src/app/tab2/tab2.page.scss

@@ -1,135 +1,72 @@
-ion-content {
-    --background: linear-gradient(135deg, #F8F9FF, #E6F7FF);
-    background-size: cover;   
-    --padding-start: 16px;  
-    --padding-end: 16px;    
-}
-
-:root {
-    --primary: #3A5FE5;
-    --secondary: #00C4A1;
-    --danger: #FF4D4F;
-    --bg: #F8F9FF;
-    --text: #2D3748;
-    --card: #FFFFFF;
-}
-
-* {
-    margin: 0;
-    padding: 0;
-    box-sizing: border-box;
-    font-family: "PingFang SC", "Microsoft YaHei", sans-serif;
-}
-
-.container {
-    width: 100%;
-    max-width: 480px;
-    margin: 0 auto;
-    padding: 15px;
-    min-height: 100vh;
-    display: flex;
-    flex-direction: column;
-}
-
- /* 顶部导航 */
-.header {
+.lawyer-card {
+  border-radius: 12px;
+  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);
+  margin: 16px;
+  overflow: hidden;
+  
+  .card-header {
     display: flex;
-    justify-content: space-between;
     align-items: center;
-    padding: 10px 0;
-    margin-top: 10px;
-    margin-bottom: 15px;
-}
-
-.logo {
-    font-weight: bold;
-    font-size: 20px;
-    color: #3A5FE5;
-    display: flex;
-    align-items: center;
-}
-
-.logo i {
-    margin-right: 8px;
-    color: #00C4A1;
-}
-
-.user-avatar {
-    width: 36px;
-    height: 36px;
-    border-radius: 50%;
-    background-color: #3A5FE5;
-    display: flex;
-    align-items: center;
-    justify-content: center;
+    padding: 16px;
+    background: linear-gradient(135deg, #1976d2 0%, #0d47a1 100%);
     color: white;
-}
-/* 咨询类型选择 */
-.consult-types {
+    
+    .avatar-container {
+      width: 80px;
+      height: 80px;
+      border-radius: 50%;
+      overflow: hidden;
+      border: 3px solid rgba(255, 255, 255, 0.3);
+      margin-right: 16px;
+      
+      .lawyer-avatar {
+        width: 100%;
+        height: 100%;
+        object-fit: cover;
+      }
+    }
+    
+    .header-text {
+      h2 {
+        margin: 0;
+        font-weight: 600;
+        font-size: 1.3rem;
+      }
+      
+      .title {
+        margin: 4px 0 0;
+        font-size: 0.9rem;
+        opacity: 0.9;
+      }
+    }
+  }
+  
+  .specialty-tags {
+    margin: 8px 0 16px;
     display: flex;
     flex-wrap: wrap;
-    gap: 10px;
-    margin: 15px 0;
-}
-
-.consult-type {
-    flex: 1;
-    min-width: calc(50% - 5px);
-    background: white;
-    border-radius: 12px;
-    padding: 15px;
-    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
-    display: flex;
-    flex-direction: column;
-    align-items: center;
-    transition: all 0.2s;
-}
-
-.consult-type:active {
-    transform: scale(0.98);
-}
-
-.consult-icon {
-    font-size: 24px;
-    color: var(--primary);
-    margin-bottom: 10px;
-}
-
-.consult-icon i{
-    color: #3A5FE5;
-}
-
-.consult-title {
-    font-weight: bold;
-    margin-bottom: 5px;
-}
-
-.consult-desc {
-    font-size: 12px;
-    color: #666;
-    text-align: center;
-}
-
-
-
-
-.faq-section{
-    margin: 20px 0;
-}
-.section-title{
-    margin-bottom: 15px;
-}
-.faq-container{
-    background: white; 
-    border-radius: 12px; 
-    padding: 15px; 
-    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
-}
-.faq-item{
-    margin-bottom: 10px; 
-    padding: 10px; 
-    border-bottom: 1px solid #eee; cursor: pointer;
-}
-.faq-item i{
-    color: #3A5FE5; margin-right: 8px;
-}
+    gap: 8px;
+  }
+  
+  .profile-desc {
+    p {
+      display: flex;
+      align-items: center;
+      margin: 12px 0;
+      color: #444;
+      font-size: 0.9rem;
+      
+      ion-icon {
+        margin-right: 8px;
+        color: #1976d2;
+      }
+    }
+  }
+  
+  .consult-btn {
+    margin: 0;
+    --border-radius: 0;
+    font-weight: 500;
+    letter-spacing: 0.5px;
+  }
+}

+ 157 - 1
myapp/src/app/tab2/tab2.page.ts

@@ -1,4 +1,7 @@
 import { Component } from '@angular/core';
+import { ModalController } from '@ionic/angular/standalone';
+import { ChatPanelOptions, FmChatModalInput, FmodeChat, FmodeChatMessage, openChatPanelModal } from 'fmode-ng';
+import Parse from "parse";
 
 @Component({
   selector: 'app-tab2',
@@ -8,6 +11,159 @@ import { Component } from '@angular/core';
 })
 export class Tab2Page {
 
-  constructor() {}
+  constructor(
+    private modalCtrl:ModalController
+  ) {
+
+  }
+
+openConsult(chatId?:string){
+    localStorage.setItem("company","E4KpGvTEto")
+    let options:ChatPanelOptions = {
+      roleId:"2DXJkRsjXK", // 预设,无需更改
+      // chatId:chatId, // 若存在,则恢复会话。若不存在,则开启新会话
+      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","一名亲切和蔼的律师,林正鸿,年龄45岁");
+        // 角色标签
+        chat.role.set("tags",['刚正务实', '儒雅']);
+        // 角色头像
+        chat.role.set("avatar","/assets/lin.jpg")
+        // 角色提示词
+        chat.role.set("prompt",`
+# 角色设定
+身份:
+45岁,北京「国正律师事务所」创始合伙人,全国律协刑事专业委员会副主任,曾获「全国优秀律师」称号。
+
+外貌与气质:
+身材挺拔,常穿深色中山装或商务西装,不戴过多配饰,仅一枚简洁的律师徽章别在领口。
+面容沉稳,目光如炬,言谈间带有一种不怒自威的气场,但对待普通当事人时语气温和,极具亲和力。
+
+性格特质:
+刚正务实:坚持“法律是底线,也是武器”,厌恶投机取巧,擅长以扎实的证据链和法理分析取胜。
+家国情怀:代理案件时不仅考虑胜诉,更关注社会影响,曾多次为农民工、消费者群体提供公益法律援助。
+儒雅学者风:精通中国法制史,常在辩论中引用古代律法(如《唐律疏议》)与现代法条对比,增强说服力。
+
+语言风格:
+善用“根据我国《刑事诉讼法》第XX条”“最高人民法院指导意见明确……”等专业表述。
+偶尔引用传统智慧,如:“古人云‘律设大法,理顺人情’,本案应当兼顾法理与情理。”
+
+执业理念:
+坚持“党的领导+依法执业”,代理敏感案件时注重政治效果、法律效果与社会效果统一。
+
+生活细节:
+早晨习惯听《新闻联播》了解政策动向,办公室常备《求是》杂志。
+`);
+        // 对话灵感分类
+        let promptCates = [
+          {
+            "img": "/assets/icon/ld.jpg",
+            "name": "劳动就业问题"
+          },
+          {
+            "img": "/assets/icon/hy.jpg",
+            "name": "婚姻家庭问题"
+          },
+          {
+            "img": "/assets/icon/sh.jpg",
+            "name": "日常生活纠纷"
+          }
+        ]
+        setTimeout(() => {
+          chat.role.set("promptCates",promptCates)
+        }, 500);
+        // 对话灵感列表
+        let promptList = [
+          {
+            cate:"劳动就业问题",img:"/assets/icon/ld.jpg",
+            messageList:[
+            "公司不签劳动合同怎么办?",
+            "离职后老板拖欠工资该如何维权?",
+            "加班不给加班费是否合法?",
+            "试用期被无故辞退能要求赔偿吗?",
+            "工伤认定需要准备哪些材料?"  
+          ]
+          },
+          {
+            cate:"婚姻家庭问题",img:"/assets/icon/hy.jpg",
+            messageList:[
+              "离婚必须要有30天冷静期吗?",
+              "婚前财产婚后会变成共同财产吗?",
+              "家暴报警后警察一般会怎么处理?",
+              "抚养费标准是如何计算的?",
+              "对方出轨能让他净身出户吗?" 
+            ]
+          },
+          {
+            cate:"日常生活纠纷",img:"/assets/icon/sh.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:"话题灵感", // 按钮标题
+           showTitle:true, // 是否显示标题文字
+           icon:"color-wand-outline", // 标题icon图标
+           onClick:()=>{ // 按钮点击事件
+               chat.isPromptModalOpen = true
+           },
+           show:()=>{ // 按钮显示条件
+             return chat?.promptList?.length // 存在话题提示词时显示
+           }
+         },
+      ]
+
+      },
+      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('结束会话');
+          }
+        }
+      },
+      onChatSaved:(chat:FmodeChat)=>{
+        // chat?.chatSession?.id 本次会话的 chatId
+        console.log("onChatSaved",chat,chat?.chatSession,chat?.chatSession?.id)
+      }
+    }
+    openChatPanelModal(this.modalCtrl,options)
+  }
 
 }

+ 6 - 2
myapp/src/app/tabs/tabs.module.ts

@@ -6,14 +6,18 @@ import { FormsModule } from '@angular/forms';
 import { TabsPageRoutingModule } from './tabs-routing.module';
 
 import { TabsPage } from './tabs.page';
+import { ModalController } from '@ionic/angular/standalone';
 
 @NgModule({
   imports: [
     IonicModule,
     CommonModule,
     FormsModule,
-    TabsPageRoutingModule
+    TabsPageRoutingModule,   
   ],
-  declarations: [TabsPage]
+  declarations: [TabsPage],
+  providers:[
+    ModalController,
+  ]
 })
 export class TabsPageModule {}

BIN
myapp/src/assets/icon/hy.jpg


BIN
myapp/src/assets/icon/ld.jpg


BIN
myapp/src/assets/icon/sh.jpg


BIN
myapp/src/assets/lin.jpg


+ 2 - 0
myapp/tsconfig.json

@@ -10,6 +10,8 @@
     "noPropertyAccessFromIndexSignature": true,
     "noImplicitReturns": true,
     "noFallthroughCasesInSwitch": true,
+    "allowSyntheticDefaultImports":true,
+    "skipLibCheck": true,
     "sourceMap": true,
     "declaration": false,
     "downlevelIteration": true,

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