fmode-ng 0.0.38 → 0.0.40
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm2022/lib/aigc/chat/chat-modal-input/modal-input.component.mjs +1 -1
- package/esm2022/lib/aigc/chat/comp-role-prompt/comp-role-prompt.component.mjs +1 -1
- package/esm2022/lib/aigc/service-fmai/service-chat/chat-class.mjs +1 -1
- package/esm2022/lib/social/wechat/wechat-jssdk.service.mjs +1 -1
- package/esm2022/lib/user/account/account.service.mjs +1 -1
- package/fesm2022/fmode-ng.mjs +1 -1
- package/fesm2022/fmode-ng.mjs.map +1 -1
- package/package.json +1 -1
|
@@ -5,6 +5,6 @@
|
|
|
5
5
|
* 保留所有权利 All Rights Reserved.
|
|
6
6
|
* /home/ryan/workspace/nova/nova-admin/dist/fmode-ng/esm2022/lib/aigc/chat/chat-modal-input/modal-input.component.mjs
|
|
7
7
|
*/
|
|
8
|
-
import{Component,Input,ViewChild}from"@angular/core";import{ActivatedRoute,Router,RouterModule}from"@angular/router";import{AlertController,NavController,ToastController}from"@ionic/angular";import{FmodeChat}from"../../service-fmai/service-chat";import{ChatService}from"../../service-fmai/service-chat";import Parse from"parse";import{NzMessageService}from"ng-zorro-antd/message";import{ImagineService}from"../../service-fmai/service-imagine/imagine.service";import{IonButton,IonContent,IonIcon,IonInput,IonItem,IonList,IonModal,IonPopover,IonTextarea,IonToolbar}from"@ionic/angular/standalone";import{CommonModule}from"@angular/common";import{FormsModule,ReactiveFormsModule}from"@angular/forms";import{NzModalModule}from"ng-zorro-antd/modal";import{ModalAudioMessageComponent}from"./modal-audio-message/modal-audio-message.component";import*as i0 from"@angular/core";import*as i1 from"@ionic/angular";import*as i2 from"@angular/router";import*as i3 from"../../service-fmai/service-imagine/imagine.service";import*as i4 from"../../service-fmai/service-chat";import*as i5 from"ng-zorro-antd/message";import*as i6 from"@angular/common";import*as i7 from"@angular/forms";import*as i8 from"ng-zorro-antd/modal";export class FmChatModalInput{closeAudio(){this.audioComp?.cancel(),this.isAudioModal=!1}constructor(e,n,t,o,a,s,i,r){this.toastCtrl=e,this.alertCtrl=n,this.navCtrl=t,this.router=o,this.imagineServ=a,this.chatServ=s,this.route=i,this.messages=r,this.errorText="",this.isAudioModal=!1,this.isShare=!1,this.user=Parse.User.current()}ngOnInit(){this.loadModel()}async loadModel(){let e=this.chat?.role?.get("model");await this.chatServ.loadModelList(e)}async setMessageImage(){let e=await this.imagineServ.getimg();this.chat.userImage=e,console.log(this.chat?.userImage)}onKeyDown(e){e.ctrlKey&&"Enter"===e.key&&(console.log("Ctrl+Enter 被按下"),this.sendMessage())}async sendMessage(){if(!this.chat.userInput){return this.errorText="内容不能为空",void(await this.toastCtrl.create({message:this.errorText,position:"top",icon:"alert",color:"warning-circle",duration:1e3})).present()}this.chat?.sendMessage(this.chat?.userInput,this.chat?.userImage,(e=>{}),{onSSMLComplete:e=>{console.log(e)}}),this.chat.userInput="",this.chat.userImage=""}async checkBalance(){if(!this.chatServ?.currentModel?.get("payLimit"))return!0;let e=await this.account.getBilling();if(e?.credit?.balance<10){return(await this.alertCtrl.create({header:"注意",subHeader:"您的余额不足,请充值后解锁高级模型",buttons:[{role:"cancel",text:"取消"},{role:"destructive",text:"充值",handler:()=>{this.router.navigateByUrl("/account/billing")}}]})).present(),!1}return!0}async getChatShare(){this.user=Parse.User.current();let e=new Parse.Query("ChatShare");e.equalTo("user",Parse.User.current().id),e.equalTo("session",this.chat?.sessionId);await e.first()}async toggleChatShare(){let e=new Parse.Query("ChatShare");e.equalTo("user",Parse.User.current().id),e.equalTo("role",this.chat?.role.id),e.equalTo("session",this.chat?.sessionId),e.select("objectId");let n=await e.first();if(n?.id)n.set("messageList",this.chat?.messageList);else{n=new(Parse.Object.extend("ChatShare")),n.set("user",{__type:"Pointer",className:"_User",objectId:Parse.User.current()?.id}),n.set("session",{__type:"Pointer",className:"ChatSession",objectId:this.chat?.sessionId}),n.set("role",{__type:"Pointer",className:"AvatarRole",objectId:this.chat?.role.id}),n.set("company",{__type:"Pointer",className:"Company",objectId:"E4KpGvTEto"}),n.set("messageList",this.chat?.messageList)}await n.save(),this.getChatShare()}chatShareSuccessMessage(){this.messages.success("分享成功")}showShare(){this.isShare=!0}handleOkShare(){this.toggleChatShare(),this.chatShareSuccessMessage(),this.isShare=!1}handleCancelShare(){this.isShare=!1}static{this.ɵfac=i0.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"17.3.12",ngImport:i0,type:FmChatModalInput,deps:[{token:i1.ToastController},{token:i1.AlertController},{token:i1.NavController},{token:i2.Router},{token:i3.ImagineService},{token:i4.ChatService},{token:i2.ActivatedRoute},{token:i5.NzMessageService}],target:i0.ɵɵFactoryTarget.Component})}static{this.ɵcmp=i0.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"17.3.12",type:FmChatModalInput,isStandalone:!0,selector:"fm-chat-modal-input",inputs:{chat:"chat",message:"message",role:"role"},viewQueries:[{propertyName:"audioComp",first:!0,predicate:ModalAudioMessageComponent,descendants:!0}],ngImport:i0,template:'<ion-toolbar>\n <ion-item class="button-item" lines="none">\n \x3c!-- 设置 --\x3e\n \x3c!-- <ion-button fill="outline" slot="start">\n <ion-icon name="settings-outline"></ion-icon> \n </ion-button> --\x3e\n <ng-container *ngFor="let button of chat?.leftButtons">\n <ion-button shape="round" *ngIf="button.show()" fill="outline" [title]="button?.title" slot="start" (click)="button.onClick()">\n <ion-icon [name]="button?.icon" [slot]="button?.showTitle?\'start\':\'icon-only\'"></ion-icon>\n {{button?.showTitle&&button?.title}}\n </ion-button>\n </ng-container>\n\n <ng-container *ngFor="let button of chat?.role?.get(\'buttons\')">\n <ion-button shape="round" (click)="chatServ.doButtonAction(button)" fill="outline" slot="start">\n {{button?.name}}\n </ion-button>\n </ng-container>\n\n \x3c!--分享按钮--\x3e\n <ion-button shape="round" *ngIf="chat?.messageList?.length>1" (click)="showShare()" fill="outline" title="分享" slot="end">\n <ion-icon name="share-social-outline"></ion-icon>\n </ion-button>\n \x3c!-- <button nz-button *ngIf="chat?.messageList?.length>1"\n nzType="primary" title="分享" (click)="showShare()" style="width: 31.188px;height: 22px;box-shadow: none;background: #fff;border: 1px solid #4588ff;border-radius: 5px;"> <span class="iconfont icon-fenxiang" style="color: #4588ff;"></span></button>\n --\x3e\n <ion-modal [isOpen]="isShare">\n <ng-template>\n <ion-header>\n <ion-toolbar>\n <ion-buttons slot="start">\n <ion-button (click)="handleCancelShare()">取消</ion-button>\n </ion-buttons>\n <ion-title>对话分享</ion-title>\n <ion-buttons slot="end">\n <ion-button (click)="handleOkShare()">分享</ion-button>\n </ion-buttons>\n </ion-toolbar>\n </ion-header>\n <ion-content class="ion-padding">\n <div class="popup-content">\n <div *ngFor="let message of chat?.messageList">\n \x3c!-- 头像 --\x3e\n <div class="item-row user" *ngIf="message?.role!=\'system\'">\n <div>\n <nz-avatar *ngIf="message?.role!=\'user\'" [nzSrc]="(chat?.role?.get(\'avatar\') || chat?.role?.get(\'thumb\') || \'https://file-cloud.fmode.cn/E4KpGvTEto/20230930/l413e6090731854.png\')+\'?\'+\'x-image-process=image/resize,m_fixed,w_100\'+\'&imageView2/1/w/32/h/32\'"></nz-avatar>\n </div>\n <div class="user-question">\n <app-comp-user-avatar [user]="user" *ngIf="message?.role==\'user\'"></app-comp-user-avatar>\n </div>\n </div>\n \x3c!-- 内容 --\x3e\n <div class="message-wrapper">\n <div class="message-content-user">\n <div class="user-message" *ngIf="message?.role === \'user\'">\n <div class="item-content">\n \x3c!-- <fm-markdown-preview *ngIf="!message?.complete" class="content-style" [content]="message?.content" [render]="false"></fm-markdown-preview> --\x3e\n <fm-markdown-preview *ngIf="message?.complete" class="content-style" [content]="message?.content"></fm-markdown-preview>\n </div>\n </div>\n </div>\n <div class="message-content-role">\n <div class="role-message" *ngIf="message?.role !== \'user\' && message?.role !== \'system\'">\n <div class="item-content">\n \x3c!-- <fm-markdown-preview *ngIf="!message?.complete" class="content-style" [content]="message?.content" [render]="false"></fm-markdown-preview> --\x3e\n <fm-markdown-preview *ngIf="message?.complete" class="content-style" [content]="message?.content"></fm-markdown-preview>\n </div>\n </div>\n </div>\n <div class="message-content-system">\n <div class="system-message" *ngIf="message?.role === \'system\'">\n <div class="item-content">\n \x3c!-- <fm-markdown-preview *ngIf="!message?.complete" class="content-style" [content]="message?.content" [render]="false"></fm-markdown-preview> --\x3e\n <fm-markdown-preview *ngIf="message?.complete" class="content-style" [content]="message?.content"></fm-markdown-preview>\n </div>\n </div>\n </div>\n </div>\n <div class="chat-time" *ngIf="message?.createdAt" [ngClass]="{\'role-time\': message?.role !== \'user\'}">\n <span>{{message?.createdAt | date:"dd/MM/yyyy, HH/mm/ss a"}}</span>\n </div>\n </div>\n </div> \n </ion-content>\n </ng-template>\n </ion-modal>\n\n <nz-modal *ngIf="false"\n [(nzVisible)]="isShare"\n nzTitle="问答分享"\n nzCentered\n nzOkText="分享"\n nzCancelText="取消"\n (nzOnCancel)="handleCancelShare()"\n (nzOnOk)="handleOkShare()"\n >\n <ng-container *nzModalContent>\n <div class="popup-content">\n <div *ngFor="let message of chat?.messageList">\n \x3c!-- 头像 --\x3e\n <div class="item-row user" *ngIf="message?.role!=\'system\'">\n <div>\n <nz-avatar *ngIf="message?.role!=\'user\'" [nzSrc]="(chat?.role?.get(\'thumb\') || \'https://file-cloud.fmode.cn/E4KpGvTEto/20230930/l413e6090731854.png\')+\'?\'+\'x-image-process=image/resize,m_fixed,w_100\'+\'&imageView2/1/w/32/h/32\'"></nz-avatar>\n </div>\n <div class="user-question">\n <app-comp-user-avatar [user]="user" *ngIf="message?.role==\'user\'"></app-comp-user-avatar>\n </div>\n </div>\n \x3c!-- 内容 --\x3e\n <div class="message-wrapper">\n <div class="message-content-user">\n <div class="user-message" *ngIf="message?.role === \'user\'">\n <div class="item-content">\n \x3c!-- <fm-markdown-preview *ngIf="!message?.complete" class="content-style" [content]="message?.content" [render]="false"></fm-markdown-preview> --\x3e\n <fm-markdown-preview *ngIf="message?.complete" class="content-style" [content]="message?.content"></fm-markdown-preview>\n </div>\n </div>\n </div>\n <div class="message-content-role">\n <div class="role-message" *ngIf="message?.role !== \'user\' && message?.role !== \'system\'">\n <div class="item-content">\n \x3c!-- <fm-markdown-preview *ngIf="!message?.complete" class="content-style" [content]="message?.content" [render]="false"></fm-markdown-preview> --\x3e\n <fm-markdown-preview *ngIf="message?.complete" class="content-style" [content]="message?.content"></fm-markdown-preview>\n </div>\n </div>\n </div>\n <div class="message-content-system">\n <div class="system-message" *ngIf="message?.role === \'system\'">\n <div class="item-content">\n \x3c!-- <fm-markdown-preview *ngIf="!message?.complete" class="content-style" [content]="message?.content" [render]="false"></fm-markdown-preview> --\x3e\n <fm-markdown-preview *ngIf="message?.complete" class="content-style" [content]="message?.content"></fm-markdown-preview>\n </div>\n </div>\n </div>\n </div>\n <div class="chat-time" *ngIf="message?.createdAt" [ngClass]="{\'role-time\': message?.role !== \'user\'}">\n <span>{{message?.createdAt | date:"dd/MM/yyyy, HH/mm/ss a"}}</span>\n </div>\n </div>\n </div> \n </ng-container>\n </nz-modal>\n\n \x3c!-- 图片 --\x3e\n <ion-button shape="round" *ngIf="chatServ?.currentModel?.get(\'config\')?.imageEnabled" fill="outline" slot="end" (click)="setMessageImage()">\n <ion-icon name="image-outline"></ion-icon>\n </ion-button>\n \x3c!-- 模型 --\x3e\n <ion-button shape="round" fill="outline" slot="end" id="model-button">\n <ion-icon name="chevron-down-outline"></ion-icon>\n {{chatServ?.currentModel?.get&&chatServ?.currentModel?.get("name")||"飞码4.0"}}\n </ion-button>\n <ion-popover trigger="model-button" [dismissOnSelect]="true">\n <ng-template>\n <ion-content>\n <ion-list>\n <ng-container *ngFor="let model of chatServ.modelList">\n <ion-item (click)="chatServ.currentModel = model" [button]="true" [detail]="false">\n {{model?.get("name")}}\n <ion-note slot="end">{{model?.get("credit")}}/k</ion-note>\n </ion-item>\n </ng-container>\n </ion-list>\n </ion-content>\n </ng-template>\n </ion-popover>\n\n </ion-item>\n\n <ion-item class="input-item" lines="none">\n \x3c!-- 语音消息输入 --\x3e\n <ng-container *ngIf="chat?.isVoiceInputMode">\n \x3c!-- 切换文本输入 --\x3e\n <ion-button class="btn-input-change" color="primary" (click)="chat.isVoiceInputMode=false" shape="round" size="large">\n <ion-icon name="chatbox-ellipses-outline" slot="icon-only"></ion-icon>\n </ion-button>\n \n <div class="btn-voice-start" (click)="isAudioModal=true">\n <span>\n 点击讲话\n </span> \n </div>\n </ng-container>\n\n \x3c!-- 文本消息输入 --\x3e\n <ng-container *ngIf="!chat?.isVoiceInputMode">\n \x3c!-- 切换语音输入 --\x3e\n <ion-button [style.display]="chat.isTexting?\'none\':\'flex\'" class="btn-input-change" color="primary" *ngIf="chat?.role?.get(\'voiceConfig\')" (click)="chat.isVoiceInputMode=true" shape="round" size="large">\n <ion-icon name="mic-outline" slot="icon-only"></ion-icon>\n </ion-button>\n\n \x3c!-- 文本输入区域 --\x3e\n <ion-textarea *ngIf="chat" (keydown)="onKeyDown($event)"\n [errorText]="errorText"\n [(ngModel)]="chat.userInput"\n (ionFocus)="chat.isTexting=true"\n (ionBlur)="chat.isTexting=false"\n [autoGrow]="true" shape="round" fill="outline"\n label="Ctrl + Enter 发送消息" placeholder="请输入您的提示词"\n labelPlacement="floating"></ion-textarea>\n \n \x3c!-- 文本发送按钮 --\x3e\n <ion-button color="primary" shape="round" size="large" (click)="sendMessage()">\n <ion-icon name="paper-plane-outline" slot="icon-only"></ion-icon>\n </ion-button>\n </ng-container>\n </ion-item>\n</ion-toolbar>\n\n\n\x3c!-- 语音消息输入:弹出区域 --\x3e\n<ion-modal #audioModal [isOpen]="isAudioModal" (willDismiss)="closeAudio()" [initialBreakpoint]="0.35" [breakpoints]="[0, 0.35, 0.5]">\n <ng-template>\n <fm-modal-audio-message #audioComp *ngIf="isAudioModal" [chat]="chat" [modal]="audioModal"></fm-modal-audio-message>\n </ng-template>\n</ion-modal>',styles:['@charset "UTF-8";:host-context(body.dark) .btn-voice-start{background-color:#222428;color:#fff}:host-context(body.dark) ion-textarea{background-color:#222428;color:#fff}ion-toolbar{--background:none}ion-toolbar .button-item{--inner-padding-start:5px;--inner-padding-end:0px;--padding-start:5px;--padding-end:0px}ion-toolbar ion-item{--background:transparent}ion-textarea.custom{--background: #373737;--color: #fff;--padding-end: 10px;--padding-start: 10px;--placeholder-color: #ddd;--placeholder-opacity: .8}ion-textarea.custom textarea{width:calc(100% - 95px)}ion-textarea.custom ion-button{position:absolute;right:0}.input-item{display:flex;min-height:77px;align-items:center;border:none;--inner-padding-start:0px;--inner-padding-end:0px;--padding-start:0px;--padding-end:0px}.input-item ion-textarea{background-color:#fff;max-height:400px;padding:0 5px;margin:0 5px;border-radius:20px;overflow-y:auto}.input-item .btn-voice-start{display:flex;flex:1;justify-content:center;align-items:center;font-weight:700;background:#fff;border-radius:20px;min-height:50px}ion-textarea{transition:width .5s ease}ion-textarea:hover .btn-input-change,ion-textarea:focus-within .btn-input-change{display:none}.input-item:hover ion-textarea,.input-item:focus-within ion-textarea{border-color:var(--logo-color-primary)}::ng-deep .ant-modal-body{max-height:600px;overflow-y:auto}::ng-deep .ant-modal-footer{display:flex;justify-content:space-around}::ng-deep .ant-btn{width:40%}.popup-content{position:relative}.popup-content .message-content-user{display:flex;justify-content:flex-end}.popup-content .message-content-role{display:flex;justify-content:flex-start}.popup-content .message-content-system{display:flex;justify-content:center}.popup-content .user-message{padding:10px 10px 0;border-radius:10px;width:fit-content;max-width:100%;background-color:#e7f8ff}.popup-content .role-message{padding:10px 10px 0;border-radius:10px;width:fit-content;max-width:100%;background-color:#f6f6f6}.popup-content .user-question{margin-bottom:5px;display:flex;justify-content:flex-end}.popup-content .chat-time{margin-bottom:10px;display:flex;justify-content:flex-end;font-size:14px;color:#a3a3a3}.popup-content .role-time{justify-content:flex-start}\n'],dependencies:[{kind:"ngmodule",type:CommonModule},{kind:"directive",type:i6.NgClass,selector:"[ngClass]",inputs:["class","ngClass"]},{kind:"directive",type:i6.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:i6.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"pipe",type:i6.DatePipe,name:"date"},{kind:"ngmodule",type:FormsModule},{kind:"directive",type:i7.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:i7.NgModel,selector:"[ngModel]:not([formControlName]):not([formControl])",inputs:["name","disabled","ngModel","ngModelOptions"],outputs:["ngModelChange"],exportAs:["ngModel"]},{kind:"ngmodule",type:ReactiveFormsModule},{kind:"ngmodule",type:RouterModule},{kind:"component",type:IonToolbar,selector:"ion-toolbar",inputs:["color","mode"]},{kind:"component",type:IonItem,selector:"ion-item",inputs:["button","color","detail","detailIcon","disabled","download","href","lines","mode","rel","routerAnimation","routerDirection","target","type"]},{kind:"component",type:IonButton,selector:"ion-button",inputs:["buttonType","color","disabled","download","expand","fill","form","href","mode","rel","routerAnimation","routerDirection","shape","size","strong","target","type"]},{kind:"component",type:IonList,selector:"ion-list",inputs:["inset","lines","mode"]},{kind:"component",type:IonModal,selector:"ion-modal"},{kind:"component",type:IonIcon,selector:"ion-icon",inputs:["color","flipRtl","icon","ios","lazy","md","mode","name","sanitize","size","src"]},{kind:"component",type:IonTextarea,selector:"ion-textarea",inputs:["autoGrow","autocapitalize","autofocus","clearOnEdit","color","cols","counter","counterFormatter","debounce","disabled","enterkeyhint","errorText","fill","helperText","inputmode","label","labelPlacement","maxlength","minlength","mode","name","placeholder","readonly","required","rows","shape","spellcheck","value","wrap"]},{kind:"component",type:IonPopover,selector:"ion-popover"},{kind:"component",type:IonContent,selector:"ion-content",inputs:["color","fixedSlotPlacement","forceOverscroll","fullscreen","scrollEvents","scrollX","scrollY"]},{kind:"ngmodule",type:NzModalModule},{kind:"component",type:i8.NzModalComponent,selector:"nz-modal",inputs:["nzMask","nzMaskClosable","nzCloseOnNavigation","nzVisible","nzClosable","nzOkLoading","nzOkDisabled","nzCancelDisabled","nzCancelLoading","nzKeyboard","nzNoAnimation","nzCentered","nzDraggable","nzContent","nzFooter","nzZIndex","nzWidth","nzWrapClassName","nzClassName","nzStyle","nzTitle","nzCloseIcon","nzMaskStyle","nzBodyStyle","nzOkText","nzCancelText","nzOkType","nzOkDanger","nzIconType","nzModalType","nzAutofocus","nzOnOk","nzOnCancel"],outputs:["nzOnOk","nzOnCancel","nzAfterOpen","nzAfterClose","nzVisibleChange"],exportAs:["nzModal"]},{kind:"directive",type:i8.NzModalContentDirective,selector:"[nzModalContent]",exportAs:["nzModalContent"]},{kind:"component",type:ModalAudioMessageComponent,selector:"fm-modal-audio-message",inputs:["chat","modal"]}]})}}i0.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"17.3.12",ngImport:i0,type:FmChatModalInput,decorators:[{type:Component,args:[{selector:"fm-chat-modal-input",standalone:!0,imports:[CommonModule,FormsModule,ReactiveFormsModule,RouterModule,IonToolbar,IonItem,IonButton,IonList,IonModal,IonInput,IonIcon,IonTextarea,IonPopover,IonContent,NzModalModule,ModalAudioMessageComponent],template:'<ion-toolbar>\n <ion-item class="button-item" lines="none">\n \x3c!-- 设置 --\x3e\n \x3c!-- <ion-button fill="outline" slot="start">\n <ion-icon name="settings-outline"></ion-icon> \n </ion-button> --\x3e\n <ng-container *ngFor="let button of chat?.leftButtons">\n <ion-button shape="round" *ngIf="button.show()" fill="outline" [title]="button?.title" slot="start" (click)="button.onClick()">\n <ion-icon [name]="button?.icon" [slot]="button?.showTitle?\'start\':\'icon-only\'"></ion-icon>\n {{button?.showTitle&&button?.title}}\n </ion-button>\n </ng-container>\n\n <ng-container *ngFor="let button of chat?.role?.get(\'buttons\')">\n <ion-button shape="round" (click)="chatServ.doButtonAction(button)" fill="outline" slot="start">\n {{button?.name}}\n </ion-button>\n </ng-container>\n\n \x3c!--分享按钮--\x3e\n <ion-button shape="round" *ngIf="chat?.messageList?.length>1" (click)="showShare()" fill="outline" title="分享" slot="end">\n <ion-icon name="share-social-outline"></ion-icon>\n </ion-button>\n \x3c!-- <button nz-button *ngIf="chat?.messageList?.length>1"\n nzType="primary" title="分享" (click)="showShare()" style="width: 31.188px;height: 22px;box-shadow: none;background: #fff;border: 1px solid #4588ff;border-radius: 5px;"> <span class="iconfont icon-fenxiang" style="color: #4588ff;"></span></button>\n --\x3e\n <ion-modal [isOpen]="isShare">\n <ng-template>\n <ion-header>\n <ion-toolbar>\n <ion-buttons slot="start">\n <ion-button (click)="handleCancelShare()">取消</ion-button>\n </ion-buttons>\n <ion-title>对话分享</ion-title>\n <ion-buttons slot="end">\n <ion-button (click)="handleOkShare()">分享</ion-button>\n </ion-buttons>\n </ion-toolbar>\n </ion-header>\n <ion-content class="ion-padding">\n <div class="popup-content">\n <div *ngFor="let message of chat?.messageList">\n \x3c!-- 头像 --\x3e\n <div class="item-row user" *ngIf="message?.role!=\'system\'">\n <div>\n <nz-avatar *ngIf="message?.role!=\'user\'" [nzSrc]="(chat?.role?.get(\'avatar\') || chat?.role?.get(\'thumb\') || \'https://file-cloud.fmode.cn/E4KpGvTEto/20230930/l413e6090731854.png\')+\'?\'+\'x-image-process=image/resize,m_fixed,w_100\'+\'&imageView2/1/w/32/h/32\'"></nz-avatar>\n </div>\n <div class="user-question">\n <app-comp-user-avatar [user]="user" *ngIf="message?.role==\'user\'"></app-comp-user-avatar>\n </div>\n </div>\n \x3c!-- 内容 --\x3e\n <div class="message-wrapper">\n <div class="message-content-user">\n <div class="user-message" *ngIf="message?.role === \'user\'">\n <div class="item-content">\n \x3c!-- <fm-markdown-preview *ngIf="!message?.complete" class="content-style" [content]="message?.content" [render]="false"></fm-markdown-preview> --\x3e\n <fm-markdown-preview *ngIf="message?.complete" class="content-style" [content]="message?.content"></fm-markdown-preview>\n </div>\n </div>\n </div>\n <div class="message-content-role">\n <div class="role-message" *ngIf="message?.role !== \'user\' && message?.role !== \'system\'">\n <div class="item-content">\n \x3c!-- <fm-markdown-preview *ngIf="!message?.complete" class="content-style" [content]="message?.content" [render]="false"></fm-markdown-preview> --\x3e\n <fm-markdown-preview *ngIf="message?.complete" class="content-style" [content]="message?.content"></fm-markdown-preview>\n </div>\n </div>\n </div>\n <div class="message-content-system">\n <div class="system-message" *ngIf="message?.role === \'system\'">\n <div class="item-content">\n \x3c!-- <fm-markdown-preview *ngIf="!message?.complete" class="content-style" [content]="message?.content" [render]="false"></fm-markdown-preview> --\x3e\n <fm-markdown-preview *ngIf="message?.complete" class="content-style" [content]="message?.content"></fm-markdown-preview>\n </div>\n </div>\n </div>\n </div>\n <div class="chat-time" *ngIf="message?.createdAt" [ngClass]="{\'role-time\': message?.role !== \'user\'}">\n <span>{{message?.createdAt | date:"dd/MM/yyyy, HH/mm/ss a"}}</span>\n </div>\n </div>\n </div> \n </ion-content>\n </ng-template>\n </ion-modal>\n\n <nz-modal *ngIf="false"\n [(nzVisible)]="isShare"\n nzTitle="问答分享"\n nzCentered\n nzOkText="分享"\n nzCancelText="取消"\n (nzOnCancel)="handleCancelShare()"\n (nzOnOk)="handleOkShare()"\n >\n <ng-container *nzModalContent>\n <div class="popup-content">\n <div *ngFor="let message of chat?.messageList">\n \x3c!-- 头像 --\x3e\n <div class="item-row user" *ngIf="message?.role!=\'system\'">\n <div>\n <nz-avatar *ngIf="message?.role!=\'user\'" [nzSrc]="(chat?.role?.get(\'thumb\') || \'https://file-cloud.fmode.cn/E4KpGvTEto/20230930/l413e6090731854.png\')+\'?\'+\'x-image-process=image/resize,m_fixed,w_100\'+\'&imageView2/1/w/32/h/32\'"></nz-avatar>\n </div>\n <div class="user-question">\n <app-comp-user-avatar [user]="user" *ngIf="message?.role==\'user\'"></app-comp-user-avatar>\n </div>\n </div>\n \x3c!-- 内容 --\x3e\n <div class="message-wrapper">\n <div class="message-content-user">\n <div class="user-message" *ngIf="message?.role === \'user\'">\n <div class="item-content">\n \x3c!-- <fm-markdown-preview *ngIf="!message?.complete" class="content-style" [content]="message?.content" [render]="false"></fm-markdown-preview> --\x3e\n <fm-markdown-preview *ngIf="message?.complete" class="content-style" [content]="message?.content"></fm-markdown-preview>\n </div>\n </div>\n </div>\n <div class="message-content-role">\n <div class="role-message" *ngIf="message?.role !== \'user\' && message?.role !== \'system\'">\n <div class="item-content">\n \x3c!-- <fm-markdown-preview *ngIf="!message?.complete" class="content-style" [content]="message?.content" [render]="false"></fm-markdown-preview> --\x3e\n <fm-markdown-preview *ngIf="message?.complete" class="content-style" [content]="message?.content"></fm-markdown-preview>\n </div>\n </div>\n </div>\n <div class="message-content-system">\n <div class="system-message" *ngIf="message?.role === \'system\'">\n <div class="item-content">\n \x3c!-- <fm-markdown-preview *ngIf="!message?.complete" class="content-style" [content]="message?.content" [render]="false"></fm-markdown-preview> --\x3e\n <fm-markdown-preview *ngIf="message?.complete" class="content-style" [content]="message?.content"></fm-markdown-preview>\n </div>\n </div>\n </div>\n </div>\n <div class="chat-time" *ngIf="message?.createdAt" [ngClass]="{\'role-time\': message?.role !== \'user\'}">\n <span>{{message?.createdAt | date:"dd/MM/yyyy, HH/mm/ss a"}}</span>\n </div>\n </div>\n </div> \n </ng-container>\n </nz-modal>\n\n \x3c!-- 图片 --\x3e\n <ion-button shape="round" *ngIf="chatServ?.currentModel?.get(\'config\')?.imageEnabled" fill="outline" slot="end" (click)="setMessageImage()">\n <ion-icon name="image-outline"></ion-icon>\n </ion-button>\n \x3c!-- 模型 --\x3e\n <ion-button shape="round" fill="outline" slot="end" id="model-button">\n <ion-icon name="chevron-down-outline"></ion-icon>\n {{chatServ?.currentModel?.get&&chatServ?.currentModel?.get("name")||"飞码4.0"}}\n </ion-button>\n <ion-popover trigger="model-button" [dismissOnSelect]="true">\n <ng-template>\n <ion-content>\n <ion-list>\n <ng-container *ngFor="let model of chatServ.modelList">\n <ion-item (click)="chatServ.currentModel = model" [button]="true" [detail]="false">\n {{model?.get("name")}}\n <ion-note slot="end">{{model?.get("credit")}}/k</ion-note>\n </ion-item>\n </ng-container>\n </ion-list>\n </ion-content>\n </ng-template>\n </ion-popover>\n\n </ion-item>\n\n <ion-item class="input-item" lines="none">\n \x3c!-- 语音消息输入 --\x3e\n <ng-container *ngIf="chat?.isVoiceInputMode">\n \x3c!-- 切换文本输入 --\x3e\n <ion-button class="btn-input-change" color="primary" (click)="chat.isVoiceInputMode=false" shape="round" size="large">\n <ion-icon name="chatbox-ellipses-outline" slot="icon-only"></ion-icon>\n </ion-button>\n \n <div class="btn-voice-start" (click)="isAudioModal=true">\n <span>\n 点击讲话\n </span> \n </div>\n </ng-container>\n\n \x3c!-- 文本消息输入 --\x3e\n <ng-container *ngIf="!chat?.isVoiceInputMode">\n \x3c!-- 切换语音输入 --\x3e\n <ion-button [style.display]="chat.isTexting?\'none\':\'flex\'" class="btn-input-change" color="primary" *ngIf="chat?.role?.get(\'voiceConfig\')" (click)="chat.isVoiceInputMode=true" shape="round" size="large">\n <ion-icon name="mic-outline" slot="icon-only"></ion-icon>\n </ion-button>\n\n \x3c!-- 文本输入区域 --\x3e\n <ion-textarea *ngIf="chat" (keydown)="onKeyDown($event)"\n [errorText]="errorText"\n [(ngModel)]="chat.userInput"\n (ionFocus)="chat.isTexting=true"\n (ionBlur)="chat.isTexting=false"\n [autoGrow]="true" shape="round" fill="outline"\n label="Ctrl + Enter 发送消息" placeholder="请输入您的提示词"\n labelPlacement="floating"></ion-textarea>\n \n \x3c!-- 文本发送按钮 --\x3e\n <ion-button color="primary" shape="round" size="large" (click)="sendMessage()">\n <ion-icon name="paper-plane-outline" slot="icon-only"></ion-icon>\n </ion-button>\n </ng-container>\n </ion-item>\n</ion-toolbar>\n\n\n\x3c!-- 语音消息输入:弹出区域 --\x3e\n<ion-modal #audioModal [isOpen]="isAudioModal" (willDismiss)="closeAudio()" [initialBreakpoint]="0.35" [breakpoints]="[0, 0.35, 0.5]">\n <ng-template>\n <fm-modal-audio-message #audioComp *ngIf="isAudioModal" [chat]="chat" [modal]="audioModal"></fm-modal-audio-message>\n </ng-template>\n</ion-modal>',styles:['@charset "UTF-8";:host-context(body.dark) .btn-voice-start{background-color:#222428;color:#fff}:host-context(body.dark) ion-textarea{background-color:#222428;color:#fff}ion-toolbar{--background:none}ion-toolbar .button-item{--inner-padding-start:5px;--inner-padding-end:0px;--padding-start:5px;--padding-end:0px}ion-toolbar ion-item{--background:transparent}ion-textarea.custom{--background: #373737;--color: #fff;--padding-end: 10px;--padding-start: 10px;--placeholder-color: #ddd;--placeholder-opacity: .8}ion-textarea.custom textarea{width:calc(100% - 95px)}ion-textarea.custom ion-button{position:absolute;right:0}.input-item{display:flex;min-height:77px;align-items:center;border:none;--inner-padding-start:0px;--inner-padding-end:0px;--padding-start:0px;--padding-end:0px}.input-item ion-textarea{background-color:#fff;max-height:400px;padding:0 5px;margin:0 5px;border-radius:20px;overflow-y:auto}.input-item .btn-voice-start{display:flex;flex:1;justify-content:center;align-items:center;font-weight:700;background:#fff;border-radius:20px;min-height:50px}ion-textarea{transition:width .5s ease}ion-textarea:hover .btn-input-change,ion-textarea:focus-within .btn-input-change{display:none}.input-item:hover ion-textarea,.input-item:focus-within ion-textarea{border-color:var(--logo-color-primary)}::ng-deep .ant-modal-body{max-height:600px;overflow-y:auto}::ng-deep .ant-modal-footer{display:flex;justify-content:space-around}::ng-deep .ant-btn{width:40%}.popup-content{position:relative}.popup-content .message-content-user{display:flex;justify-content:flex-end}.popup-content .message-content-role{display:flex;justify-content:flex-start}.popup-content .message-content-system{display:flex;justify-content:center}.popup-content .user-message{padding:10px 10px 0;border-radius:10px;width:fit-content;max-width:100%;background-color:#e7f8ff}.popup-content .role-message{padding:10px 10px 0;border-radius:10px;width:fit-content;max-width:100%;background-color:#f6f6f6}.popup-content .user-question{margin-bottom:5px;display:flex;justify-content:flex-end}.popup-content .chat-time{margin-bottom:10px;display:flex;justify-content:flex-end;font-size:14px;color:#a3a3a3}.popup-content .role-time{justify-content:flex-start}\n']}]}],ctorParameters:()=>[{type:i1.ToastController},{type:i1.AlertController},{type:i1.NavController},{type:i2.Router},{type:i3.ImagineService},{type:i4.ChatService},{type:i2.ActivatedRoute},{type:i5.NzMessageService}],propDecorators:{audioComp:[{type:ViewChild,args:[ModalAudioMessageComponent]}],chat:[{type:Input}],message:[{type:Input}],role:[{type:Input}]}});
|
|
8
|
+
import{Component,Input,ViewChild}from"@angular/core";import{ActivatedRoute,Router,RouterModule}from"@angular/router";import{AlertController,NavController,ToastController}from"@ionic/angular";import{FmodeChat}from"../../service-fmai/service-chat";import{ChatService}from"../../service-fmai/service-chat";import Parse from"parse";import{NzMessageService}from"ng-zorro-antd/message";import{ImagineService}from"../../service-fmai/service-imagine/imagine.service";import{IonButton,IonContent,IonIcon,IonInput,IonItem,IonList,IonModal,IonPopover,IonTextarea,IonToolbar}from"@ionic/angular/standalone";import{CommonModule}from"@angular/common";import{FormsModule,ReactiveFormsModule}from"@angular/forms";import{NzModalModule}from"ng-zorro-antd/modal";import{ModalAudioMessageComponent}from"./modal-audio-message/modal-audio-message.component";import*as i0 from"@angular/core";import*as i1 from"@ionic/angular";import*as i2 from"@angular/router";import*as i3 from"../../service-fmai/service-imagine/imagine.service";import*as i4 from"../../service-fmai/service-chat";import*as i5 from"ng-zorro-antd/message";import*as i6 from"@angular/common";import*as i7 from"@angular/forms";import*as i8 from"ng-zorro-antd/modal";export class FmChatModalInput{closeAudio(){this.audioComp?.cancel(),this.isAudioModal=!1}constructor(e,n,t,o,a,s,i,r){this.toastCtrl=e,this.alertCtrl=n,this.navCtrl=t,this.router=o,this.imagineServ=a,this.chatServ=s,this.route=i,this.messages=r,this.errorText="",this.isAudioModal=!1,this.isShare=!1,this.user=Parse.User.current()}ngOnInit(){this.loadModel()}async loadModel(){let e=this.chat?.role?.get("model");await this.chatServ.loadModelList(e)}async setMessageImage(){let e=await this.imagineServ.getimg();this.chat.userImage=e,console.log(this.chat?.userImage)}onKeyDown(e){e.ctrlKey&&"Enter"===e.key&&(console.log("Ctrl+Enter 被按下"),this.sendMessage())}async sendMessage(){if(!this.chat.userInput){return this.errorText="内容不能为空",void(await this.toastCtrl.create({message:this.errorText,position:"top",icon:"alert",color:"warning-circle",duration:1e3})).present()}this.chat?.sendMessage(this.chat?.userInput,this.chat?.userImage,(e=>{}),{onSSMLComplete:e=>{console.log(e)}}),this.chat.userInput="",this.chat.userImage=""}async checkBalance(){if(!this.chatServ?.currentModel?.get("payLimit"))return!0;let e=await this.account.getBilling();if(e?.credit?.balance<10){return(await this.alertCtrl.create({header:"注意",subHeader:"您的余额不足,请充值后解锁高级模型",buttons:[{role:"cancel",text:"取消"},{role:"destructive",text:"充值",handler:()=>{this.router.navigateByUrl("/account/billing")}}]})).present(),!1}return!0}async getChatShare(){this.user=Parse.User.current();let e=new Parse.Query("ChatShare");e.equalTo("user",Parse.User.current().id),e.equalTo("session",this.chat?.sessionId);await e.first()}async toggleChatShare(){let e=new Parse.Query("ChatShare");e.equalTo("user",Parse.User.current().id),e.equalTo("role",this.chat?.role.id),e.equalTo("session",this.chat?.sessionId),e.select("objectId");let n=await e.first();if(n?.id)n.set("messageList",this.chat?.messageList);else{n=new(Parse.Object.extend("ChatShare")),n.set("user",{__type:"Pointer",className:"_User",objectId:Parse.User.current()?.id}),n.set("session",{__type:"Pointer",className:"ChatSession",objectId:this.chat?.sessionId}),n.set("role",{__type:"Pointer",className:"AvatarRole",objectId:this.chat?.role.id}),n.set("company",{__type:"Pointer",className:"Company",objectId:"E4KpGvTEto"}),n.set("messageList",this.chat?.messageList)}await n.save(),this.getChatShare()}chatShareSuccessMessage(){this.messages.success("分享成功")}showShare(){this.isShare=!0}handleOkShare(){this.toggleChatShare(),this.chatShareSuccessMessage(),this.isShare=!1}handleCancelShare(){this.isShare=!1}static{this.ɵfac=i0.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"17.3.12",ngImport:i0,type:FmChatModalInput,deps:[{token:i1.ToastController},{token:i1.AlertController},{token:i1.NavController},{token:i2.Router},{token:i3.ImagineService},{token:i4.ChatService},{token:i2.ActivatedRoute},{token:i5.NzMessageService}],target:i0.ɵɵFactoryTarget.Component})}static{this.ɵcmp=i0.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"17.3.12",type:FmChatModalInput,isStandalone:!0,selector:"fm-chat-modal-input",inputs:{chat:"chat",message:"message",role:"role"},viewQueries:[{propertyName:"audioComp",first:!0,predicate:ModalAudioMessageComponent,descendants:!0}],ngImport:i0,template:'<ion-toolbar>\n <ion-item class="button-item" lines="none">\n \x3c!-- 设置 --\x3e\n \x3c!-- <ion-button fill="outline" slot="start">\n <ion-icon name="settings-outline"></ion-icon> \n </ion-button> --\x3e\n <ng-container *ngFor="let button of chat?.leftButtons">\n <ion-button style="--padding-start:10px;--padding-end:10px;"\n shape="round" *ngIf="button.show()" fill="outline" [title]="button?.title" slot="start" (click)="button.onClick()">\n <ion-icon [name]="button?.icon" [slot]="button?.showTitle?\'start\':\'icon-only\'"></ion-icon>\n {{button?.showTitle&&button?.title}}\n </ion-button>\n </ng-container>\n\n <ng-container *ngFor="let button of chat?.role?.get(\'buttons\')">\n <ion-button shape="round" (click)="chatServ.doButtonAction(button)" fill="outline" slot="start">\n {{button?.name}}\n </ion-button>\n </ng-container>\n\n \x3c!--分享按钮--\x3e\n <ion-button shape="round" *ngIf="chat?.messageList?.length>1" (click)="showShare()" fill="outline" title="分享" slot="end">\n <ion-icon name="share-social-outline"></ion-icon>\n </ion-button>\n \x3c!-- <button nz-button *ngIf="chat?.messageList?.length>1"\n nzType="primary" title="分享" (click)="showShare()" style="width: 31.188px;height: 22px;box-shadow: none;background: #fff;border: 1px solid #4588ff;border-radius: 5px;"> <span class="iconfont icon-fenxiang" style="color: #4588ff;"></span></button>\n --\x3e\n <ion-modal [isOpen]="isShare">\n <ng-template>\n <ion-header>\n <ion-toolbar>\n <ion-buttons slot="start">\n <ion-button (click)="handleCancelShare()">取消</ion-button>\n </ion-buttons>\n <ion-title>对话分享</ion-title>\n <ion-buttons slot="end">\n <ion-button (click)="handleOkShare()">分享</ion-button>\n </ion-buttons>\n </ion-toolbar>\n </ion-header>\n <ion-content class="ion-padding">\n <div class="popup-content">\n <div *ngFor="let message of chat?.messageList">\n \x3c!-- 头像 --\x3e\n <div class="item-row user" *ngIf="message?.role!=\'system\'">\n <div>\n <nz-avatar *ngIf="message?.role!=\'user\'" [nzSrc]="(chat?.role?.get(\'avatar\') || chat?.role?.get(\'thumb\') || \'https://file-cloud.fmode.cn/E4KpGvTEto/20230930/l413e6090731854.png\')+\'?\'+\'x-image-process=image/resize,m_fixed,w_100\'+\'&imageView2/1/w/32/h/32\'"></nz-avatar>\n </div>\n <div class="user-question">\n <app-comp-user-avatar [user]="user" *ngIf="message?.role==\'user\'"></app-comp-user-avatar>\n </div>\n </div>\n \x3c!-- 内容 --\x3e\n <div class="message-wrapper">\n <div class="message-content-user">\n <div class="user-message" *ngIf="message?.role === \'user\'">\n <div class="item-content">\n \x3c!-- <fm-markdown-preview *ngIf="!message?.complete" class="content-style" [content]="message?.content" [render]="false"></fm-markdown-preview> --\x3e\n <fm-markdown-preview *ngIf="message?.complete" class="content-style" [content]="message?.content"></fm-markdown-preview>\n </div>\n </div>\n </div>\n <div class="message-content-role">\n <div class="role-message" *ngIf="message?.role !== \'user\' && message?.role !== \'system\'">\n <div class="item-content">\n \x3c!-- <fm-markdown-preview *ngIf="!message?.complete" class="content-style" [content]="message?.content" [render]="false"></fm-markdown-preview> --\x3e\n <fm-markdown-preview *ngIf="message?.complete" class="content-style" [content]="message?.content"></fm-markdown-preview>\n </div>\n </div>\n </div>\n <div class="message-content-system">\n <div class="system-message" *ngIf="message?.role === \'system\'">\n <div class="item-content">\n \x3c!-- <fm-markdown-preview *ngIf="!message?.complete" class="content-style" [content]="message?.content" [render]="false"></fm-markdown-preview> --\x3e\n <fm-markdown-preview *ngIf="message?.complete" class="content-style" [content]="message?.content"></fm-markdown-preview>\n </div>\n </div>\n </div>\n </div>\n <div class="chat-time" *ngIf="message?.createdAt" [ngClass]="{\'role-time\': message?.role !== \'user\'}">\n <span>{{message?.createdAt | date:"dd/MM/yyyy, HH/mm/ss a"}}</span>\n </div>\n </div>\n </div> \n </ion-content>\n </ng-template>\n </ion-modal>\n\n <nz-modal *ngIf="false"\n [(nzVisible)]="isShare"\n nzTitle="问答分享"\n nzCentered\n nzOkText="分享"\n nzCancelText="取消"\n (nzOnCancel)="handleCancelShare()"\n (nzOnOk)="handleOkShare()"\n >\n <ng-container *nzModalContent>\n <div class="popup-content">\n <div *ngFor="let message of chat?.messageList">\n \x3c!-- 头像 --\x3e\n <div class="item-row user" *ngIf="message?.role!=\'system\'">\n <div>\n <nz-avatar *ngIf="message?.role!=\'user\'" [nzSrc]="(chat?.role?.get(\'thumb\') || \'https://file-cloud.fmode.cn/E4KpGvTEto/20230930/l413e6090731854.png\')+\'?\'+\'x-image-process=image/resize,m_fixed,w_100\'+\'&imageView2/1/w/32/h/32\'"></nz-avatar>\n </div>\n <div class="user-question">\n <app-comp-user-avatar [user]="user" *ngIf="message?.role==\'user\'"></app-comp-user-avatar>\n </div>\n </div>\n \x3c!-- 内容 --\x3e\n <div class="message-wrapper">\n <div class="message-content-user">\n <div class="user-message" *ngIf="message?.role === \'user\'">\n <div class="item-content">\n \x3c!-- <fm-markdown-preview *ngIf="!message?.complete" class="content-style" [content]="message?.content" [render]="false"></fm-markdown-preview> --\x3e\n <fm-markdown-preview *ngIf="message?.complete" class="content-style" [content]="message?.content"></fm-markdown-preview>\n </div>\n </div>\n </div>\n <div class="message-content-role">\n <div class="role-message" *ngIf="message?.role !== \'user\' && message?.role !== \'system\'">\n <div class="item-content">\n \x3c!-- <fm-markdown-preview *ngIf="!message?.complete" class="content-style" [content]="message?.content" [render]="false"></fm-markdown-preview> --\x3e\n <fm-markdown-preview *ngIf="message?.complete" class="content-style" [content]="message?.content"></fm-markdown-preview>\n </div>\n </div>\n </div>\n <div class="message-content-system">\n <div class="system-message" *ngIf="message?.role === \'system\'">\n <div class="item-content">\n \x3c!-- <fm-markdown-preview *ngIf="!message?.complete" class="content-style" [content]="message?.content" [render]="false"></fm-markdown-preview> --\x3e\n <fm-markdown-preview *ngIf="message?.complete" class="content-style" [content]="message?.content"></fm-markdown-preview>\n </div>\n </div>\n </div>\n </div>\n <div class="chat-time" *ngIf="message?.createdAt" [ngClass]="{\'role-time\': message?.role !== \'user\'}">\n <span>{{message?.createdAt | date:"dd/MM/yyyy, HH/mm/ss a"}}</span>\n </div>\n </div>\n </div> \n </ng-container>\n </nz-modal>\n\n \x3c!-- 图片 --\x3e\n <ion-button shape="round" *ngIf="chatServ?.currentModel?.get(\'config\')?.imageEnabled" fill="outline" slot="end" (click)="setMessageImage()">\n <ion-icon name="image-outline"></ion-icon>\n </ion-button>\n \x3c!-- 模型 --\x3e\n <ion-button shape="round" fill="outline" slot="end" id="model-button">\n <ion-icon name="chevron-down-outline"></ion-icon>\n {{chatServ?.currentModel?.get&&chatServ?.currentModel?.get("name")||"飞码4.0"}}\n </ion-button>\n <ion-popover trigger="model-button" [dismissOnSelect]="true">\n <ng-template>\n <ion-content>\n <ion-list>\n <ng-container *ngFor="let model of chatServ.modelList">\n <ion-item (click)="chatServ.currentModel = model" [button]="true" [detail]="false">\n {{model?.get("name")}}\n <ion-note slot="end">{{model?.get("credit")}}/k</ion-note>\n </ion-item>\n </ng-container>\n </ion-list>\n </ion-content>\n </ng-template>\n </ion-popover>\n\n </ion-item>\n\n <ion-item class="input-item" lines="none">\n \x3c!-- 语音消息输入 --\x3e\n <ng-container *ngIf="chat?.isVoiceInputMode">\n \x3c!-- 切换文本输入 --\x3e\n <ion-button class="btn-input-change" color="primary" (click)="chat.isVoiceInputMode=false" shape="round" size="large">\n <ion-icon name="chatbox-ellipses-outline" slot="icon-only"></ion-icon>\n </ion-button>\n \n <div class="btn-voice-start" (click)="isAudioModal=true">\n <span>\n 点击讲话\n </span> \n </div>\n </ng-container>\n\n \x3c!-- 文本消息输入 --\x3e\n <ng-container *ngIf="!chat?.isVoiceInputMode">\n \x3c!-- 切换语音输入 --\x3e\n <ion-button [style.display]="chat.isTexting?\'none\':\'flex\'" class="btn-input-change" color="primary" *ngIf="chat?.role?.get(\'voiceConfig\')" (click)="chat.isVoiceInputMode=true" shape="round" size="large">\n <ion-icon name="mic-outline" slot="icon-only"></ion-icon>\n </ion-button>\n\n \x3c!-- 文本输入区域 --\x3e\n <ion-textarea *ngIf="chat" (keydown)="onKeyDown($event)"\n [errorText]="errorText"\n [(ngModel)]="chat.userInput"\n (ionFocus)="chat.isTexting=true"\n (ionBlur)="chat.isTexting=false"\n [autoGrow]="true" shape="round" fill="outline"\n label="Ctrl + Enter 发送消息" placeholder="请输入您的提示词"\n labelPlacement="floating"></ion-textarea>\n \n \x3c!-- 文本发送按钮 --\x3e\n <ion-button color="primary" shape="round" size="large" (click)="sendMessage()">\n <ion-icon name="paper-plane-outline" slot="icon-only"></ion-icon>\n </ion-button>\n </ng-container>\n </ion-item>\n</ion-toolbar>\n\n\n\x3c!-- 语音消息输入:弹出区域 --\x3e\n<ion-modal #audioModal [isOpen]="isAudioModal" (willDismiss)="closeAudio()" [initialBreakpoint]="0.35" [breakpoints]="[0, 0.35, 0.5]">\n <ng-template>\n <fm-modal-audio-message #audioComp *ngIf="isAudioModal" [chat]="chat" [modal]="audioModal"></fm-modal-audio-message>\n </ng-template>\n</ion-modal>',styles:['@charset "UTF-8";:host-context(body.dark) .btn-voice-start{background-color:#222428;color:#fff}:host-context(body.dark) ion-textarea{background-color:#222428;color:#fff}ion-toolbar{--background:none}ion-toolbar .button-item{--inner-padding-start:5px;--inner-padding-end:0px;--padding-start:5px;--padding-end:0px}ion-toolbar ion-item{--background:transparent}ion-textarea.custom{--background: #373737;--color: #fff;--padding-end: 10px;--padding-start: 10px;--placeholder-color: #ddd;--placeholder-opacity: .8}ion-textarea.custom textarea{width:calc(100% - 95px)}ion-textarea.custom ion-button{position:absolute;right:0}.input-item{display:flex;min-height:77px;align-items:center;border:none;--inner-padding-start:0px;--inner-padding-end:0px;--padding-start:0px;--padding-end:0px}.input-item ion-textarea{background-color:#fff;max-height:400px;padding:0 5px;margin:0 5px;border-radius:20px;overflow-y:auto}.input-item .btn-voice-start{display:flex;flex:1;justify-content:center;align-items:center;font-weight:700;background:#fff;border-radius:20px;min-height:50px}ion-textarea{transition:width .5s ease}ion-textarea:hover .btn-input-change,ion-textarea:focus-within .btn-input-change{display:none}.input-item:hover ion-textarea,.input-item:focus-within ion-textarea{border-color:var(--logo-color-primary)}::ng-deep .ant-modal-body{max-height:600px;overflow-y:auto}::ng-deep .ant-modal-footer{display:flex;justify-content:space-around}::ng-deep .ant-btn{width:40%}.popup-content{position:relative}.popup-content .message-content-user{display:flex;justify-content:flex-end}.popup-content .message-content-role{display:flex;justify-content:flex-start}.popup-content .message-content-system{display:flex;justify-content:center}.popup-content .user-message{padding:10px 10px 0;border-radius:10px;width:fit-content;max-width:100%;background-color:#e7f8ff}.popup-content .role-message{padding:10px 10px 0;border-radius:10px;width:fit-content;max-width:100%;background-color:#f6f6f6}.popup-content .user-question{margin-bottom:5px;display:flex;justify-content:flex-end}.popup-content .chat-time{margin-bottom:10px;display:flex;justify-content:flex-end;font-size:14px;color:#a3a3a3}.popup-content .role-time{justify-content:flex-start}\n'],dependencies:[{kind:"ngmodule",type:CommonModule},{kind:"directive",type:i6.NgClass,selector:"[ngClass]",inputs:["class","ngClass"]},{kind:"directive",type:i6.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:i6.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"pipe",type:i6.DatePipe,name:"date"},{kind:"ngmodule",type:FormsModule},{kind:"directive",type:i7.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:i7.NgModel,selector:"[ngModel]:not([formControlName]):not([formControl])",inputs:["name","disabled","ngModel","ngModelOptions"],outputs:["ngModelChange"],exportAs:["ngModel"]},{kind:"ngmodule",type:ReactiveFormsModule},{kind:"ngmodule",type:RouterModule},{kind:"component",type:IonToolbar,selector:"ion-toolbar",inputs:["color","mode"]},{kind:"component",type:IonItem,selector:"ion-item",inputs:["button","color","detail","detailIcon","disabled","download","href","lines","mode","rel","routerAnimation","routerDirection","target","type"]},{kind:"component",type:IonButton,selector:"ion-button",inputs:["buttonType","color","disabled","download","expand","fill","form","href","mode","rel","routerAnimation","routerDirection","shape","size","strong","target","type"]},{kind:"component",type:IonList,selector:"ion-list",inputs:["inset","lines","mode"]},{kind:"component",type:IonModal,selector:"ion-modal"},{kind:"component",type:IonIcon,selector:"ion-icon",inputs:["color","flipRtl","icon","ios","lazy","md","mode","name","sanitize","size","src"]},{kind:"component",type:IonTextarea,selector:"ion-textarea",inputs:["autoGrow","autocapitalize","autofocus","clearOnEdit","color","cols","counter","counterFormatter","debounce","disabled","enterkeyhint","errorText","fill","helperText","inputmode","label","labelPlacement","maxlength","minlength","mode","name","placeholder","readonly","required","rows","shape","spellcheck","value","wrap"]},{kind:"component",type:IonPopover,selector:"ion-popover"},{kind:"component",type:IonContent,selector:"ion-content",inputs:["color","fixedSlotPlacement","forceOverscroll","fullscreen","scrollEvents","scrollX","scrollY"]},{kind:"ngmodule",type:NzModalModule},{kind:"component",type:i8.NzModalComponent,selector:"nz-modal",inputs:["nzMask","nzMaskClosable","nzCloseOnNavigation","nzVisible","nzClosable","nzOkLoading","nzOkDisabled","nzCancelDisabled","nzCancelLoading","nzKeyboard","nzNoAnimation","nzCentered","nzDraggable","nzContent","nzFooter","nzZIndex","nzWidth","nzWrapClassName","nzClassName","nzStyle","nzTitle","nzCloseIcon","nzMaskStyle","nzBodyStyle","nzOkText","nzCancelText","nzOkType","nzOkDanger","nzIconType","nzModalType","nzAutofocus","nzOnOk","nzOnCancel"],outputs:["nzOnOk","nzOnCancel","nzAfterOpen","nzAfterClose","nzVisibleChange"],exportAs:["nzModal"]},{kind:"directive",type:i8.NzModalContentDirective,selector:"[nzModalContent]",exportAs:["nzModalContent"]},{kind:"component",type:ModalAudioMessageComponent,selector:"fm-modal-audio-message",inputs:["chat","modal"]}]})}}i0.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"17.3.12",ngImport:i0,type:FmChatModalInput,decorators:[{type:Component,args:[{selector:"fm-chat-modal-input",standalone:!0,imports:[CommonModule,FormsModule,ReactiveFormsModule,RouterModule,IonToolbar,IonItem,IonButton,IonList,IonModal,IonInput,IonIcon,IonTextarea,IonPopover,IonContent,NzModalModule,ModalAudioMessageComponent],template:'<ion-toolbar>\n <ion-item class="button-item" lines="none">\n \x3c!-- 设置 --\x3e\n \x3c!-- <ion-button fill="outline" slot="start">\n <ion-icon name="settings-outline"></ion-icon> \n </ion-button> --\x3e\n <ng-container *ngFor="let button of chat?.leftButtons">\n <ion-button style="--padding-start:10px;--padding-end:10px;"\n shape="round" *ngIf="button.show()" fill="outline" [title]="button?.title" slot="start" (click)="button.onClick()">\n <ion-icon [name]="button?.icon" [slot]="button?.showTitle?\'start\':\'icon-only\'"></ion-icon>\n {{button?.showTitle&&button?.title}}\n </ion-button>\n </ng-container>\n\n <ng-container *ngFor="let button of chat?.role?.get(\'buttons\')">\n <ion-button shape="round" (click)="chatServ.doButtonAction(button)" fill="outline" slot="start">\n {{button?.name}}\n </ion-button>\n </ng-container>\n\n \x3c!--分享按钮--\x3e\n <ion-button shape="round" *ngIf="chat?.messageList?.length>1" (click)="showShare()" fill="outline" title="分享" slot="end">\n <ion-icon name="share-social-outline"></ion-icon>\n </ion-button>\n \x3c!-- <button nz-button *ngIf="chat?.messageList?.length>1"\n nzType="primary" title="分享" (click)="showShare()" style="width: 31.188px;height: 22px;box-shadow: none;background: #fff;border: 1px solid #4588ff;border-radius: 5px;"> <span class="iconfont icon-fenxiang" style="color: #4588ff;"></span></button>\n --\x3e\n <ion-modal [isOpen]="isShare">\n <ng-template>\n <ion-header>\n <ion-toolbar>\n <ion-buttons slot="start">\n <ion-button (click)="handleCancelShare()">取消</ion-button>\n </ion-buttons>\n <ion-title>对话分享</ion-title>\n <ion-buttons slot="end">\n <ion-button (click)="handleOkShare()">分享</ion-button>\n </ion-buttons>\n </ion-toolbar>\n </ion-header>\n <ion-content class="ion-padding">\n <div class="popup-content">\n <div *ngFor="let message of chat?.messageList">\n \x3c!-- 头像 --\x3e\n <div class="item-row user" *ngIf="message?.role!=\'system\'">\n <div>\n <nz-avatar *ngIf="message?.role!=\'user\'" [nzSrc]="(chat?.role?.get(\'avatar\') || chat?.role?.get(\'thumb\') || \'https://file-cloud.fmode.cn/E4KpGvTEto/20230930/l413e6090731854.png\')+\'?\'+\'x-image-process=image/resize,m_fixed,w_100\'+\'&imageView2/1/w/32/h/32\'"></nz-avatar>\n </div>\n <div class="user-question">\n <app-comp-user-avatar [user]="user" *ngIf="message?.role==\'user\'"></app-comp-user-avatar>\n </div>\n </div>\n \x3c!-- 内容 --\x3e\n <div class="message-wrapper">\n <div class="message-content-user">\n <div class="user-message" *ngIf="message?.role === \'user\'">\n <div class="item-content">\n \x3c!-- <fm-markdown-preview *ngIf="!message?.complete" class="content-style" [content]="message?.content" [render]="false"></fm-markdown-preview> --\x3e\n <fm-markdown-preview *ngIf="message?.complete" class="content-style" [content]="message?.content"></fm-markdown-preview>\n </div>\n </div>\n </div>\n <div class="message-content-role">\n <div class="role-message" *ngIf="message?.role !== \'user\' && message?.role !== \'system\'">\n <div class="item-content">\n \x3c!-- <fm-markdown-preview *ngIf="!message?.complete" class="content-style" [content]="message?.content" [render]="false"></fm-markdown-preview> --\x3e\n <fm-markdown-preview *ngIf="message?.complete" class="content-style" [content]="message?.content"></fm-markdown-preview>\n </div>\n </div>\n </div>\n <div class="message-content-system">\n <div class="system-message" *ngIf="message?.role === \'system\'">\n <div class="item-content">\n \x3c!-- <fm-markdown-preview *ngIf="!message?.complete" class="content-style" [content]="message?.content" [render]="false"></fm-markdown-preview> --\x3e\n <fm-markdown-preview *ngIf="message?.complete" class="content-style" [content]="message?.content"></fm-markdown-preview>\n </div>\n </div>\n </div>\n </div>\n <div class="chat-time" *ngIf="message?.createdAt" [ngClass]="{\'role-time\': message?.role !== \'user\'}">\n <span>{{message?.createdAt | date:"dd/MM/yyyy, HH/mm/ss a"}}</span>\n </div>\n </div>\n </div> \n </ion-content>\n </ng-template>\n </ion-modal>\n\n <nz-modal *ngIf="false"\n [(nzVisible)]="isShare"\n nzTitle="问答分享"\n nzCentered\n nzOkText="分享"\n nzCancelText="取消"\n (nzOnCancel)="handleCancelShare()"\n (nzOnOk)="handleOkShare()"\n >\n <ng-container *nzModalContent>\n <div class="popup-content">\n <div *ngFor="let message of chat?.messageList">\n \x3c!-- 头像 --\x3e\n <div class="item-row user" *ngIf="message?.role!=\'system\'">\n <div>\n <nz-avatar *ngIf="message?.role!=\'user\'" [nzSrc]="(chat?.role?.get(\'thumb\') || \'https://file-cloud.fmode.cn/E4KpGvTEto/20230930/l413e6090731854.png\')+\'?\'+\'x-image-process=image/resize,m_fixed,w_100\'+\'&imageView2/1/w/32/h/32\'"></nz-avatar>\n </div>\n <div class="user-question">\n <app-comp-user-avatar [user]="user" *ngIf="message?.role==\'user\'"></app-comp-user-avatar>\n </div>\n </div>\n \x3c!-- 内容 --\x3e\n <div class="message-wrapper">\n <div class="message-content-user">\n <div class="user-message" *ngIf="message?.role === \'user\'">\n <div class="item-content">\n \x3c!-- <fm-markdown-preview *ngIf="!message?.complete" class="content-style" [content]="message?.content" [render]="false"></fm-markdown-preview> --\x3e\n <fm-markdown-preview *ngIf="message?.complete" class="content-style" [content]="message?.content"></fm-markdown-preview>\n </div>\n </div>\n </div>\n <div class="message-content-role">\n <div class="role-message" *ngIf="message?.role !== \'user\' && message?.role !== \'system\'">\n <div class="item-content">\n \x3c!-- <fm-markdown-preview *ngIf="!message?.complete" class="content-style" [content]="message?.content" [render]="false"></fm-markdown-preview> --\x3e\n <fm-markdown-preview *ngIf="message?.complete" class="content-style" [content]="message?.content"></fm-markdown-preview>\n </div>\n </div>\n </div>\n <div class="message-content-system">\n <div class="system-message" *ngIf="message?.role === \'system\'">\n <div class="item-content">\n \x3c!-- <fm-markdown-preview *ngIf="!message?.complete" class="content-style" [content]="message?.content" [render]="false"></fm-markdown-preview> --\x3e\n <fm-markdown-preview *ngIf="message?.complete" class="content-style" [content]="message?.content"></fm-markdown-preview>\n </div>\n </div>\n </div>\n </div>\n <div class="chat-time" *ngIf="message?.createdAt" [ngClass]="{\'role-time\': message?.role !== \'user\'}">\n <span>{{message?.createdAt | date:"dd/MM/yyyy, HH/mm/ss a"}}</span>\n </div>\n </div>\n </div> \n </ng-container>\n </nz-modal>\n\n \x3c!-- 图片 --\x3e\n <ion-button shape="round" *ngIf="chatServ?.currentModel?.get(\'config\')?.imageEnabled" fill="outline" slot="end" (click)="setMessageImage()">\n <ion-icon name="image-outline"></ion-icon>\n </ion-button>\n \x3c!-- 模型 --\x3e\n <ion-button shape="round" fill="outline" slot="end" id="model-button">\n <ion-icon name="chevron-down-outline"></ion-icon>\n {{chatServ?.currentModel?.get&&chatServ?.currentModel?.get("name")||"飞码4.0"}}\n </ion-button>\n <ion-popover trigger="model-button" [dismissOnSelect]="true">\n <ng-template>\n <ion-content>\n <ion-list>\n <ng-container *ngFor="let model of chatServ.modelList">\n <ion-item (click)="chatServ.currentModel = model" [button]="true" [detail]="false">\n {{model?.get("name")}}\n <ion-note slot="end">{{model?.get("credit")}}/k</ion-note>\n </ion-item>\n </ng-container>\n </ion-list>\n </ion-content>\n </ng-template>\n </ion-popover>\n\n </ion-item>\n\n <ion-item class="input-item" lines="none">\n \x3c!-- 语音消息输入 --\x3e\n <ng-container *ngIf="chat?.isVoiceInputMode">\n \x3c!-- 切换文本输入 --\x3e\n <ion-button class="btn-input-change" color="primary" (click)="chat.isVoiceInputMode=false" shape="round" size="large">\n <ion-icon name="chatbox-ellipses-outline" slot="icon-only"></ion-icon>\n </ion-button>\n \n <div class="btn-voice-start" (click)="isAudioModal=true">\n <span>\n 点击讲话\n </span> \n </div>\n </ng-container>\n\n \x3c!-- 文本消息输入 --\x3e\n <ng-container *ngIf="!chat?.isVoiceInputMode">\n \x3c!-- 切换语音输入 --\x3e\n <ion-button [style.display]="chat.isTexting?\'none\':\'flex\'" class="btn-input-change" color="primary" *ngIf="chat?.role?.get(\'voiceConfig\')" (click)="chat.isVoiceInputMode=true" shape="round" size="large">\n <ion-icon name="mic-outline" slot="icon-only"></ion-icon>\n </ion-button>\n\n \x3c!-- 文本输入区域 --\x3e\n <ion-textarea *ngIf="chat" (keydown)="onKeyDown($event)"\n [errorText]="errorText"\n [(ngModel)]="chat.userInput"\n (ionFocus)="chat.isTexting=true"\n (ionBlur)="chat.isTexting=false"\n [autoGrow]="true" shape="round" fill="outline"\n label="Ctrl + Enter 发送消息" placeholder="请输入您的提示词"\n labelPlacement="floating"></ion-textarea>\n \n \x3c!-- 文本发送按钮 --\x3e\n <ion-button color="primary" shape="round" size="large" (click)="sendMessage()">\n <ion-icon name="paper-plane-outline" slot="icon-only"></ion-icon>\n </ion-button>\n </ng-container>\n </ion-item>\n</ion-toolbar>\n\n\n\x3c!-- 语音消息输入:弹出区域 --\x3e\n<ion-modal #audioModal [isOpen]="isAudioModal" (willDismiss)="closeAudio()" [initialBreakpoint]="0.35" [breakpoints]="[0, 0.35, 0.5]">\n <ng-template>\n <fm-modal-audio-message #audioComp *ngIf="isAudioModal" [chat]="chat" [modal]="audioModal"></fm-modal-audio-message>\n </ng-template>\n</ion-modal>',styles:['@charset "UTF-8";:host-context(body.dark) .btn-voice-start{background-color:#222428;color:#fff}:host-context(body.dark) ion-textarea{background-color:#222428;color:#fff}ion-toolbar{--background:none}ion-toolbar .button-item{--inner-padding-start:5px;--inner-padding-end:0px;--padding-start:5px;--padding-end:0px}ion-toolbar ion-item{--background:transparent}ion-textarea.custom{--background: #373737;--color: #fff;--padding-end: 10px;--padding-start: 10px;--placeholder-color: #ddd;--placeholder-opacity: .8}ion-textarea.custom textarea{width:calc(100% - 95px)}ion-textarea.custom ion-button{position:absolute;right:0}.input-item{display:flex;min-height:77px;align-items:center;border:none;--inner-padding-start:0px;--inner-padding-end:0px;--padding-start:0px;--padding-end:0px}.input-item ion-textarea{background-color:#fff;max-height:400px;padding:0 5px;margin:0 5px;border-radius:20px;overflow-y:auto}.input-item .btn-voice-start{display:flex;flex:1;justify-content:center;align-items:center;font-weight:700;background:#fff;border-radius:20px;min-height:50px}ion-textarea{transition:width .5s ease}ion-textarea:hover .btn-input-change,ion-textarea:focus-within .btn-input-change{display:none}.input-item:hover ion-textarea,.input-item:focus-within ion-textarea{border-color:var(--logo-color-primary)}::ng-deep .ant-modal-body{max-height:600px;overflow-y:auto}::ng-deep .ant-modal-footer{display:flex;justify-content:space-around}::ng-deep .ant-btn{width:40%}.popup-content{position:relative}.popup-content .message-content-user{display:flex;justify-content:flex-end}.popup-content .message-content-role{display:flex;justify-content:flex-start}.popup-content .message-content-system{display:flex;justify-content:center}.popup-content .user-message{padding:10px 10px 0;border-radius:10px;width:fit-content;max-width:100%;background-color:#e7f8ff}.popup-content .role-message{padding:10px 10px 0;border-radius:10px;width:fit-content;max-width:100%;background-color:#f6f6f6}.popup-content .user-question{margin-bottom:5px;display:flex;justify-content:flex-end}.popup-content .chat-time{margin-bottom:10px;display:flex;justify-content:flex-end;font-size:14px;color:#a3a3a3}.popup-content .role-time{justify-content:flex-start}\n']}]}],ctorParameters:()=>[{type:i1.ToastController},{type:i1.AlertController},{type:i1.NavController},{type:i2.Router},{type:i3.ImagineService},{type:i4.ChatService},{type:i2.ActivatedRoute},{type:i5.NzMessageService}],propDecorators:{audioComp:[{type:ViewChild,args:[ModalAudioMessageComponent]}],chat:[{type:Input}],message:[{type:Input}],role:[{type:Input}]}});
|
|
9
9
|
var MODULE_PATH_NEED = `6K+l5paH5Lu25piv5pys6aG555uu55qE5LiA6YOo5YiGIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBDb21wb25lbnRzIGluIEZtb2RlIEluYy4KICAgIOeJiOadg+aJgOaciSDCqSDmnKrmnaXpo57pqawgwqkg5rGf6KW/6ISR5o6n56eR5oqA5pyJ6ZmQ5YWs5Y+4IENvcHlyaWdodCDCqSBGbW9kZSBUZWNobm9sb2d5IENvLiwgTHRkLgogICAg5L+d55WZ5omA5pyJ5p2D5YipIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAgICDkuKXnpoHlnKjmnKrnu4/mjojmnYPnmoTmg4XlhrXkuIvvvIzpgJrov4fku7vkvZXlqpLku4vlpI3liLbmraTmlofku7YgVW5hdXRob3JpemVkIGNvcHlpbmcgb2YgdGhpcyBmaWxlLCB2aWEgYW55IG1lZGl1bSBpcyBzdHJpY3RseSBwcm9oaWJpdGVkCiAgICDor6Xmlofku7bmmK/kuJPmnInnmoTmnLrlr4bmlofku7YgUHJvcHJpZXRhcnkgYW5kIGNvbmZpZGVudGlhbAogICAKICAgIENvcHlyaWdodCAyMDIxLW5vdyBGbW9kZSBJbmMuIHN1cHBvcnRAZm1vZGUuY24uIDE4NjA3MDA3MDczLgogICAg5L+d55WZ5omA5pyJ5p2D5YipIEFsbCByaWdodHMgcmVzZXJ2ZWQuCgogICAgUEFUSDovaG9tZS9yeWFuL3dvcmtzcGFjZS9ub3ZhL25vdmEtYWRtaW4vZGlzdC9mbW9kZS1uZy9lc20yMDIyL2xpYi9haWdjL2NoYXQvY2hhdC1tb2RhbC1pbnB1dC9tb2RhbC1pbnB1dC5jb21wb25lbnQubWpz`
|
|
10
10
|
|
|
@@ -5,6 +5,6 @@
|
|
|
5
5
|
* 保留所有权利 All Rights Reserved.
|
|
6
6
|
* /home/ryan/workspace/nova/nova-admin/dist/fmode-ng/esm2022/lib/aigc/chat/comp-role-prompt/comp-role-prompt.component.mjs
|
|
7
7
|
*/
|
|
8
|
-
import{Component,Input}from"@angular/core";import{FmodeChat}from"../../service-fmai/service-chat";import*as Parse from"parse";import{IonButton,IonLabel,IonModal,IonSegment,ModalController}from"@ionic/angular/standalone";import{CommonModule}from"@angular/common";import{NzIconModule}from"ng-zorro-antd/icon";import{FormsModule,ReactiveFormsModule}from"@angular/forms";import{CrossService}from"../../../platform/cross.service";import*as i0 from"@angular/core";import*as i1 from"../../../platform/cross.service";import*as i2 from"@ionic/angular/standalone";import*as i3 from"@angular/common";import*as i4 from"ng-zorro-antd/icon";export class CompRolePromptComponent{constructor(e,o){this.cross=e,this.modalController=o,this.role="",this.showModal=!1,this.cateIndex=0,this.company="E4KpGvTEto"}ngOnInit(){this.getChatPrompt()}applyPrompt(e){this.chat.userInput=e,this.chat.isVoiceInputMode=!1,"mobile"==this.cross?.navMenuType&&this.modalController.dismiss()}async getChatPrompt(){let e=new Parse.Query("ChatPrompt");e.notEqualTo("isDeleted",!0),e.equalTo("company",this.company),e.equalTo("role",this.role),e.include("role");let o=await e.find();this.chat.promptList=o,this.chat.promptList.forEach((e=>{let o=e.get("role").get("promptCates").filter((o=>o.name==e.get("cate")));e.img=o[0].img})),console.log(this.chat.promptList)}checkCate(e){this.cateIndex=e}static{this.ɵfac=i0.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"17.3.12",ngImport:i0,type:CompRolePromptComponent,deps:[{token:i1.CrossService},{token:i2.ModalController}],target:i0.ɵɵFactoryTarget.Component})}static{this.ɵcmp=i0.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"17.3.12",type:CompRolePromptComponent,isStandalone:!0,selector:"app-comp-role-prompt",inputs:{chat:"chat",role:"role"},providers:[ModalController],ngImport:i0,template:'<ng-container *ngIf="chat?.isPromptMessageAreaShow && !chat?.userInput">\n <div class="prompt" *ngIf="cross?.navMenuType!=\'mobile\'">\n <ng-container *ngFor="let content of chat?.promptList">\n <div class="prompt_cate">\n <div class="cate_info">\n <div>\n <img [src]="content.img" alt="">\n </div>\n <div class="cate_name">\n {{content.get(\'cate\')}}\n </div>\n </div>\n <ng-container *ngFor="let message of content.get(\'messageList\')">\n <div class="message" (click)="applyPrompt(message)" nz-tooltip [nzTooltipTitle]="message"\n nzTooltipColor="#108ee9">\n {{message}}\n </div>\n </ng-container>\n </div>\n </ng-container>\n </div>\n <ng-container *ngIf="cross?.navMenuType==\'mobile\'">\n <div class="prompt_mobile">\n <ng-container *ngFor="let content of chat?.promptList">\n <div class="prompt_cate">\n <div class="cate_info">\n <div>\n <img [src]="content.img" alt="">\n </div>\n <div class="cate_name">\n {{content.get(\'cate\')}}\n </div>\n </div>\n <ng-container *ngFor="let message of content.get(\'messageList\');let idx = index">\n <div *ngIf="idx<3" class="message" (click)="applyPrompt(message)" nz-tooltip [nzTooltipTitle]="message"\n nzTooltipColor="#108ee9">\n {{message}}\n </div>\n </ng-container>\n </div>\n </ng-container>\n </div>\n <div class="view_more" *ngIf="chat?.promptList?.length">\n <button (click)="chat.isPromptModalOpen=true" expand="block">查看更多<span nz-icon nzType="right" nzTheme="outline"></span></button>\n </div>\n</ng-container>\n\n\n <ion-modal [isOpen]="chat.isPromptModalOpen" (willDismiss)="chat.isPromptModalOpen=false" [initialBreakpoint]="1" [breakpoints]="[0, 1]">\n <ng-template>\n <div class="block">\n <ion-label>话题灵感</ion-label>\n <div class="block_cate">\n \x3c!-- <ion-segment [(ngModel)]="cateIndex">\n <ng-container *ngFor="let prompt of chat?.promptList;let i = index">\n <ion-segment-button value="i">\n <ion-label>{{prompt?.get("cate")}}</ion-label>\n </ion-segment-button>\n </ng-container>\n </ion-segment> --\x3e\n <ng-container *ngFor="let prompt of chat?.promptList;let i = index">\n <ion-button [color]="i==cateIndex?\'secondary\':\'light\'" (click)="checkCate(i)">{{prompt?.get("cate")}}</ion-button>\n \x3c!-- <div [class]="i==cateIndex?\'active_cate\':\'\'" (click)="checkCate(i)">{{prompt?.get("cate")}}</div> --\x3e\n </ng-container>\n </div>\n <div class="message_mobile">\n <ng-container *ngFor="let message of chat?.promptList[cateIndex]?.get(\'messageList\')">\n <div (click)="applyPrompt(message)">{{message}}</div>\n </ng-container>\n </div>\n </div>\n </ng-template>\n </ion-modal>\n</ng-container>',styles:[":host-context(body.dark) .cate_info{color:#fff}:host-context(body.dark) ion-modal .block h4{color:#fff!important}.prompt{color:#000;display:flex;justify-content:space-between;align-items:flex-start}.prompt .prompt_cate{flex:1;height:inherit;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex-direction:column;display:flex;justify-content:center}.prompt .prompt_cate .cate_info{font-size:1.5em;font-weight:700}.prompt .prompt_cate .cate_info div img{width:58px;height:58px}.prompt .prompt_cate .cate_info .cate_name{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.prompt .prompt_cate .message{padding:1em;margin:1em;background:#fff;border:1px solid #eef2f2;border-radius:12px;box-shadow:0 2px 8px #f5f6f8;cursor:pointer;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}@media screen and (max-width: 390.4px){.prompt .prompt_cate .message{width:100px;height:64px;padding:unset;margin:.8em;background:#fff;border:1px solid #eef2f2;border-radius:12px;box-shadow:0 2px 8px #f5f6f8;cursor:pointer;overflow:hidden;white-space:pre-wrap;text-overflow:ellipsis}}.prompt_mobile{color:#000;display:flex;justify-content:space-between;align-items:flex-start}.prompt_mobile .prompt_cate{flex:1;height:inherit}.prompt_mobile .prompt_cate .cate_info{display:flex;justify-content:center;align-items:center;font-size:1.2em}.prompt_mobile .prompt_cate .cate_info div img{width:48px;height:48px}.prompt_mobile .prompt_cate .cate_info .cate_name{display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:1;overflow:hidden;text-overflow:ellipsis;margin-top:2vw}.prompt_mobile .prompt_cate .message{min-height:48px;padding:0 2vw;margin:4vw 1vw;background:#fff;border:1px solid #eef2f2;border-radius:12px;box-shadow:0 2px 8px #f5f6f8;cursor:pointer;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;overflow:hidden;text-overflow:ellipsis}.view_more{text-align:center;color:#999;margin:4vw 0}.view_more>button{background-color:transparent}.block{width:100%;height:80vh;padding:2vw}.block .block_cate{display:flex;justify-content:space-between}.block .message_mobile{overflow-y:auto;height:65vh;color:#000}.block .message_mobile>div{background-color:#fff;text-align:center;padding:3vw 0;margin:3vw 0;border-radius:4px;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}ion-modal{--height: auto}\n"],dependencies:[{kind:"ngmodule",type:CommonModule},{kind:"directive",type:i3.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:i3.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"ngmodule",type:FormsModule},{kind:"ngmodule",type:ReactiveFormsModule},{kind:"component",type:IonModal,selector:"ion-modal"},{kind:"component",type:IonButton,selector:"ion-button",inputs:["buttonType","color","disabled","download","expand","fill","form","href","mode","rel","routerAnimation","routerDirection","shape","size","strong","target","type"]},{kind:"component",type:IonLabel,selector:"ion-label",inputs:["color","mode","position"]},{kind:"ngmodule",type:NzIconModule},{kind:"directive",type:i4.NzIconDirective,selector:"[nz-icon]",inputs:["nzSpin","nzRotate","nzType","nzTheme","nzTwotoneColor","nzIconfont"],exportAs:["nzIcon"]}]})}}i0.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"17.3.12",ngImport:i0,type:CompRolePromptComponent,decorators:[{type:Component,args:[{selector:"app-comp-role-prompt",standalone:!0,imports:[CommonModule,FormsModule,ReactiveFormsModule,IonModal,IonButton,IonSegment,IonLabel,NzIconModule],providers:[ModalController],template:'<ng-container *ngIf="chat?.isPromptMessageAreaShow && !chat?.userInput">\n <div class="prompt" *ngIf="cross?.navMenuType!=\'mobile\'">\n <ng-container *ngFor="let content of chat?.promptList">\n <div class="prompt_cate">\n <div class="cate_info">\n <div>\n <img [src]="content.img" alt="">\n </div>\n <div class="cate_name">\n {{content.get(\'cate\')}}\n </div>\n </div>\n <ng-container *ngFor="let message of content.get(\'messageList\')">\n <div class="message" (click)="applyPrompt(message)" nz-tooltip [nzTooltipTitle]="message"\n nzTooltipColor="#108ee9">\n {{message}}\n </div>\n </ng-container>\n </div>\n </ng-container>\n </div>\n <ng-container *ngIf="cross?.navMenuType==\'mobile\'">\n <div class="prompt_mobile">\n <ng-container *ngFor="let content of chat?.promptList">\n <div class="prompt_cate">\n <div class="cate_info">\n <div>\n <img [src]="content.img" alt="">\n </div>\n <div class="cate_name">\n {{content.get(\'cate\')}}\n </div>\n </div>\n <ng-container *ngFor="let message of content.get(\'messageList\');let idx = index">\n <div *ngIf="idx<3" class="message" (click)="applyPrompt(message)" nz-tooltip [nzTooltipTitle]="message"\n nzTooltipColor="#108ee9">\n {{message}}\n </div>\n </ng-container>\n </div>\n </ng-container>\n </div>\n <div class="view_more" *ngIf="chat?.promptList?.length">\n <button (click)="chat.isPromptModalOpen=true" expand="block">查看更多<span nz-icon nzType="right" nzTheme="outline"></span></button>\n </div>\n</ng-container>\n\n\n <ion-modal [isOpen]="chat.isPromptModalOpen" (willDismiss)="chat.isPromptModalOpen=false" [initialBreakpoint]="1" [breakpoints]="[0, 1]">\n <ng-template>\n <div class="block">\n <ion-label>话题灵感</ion-label>\n <div class="block_cate">\n \x3c!-- <ion-segment [(ngModel)]="cateIndex">\n <ng-container *ngFor="let prompt of chat?.promptList;let i = index">\n <ion-segment-button value="i">\n <ion-label>{{prompt?.get("cate")}}</ion-label>\n </ion-segment-button>\n </ng-container>\n </ion-segment> --\x3e\n <ng-container *ngFor="let prompt of chat?.promptList;let i = index">\n <ion-button [color]="i==cateIndex?\'secondary\':\'light\'" (click)="checkCate(i)">{{prompt?.get("cate")}}</ion-button>\n \x3c!-- <div [class]="i==cateIndex?\'active_cate\':\'\'" (click)="checkCate(i)">{{prompt?.get("cate")}}</div> --\x3e\n </ng-container>\n </div>\n <div class="message_mobile">\n <ng-container *ngFor="let message of chat?.promptList[cateIndex]?.get(\'messageList\')">\n <div (click)="applyPrompt(message)">{{message}}</div>\n </ng-container>\n </div>\n </div>\n </ng-template>\n </ion-modal>\n</ng-container>',styles:[":host-context(body.dark) .cate_info{color:#fff}:host-context(body.dark) ion-modal .block h4{color:#fff!important}.prompt{color:#000;display:flex;justify-content:space-between;align-items:flex-start}.prompt .prompt_cate{flex:1;height:inherit;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex-direction:column;display:flex;justify-content:center}.prompt .prompt_cate .cate_info{font-size:1.5em;font-weight:700}.prompt .prompt_cate .cate_info div img{width:58px;height:58px}.prompt .prompt_cate .cate_info .cate_name{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.prompt .prompt_cate .message{padding:1em;margin:1em;background:#fff;border:1px solid #eef2f2;border-radius:12px;box-shadow:0 2px 8px #f5f6f8;cursor:pointer;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}@media screen and (max-width: 390.4px){.prompt .prompt_cate .message{width:100px;height:64px;padding:unset;margin:.8em;background:#fff;border:1px solid #eef2f2;border-radius:12px;box-shadow:0 2px 8px #f5f6f8;cursor:pointer;overflow:hidden;white-space:pre-wrap;text-overflow:ellipsis}}.prompt_mobile{color:#000;display:flex;justify-content:space-between;align-items:flex-start}.prompt_mobile .prompt_cate{flex:1;height:inherit}.prompt_mobile .prompt_cate .cate_info{display:flex;justify-content:center;align-items:center;font-size:1.2em}.prompt_mobile .prompt_cate .cate_info div img{width:48px;height:48px}.prompt_mobile .prompt_cate .cate_info .cate_name{display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:1;overflow:hidden;text-overflow:ellipsis;margin-top:2vw}.prompt_mobile .prompt_cate .message{min-height:48px;padding:0 2vw;margin:4vw 1vw;background:#fff;border:1px solid #eef2f2;border-radius:12px;box-shadow:0 2px 8px #f5f6f8;cursor:pointer;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;overflow:hidden;text-overflow:ellipsis}.view_more{text-align:center;color:#999;margin:4vw 0}.view_more>button{background-color:transparent}.block{width:100%;height:80vh;padding:2vw}.block .block_cate{display:flex;justify-content:space-between}.block .message_mobile{overflow-y:auto;height:65vh;color:#000}.block .message_mobile>div{background-color:#fff;text-align:center;padding:3vw 0;margin:3vw 0;border-radius:4px;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}ion-modal{--height: auto}\n"]}]}],ctorParameters:()=>[{type:i1.CrossService},{type:i2.ModalController}],propDecorators:{chat:[{type:Input}],role:[{type:Input}]}});
|
|
8
|
+
import{Component,Input}from"@angular/core";import{FmodeChat}from"../../service-fmai/service-chat";import*as Parse from"parse";import{IonButton,IonLabel,IonModal,IonSegment,ModalController}from"@ionic/angular/standalone";import{CommonModule}from"@angular/common";import{NzIconModule}from"ng-zorro-antd/icon";import{FormsModule,ReactiveFormsModule}from"@angular/forms";import{CrossService}from"../../../platform/cross.service";import*as i0 from"@angular/core";import*as i1 from"../../../platform/cross.service";import*as i2 from"@ionic/angular/standalone";import*as i3 from"@angular/common";import*as i4 from"ng-zorro-antd/icon";export class CompRolePromptComponent{constructor(e,o){this.cross=e,this.modalController=o,this.role="",this.showModal=!1,this.cateIndex=0,this.company="E4KpGvTEto"}ngOnInit(){this.getChatPrompt()}applyPrompt(e){this.chat.userInput=e,this.chat.isVoiceInputMode=!1,"mobile"==this.cross?.navMenuType&&this.modalController.dismiss()}async getChatPrompt(){let e=new Parse.Query("ChatPrompt");e.notEqualTo("isDeleted",!0),e.equalTo("company",this.company),e.equalTo("role",this.role),e.include("role");let o=await e.find();this.chat.promptList=o,this.chat.promptList.forEach((e=>{let o=e.get("role").get("promptCates").filter((o=>o.name==e.get("cate")));e.img=o[0].img})),console.log(this.chat.promptList)}checkCate(e){this.cateIndex=e}static{this.ɵfac=i0.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"17.3.12",ngImport:i0,type:CompRolePromptComponent,deps:[{token:i1.CrossService},{token:i2.ModalController}],target:i0.ɵɵFactoryTarget.Component})}static{this.ɵcmp=i0.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"17.3.12",type:CompRolePromptComponent,isStandalone:!0,selector:"app-comp-role-prompt",inputs:{chat:"chat",role:"role"},providers:[ModalController],ngImport:i0,template:'<ng-container *ngIf="chat?.messageList<4 && chat?.isPromptMessageAreaShow && !chat?.userInput">\n <div class="prompt" *ngIf="cross?.navMenuType!=\'mobile\'">\n <ng-container *ngFor="let content of chat?.promptList">\n <div class="prompt_cate">\n <div class="cate_info">\n <div>\n <img [src]="content.img" alt="">\n </div>\n <div class="cate_name">\n {{content.get(\'cate\')}}\n </div>\n </div>\n <ng-container *ngFor="let message of content.get(\'messageList\')">\n <div class="message" (click)="applyPrompt(message)" nz-tooltip [nzTooltipTitle]="message"\n nzTooltipColor="#108ee9">\n {{message}}\n </div>\n </ng-container>\n </div>\n </ng-container>\n </div>\n <ng-container *ngIf="cross?.navMenuType==\'mobile\'">\n <div class="prompt_mobile">\n <ng-container *ngFor="let content of chat?.promptList">\n <div class="prompt_cate">\n <div class="cate_info">\n <div>\n <img [src]="content.img" alt="">\n </div>\n <div class="cate_name">\n {{content.get(\'cate\')}}\n </div>\n </div>\n <ng-container *ngFor="let message of content.get(\'messageList\');let idx = index">\n <div *ngIf="idx<3" class="message" (click)="applyPrompt(message)" nz-tooltip [nzTooltipTitle]="message"\n nzTooltipColor="#108ee9">\n {{message}}\n </div>\n </ng-container>\n </div>\n </ng-container>\n </div>\n <div class="view_more" *ngIf="chat?.promptList?.length">\n <button (click)="chat.isPromptModalOpen=true" expand="block">查看更多<span nz-icon nzType="right" nzTheme="outline"></span></button>\n </div>\n</ng-container>\n\n\n <ion-modal [isOpen]="chat.isPromptModalOpen" (willDismiss)="chat.isPromptModalOpen=false" [initialBreakpoint]="1" [breakpoints]="[0, 1]">\n <ng-template>\n <div class="block">\n <ion-label>话题灵感</ion-label>\n <div class="block_cate">\n \x3c!-- <ion-segment [(ngModel)]="cateIndex">\n <ng-container *ngFor="let prompt of chat?.promptList;let i = index">\n <ion-segment-button value="i">\n <ion-label>{{prompt?.get("cate")}}</ion-label>\n </ion-segment-button>\n </ng-container>\n </ion-segment> --\x3e\n <ng-container *ngFor="let prompt of chat?.promptList;let i = index">\n <ion-button [color]="i==cateIndex?\'secondary\':\'light\'" (click)="checkCate(i)">{{prompt?.get("cate")}}</ion-button>\n \x3c!-- <div [class]="i==cateIndex?\'active_cate\':\'\'" (click)="checkCate(i)">{{prompt?.get("cate")}}</div> --\x3e\n </ng-container>\n </div>\n <div class="message_mobile">\n <ng-container *ngFor="let message of chat?.promptList[cateIndex]?.get(\'messageList\')">\n <div (click)="applyPrompt(message)">{{message}}</div>\n </ng-container>\n </div>\n </div>\n </ng-template>\n </ion-modal>\n</ng-container>',styles:[":host-context(body.dark) .prompt_cate .message{background:#fff3;border:1px solid #333;box-shadow:0 2px 8px #333;color:#ffffff80}:host-context(body.dark) .cate_info{color:#fff}:host-context(body.dark) ion-modal .block h4{color:#fff!important}.prompt{color:#000;display:flex;justify-content:space-between;align-items:flex-start}.prompt .prompt_cate{flex:1;height:inherit;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex-direction:column;display:flex;justify-content:center}.prompt .prompt_cate .cate_info{font-size:1.5em;font-weight:700}.prompt .prompt_cate .cate_info div img{width:58px;height:58px}.prompt .prompt_cate .cate_info .cate_name{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.prompt .prompt_cate .message{padding:1em;margin:1em;background:#fff;border:1px solid #eef2f2;border-radius:12px;box-shadow:0 2px 8px #f5f6f8;cursor:pointer;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}@media screen and (max-width: 390.4px){.prompt .prompt_cate .message{width:100px;height:64px;padding:unset;margin:.8em;background:#fff;border:1px solid #eef2f2;border-radius:12px;box-shadow:0 2px 8px #f5f6f8;cursor:pointer;overflow:hidden;white-space:pre-wrap;text-overflow:ellipsis}}.prompt_mobile{color:#000;display:flex;justify-content:space-between;align-items:flex-start}.prompt_mobile .prompt_cate{flex:1;height:inherit}.prompt_mobile .prompt_cate .cate_info{display:flex;justify-content:center;align-items:center;font-size:1.2em}.prompt_mobile .prompt_cate .cate_info div img{width:48px;height:48px}.prompt_mobile .prompt_cate .cate_info .cate_name{display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:1;overflow:hidden;text-overflow:ellipsis;margin-top:2vw}.prompt_mobile .prompt_cate .message{min-height:48px;padding:0 2vw;margin:4vw 1vw;background:#fff;border:1px solid #eef2f2;border-radius:12px;box-shadow:0 2px 8px #f5f6f8;cursor:pointer;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;overflow:hidden;text-overflow:ellipsis}.view_more{text-align:center;color:#999;margin:4vw 0}.view_more>button{background-color:transparent}.block{width:100%;height:80vh;padding:2vw}.block .block_cate{display:flex;justify-content:space-between}.block .message_mobile{overflow-y:auto;height:65vh;color:#000}.block .message_mobile>div{background-color:#fff;text-align:center;padding:3vw 0;margin:3vw 0;border-radius:4px;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}ion-modal{--height: auto}\n"],dependencies:[{kind:"ngmodule",type:CommonModule},{kind:"directive",type:i3.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:i3.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"ngmodule",type:FormsModule},{kind:"ngmodule",type:ReactiveFormsModule},{kind:"component",type:IonModal,selector:"ion-modal"},{kind:"component",type:IonButton,selector:"ion-button",inputs:["buttonType","color","disabled","download","expand","fill","form","href","mode","rel","routerAnimation","routerDirection","shape","size","strong","target","type"]},{kind:"component",type:IonLabel,selector:"ion-label",inputs:["color","mode","position"]},{kind:"ngmodule",type:NzIconModule},{kind:"directive",type:i4.NzIconDirective,selector:"[nz-icon]",inputs:["nzSpin","nzRotate","nzType","nzTheme","nzTwotoneColor","nzIconfont"],exportAs:["nzIcon"]}]})}}i0.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"17.3.12",ngImport:i0,type:CompRolePromptComponent,decorators:[{type:Component,args:[{selector:"app-comp-role-prompt",standalone:!0,imports:[CommonModule,FormsModule,ReactiveFormsModule,IonModal,IonButton,IonSegment,IonLabel,NzIconModule],providers:[ModalController],template:'<ng-container *ngIf="chat?.messageList<4 && chat?.isPromptMessageAreaShow && !chat?.userInput">\n <div class="prompt" *ngIf="cross?.navMenuType!=\'mobile\'">\n <ng-container *ngFor="let content of chat?.promptList">\n <div class="prompt_cate">\n <div class="cate_info">\n <div>\n <img [src]="content.img" alt="">\n </div>\n <div class="cate_name">\n {{content.get(\'cate\')}}\n </div>\n </div>\n <ng-container *ngFor="let message of content.get(\'messageList\')">\n <div class="message" (click)="applyPrompt(message)" nz-tooltip [nzTooltipTitle]="message"\n nzTooltipColor="#108ee9">\n {{message}}\n </div>\n </ng-container>\n </div>\n </ng-container>\n </div>\n <ng-container *ngIf="cross?.navMenuType==\'mobile\'">\n <div class="prompt_mobile">\n <ng-container *ngFor="let content of chat?.promptList">\n <div class="prompt_cate">\n <div class="cate_info">\n <div>\n <img [src]="content.img" alt="">\n </div>\n <div class="cate_name">\n {{content.get(\'cate\')}}\n </div>\n </div>\n <ng-container *ngFor="let message of content.get(\'messageList\');let idx = index">\n <div *ngIf="idx<3" class="message" (click)="applyPrompt(message)" nz-tooltip [nzTooltipTitle]="message"\n nzTooltipColor="#108ee9">\n {{message}}\n </div>\n </ng-container>\n </div>\n </ng-container>\n </div>\n <div class="view_more" *ngIf="chat?.promptList?.length">\n <button (click)="chat.isPromptModalOpen=true" expand="block">查看更多<span nz-icon nzType="right" nzTheme="outline"></span></button>\n </div>\n</ng-container>\n\n\n <ion-modal [isOpen]="chat.isPromptModalOpen" (willDismiss)="chat.isPromptModalOpen=false" [initialBreakpoint]="1" [breakpoints]="[0, 1]">\n <ng-template>\n <div class="block">\n <ion-label>话题灵感</ion-label>\n <div class="block_cate">\n \x3c!-- <ion-segment [(ngModel)]="cateIndex">\n <ng-container *ngFor="let prompt of chat?.promptList;let i = index">\n <ion-segment-button value="i">\n <ion-label>{{prompt?.get("cate")}}</ion-label>\n </ion-segment-button>\n </ng-container>\n </ion-segment> --\x3e\n <ng-container *ngFor="let prompt of chat?.promptList;let i = index">\n <ion-button [color]="i==cateIndex?\'secondary\':\'light\'" (click)="checkCate(i)">{{prompt?.get("cate")}}</ion-button>\n \x3c!-- <div [class]="i==cateIndex?\'active_cate\':\'\'" (click)="checkCate(i)">{{prompt?.get("cate")}}</div> --\x3e\n </ng-container>\n </div>\n <div class="message_mobile">\n <ng-container *ngFor="let message of chat?.promptList[cateIndex]?.get(\'messageList\')">\n <div (click)="applyPrompt(message)">{{message}}</div>\n </ng-container>\n </div>\n </div>\n </ng-template>\n </ion-modal>\n</ng-container>',styles:[":host-context(body.dark) .prompt_cate .message{background:#fff3;border:1px solid #333;box-shadow:0 2px 8px #333;color:#ffffff80}:host-context(body.dark) .cate_info{color:#fff}:host-context(body.dark) ion-modal .block h4{color:#fff!important}.prompt{color:#000;display:flex;justify-content:space-between;align-items:flex-start}.prompt .prompt_cate{flex:1;height:inherit;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex-direction:column;display:flex;justify-content:center}.prompt .prompt_cate .cate_info{font-size:1.5em;font-weight:700}.prompt .prompt_cate .cate_info div img{width:58px;height:58px}.prompt .prompt_cate .cate_info .cate_name{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.prompt .prompt_cate .message{padding:1em;margin:1em;background:#fff;border:1px solid #eef2f2;border-radius:12px;box-shadow:0 2px 8px #f5f6f8;cursor:pointer;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}@media screen and (max-width: 390.4px){.prompt .prompt_cate .message{width:100px;height:64px;padding:unset;margin:.8em;background:#fff;border:1px solid #eef2f2;border-radius:12px;box-shadow:0 2px 8px #f5f6f8;cursor:pointer;overflow:hidden;white-space:pre-wrap;text-overflow:ellipsis}}.prompt_mobile{color:#000;display:flex;justify-content:space-between;align-items:flex-start}.prompt_mobile .prompt_cate{flex:1;height:inherit}.prompt_mobile .prompt_cate .cate_info{display:flex;justify-content:center;align-items:center;font-size:1.2em}.prompt_mobile .prompt_cate .cate_info div img{width:48px;height:48px}.prompt_mobile .prompt_cate .cate_info .cate_name{display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:1;overflow:hidden;text-overflow:ellipsis;margin-top:2vw}.prompt_mobile .prompt_cate .message{min-height:48px;padding:0 2vw;margin:4vw 1vw;background:#fff;border:1px solid #eef2f2;border-radius:12px;box-shadow:0 2px 8px #f5f6f8;cursor:pointer;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;overflow:hidden;text-overflow:ellipsis}.view_more{text-align:center;color:#999;margin:4vw 0}.view_more>button{background-color:transparent}.block{width:100%;height:80vh;padding:2vw}.block .block_cate{display:flex;justify-content:space-between}.block .message_mobile{overflow-y:auto;height:65vh;color:#000}.block .message_mobile>div{background-color:#fff;text-align:center;padding:3vw 0;margin:3vw 0;border-radius:4px;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}ion-modal{--height: auto}\n"]}]}],ctorParameters:()=>[{type:i1.CrossService},{type:i2.ModalController}],propDecorators:{chat:[{type:Input}],role:[{type:Input}]}});
|
|
9
9
|
var MODULE_PATH_NEED = `6K+l5paH5Lu25piv5pys6aG555uu55qE5LiA6YOo5YiGIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBDb21wb25lbnRzIGluIEZtb2RlIEluYy4KICAgIOeJiOadg+aJgOaciSDCqSDmnKrmnaXpo57pqawgwqkg5rGf6KW/6ISR5o6n56eR5oqA5pyJ6ZmQ5YWs5Y+4IENvcHlyaWdodCDCqSBGbW9kZSBUZWNobm9sb2d5IENvLiwgTHRkLgogICAg5L+d55WZ5omA5pyJ5p2D5YipIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAgICDkuKXnpoHlnKjmnKrnu4/mjojmnYPnmoTmg4XlhrXkuIvvvIzpgJrov4fku7vkvZXlqpLku4vlpI3liLbmraTmlofku7YgVW5hdXRob3JpemVkIGNvcHlpbmcgb2YgdGhpcyBmaWxlLCB2aWEgYW55IG1lZGl1bSBpcyBzdHJpY3RseSBwcm9oaWJpdGVkCiAgICDor6Xmlofku7bmmK/kuJPmnInnmoTmnLrlr4bmlofku7YgUHJvcHJpZXRhcnkgYW5kIGNvbmZpZGVudGlhbAogICAKICAgIENvcHlyaWdodCAyMDIxLW5vdyBGbW9kZSBJbmMuIHN1cHBvcnRAZm1vZGUuY24uIDE4NjA3MDA3MDczLgogICAg5L+d55WZ5omA5pyJ5p2D5YipIEFsbCByaWdodHMgcmVzZXJ2ZWQuCgogICAgUEFUSDovaG9tZS9yeWFuL3dvcmtzcGFjZS9ub3ZhL25vdmEtYWRtaW4vZGlzdC9mbW9kZS1uZy9lc20yMDIyL2xpYi9haWdjL2NoYXQvY29tcC1yb2xlLXByb21wdC9jb21wLXJvbGUtcHJvbXB0LmNvbXBvbmVudC5tanM=`
|
|
10
10
|
|
|
@@ -5,6 +5,6 @@
|
|
|
5
5
|
* 保留所有权利 All Rights Reserved.
|
|
6
6
|
* /home/ryan/workspace/nova/nova-admin/dist/fmode-ng/esm2022/lib/aigc/service-fmai/service-chat/chat-class.mjs
|
|
7
7
|
*/
|
|
8
|
-
import{bufferTime,concatMap,Observable,delay,finalize}from"rxjs";import Parse from"parse";import{AgentPrompt}from"../../agent";import{FmodeTTS}from"../../voice/tts";const API_BASE="https://server.fmode.cn/api/apig/aigc/gpt",agentPrompt=new AgentPrompt,PromptTplTalkSSMLOutputCode="talk-ssml-output-tpl",PromptTplTalkTextSSMLCode="talk-text-ssml-tpl";export function getMessageContentText(t){let e="";return"string"==typeof t&&(e=t),"object"==typeof t&&(e=t?.find((t=>t?.text))?.text||""),e}export function getMessageImageUrl(t){return"object"==typeof t?t?.find((t=>t?.image_url))?.image_url?.url||"":null}export class FmodeChat{showAvatar(){this.avatarConfig=this.role?.get("avatarConfig"),this.avatarConfig&&(this.isAvatarShow=!0,this.avatarConfig?.image&&(this.avatarConfig.image.waiting=this.avatarConfig.image.waiting||this.role?.get("thumb")||this.role?.get("avatar"),this.avatarMode="image"),this.avatarConfig?.video&&(this.avatarConfig.video.waiting=this.avatarConfig.video.waiting,this.avatarMode="video"))}constructor(t,e,s,i,o,n,a){this.ChatSession=Parse.Object.extend("ChatSession"),this.messageList=[{role:"system",content:"系统提示:AI仅供参考"}],this.latestAIResponse="",this.userInput="",this.userImage="",this.isDirect=!1,this.isAvatarShow=!1,this.avatarMode="",this.isPromptModalOpen=!1,this.isPromptMessageAreaShow=!0,this.promptList=[],this.leftButtons=[{title:"灵感",icon:"color-wand-outline",onClick:()=>{this.isPromptModalOpen=!0},show:()=>this?.promptList?.length},{title:"角色",icon:"people-outline",onClick:()=>{this.navCtrl?.navigateRoot("/chat/pro/mask")},show:()=>!0},{title:"呼叫",icon:"call-outline",onClick:()=>{this.chatServ?.callRole(this.role)},show:()=>this?.role?.get("voiceConfig")}],this.isVoiceInputMode=!1,this.isTexting=!1,this.isTalkMode=!1,this.SSMLRoleVoice="zh-CN-XiaoxiaoNeural",this.playAnimation=t=>{console.log(t)},this.welcome=async()=>{let t=this.messageList?.filter((t=>"assistant"==t?.role));if(t?.length)return;let e=Parse.User.current(),s=await this.loadSelf("Person","userVerify"),i=await this.loadSelf("Profile","user"),o=e?.get("realname")||i?.get("name")||s?.get("name")||e?.get("nickname")||e?.get("name"),n=`${o?`${o},`:""}${`${this.getTimeOfDay()}好`},期待聆听您的人生故事,想和我聊些什么呢?`,a=await this.getVoiceByContentText(n),r={role:"assistant",voice:a,content:n,complete:!0};this.voiceMap[a?.id],this.playChatVoice(this.voiceMap[a?.id]),this.messageList.push(r)},this.self={},this.voiceMap={},this.chatServ=i,this.role=e,this.sessionId=t,this.navCtrl=o,this.ncloud=n,this.uploadServ=a,s?.id&&(this.chatSession=s,this.messageList=this.chatSession.get("messageList"),this.sessionId=s?.id),this.role?.id&&(this.voiceConfig=this.role?.get("voiceConfig"),this.voiceConfig?.autoTalk&&(this.isTalkMode=!0,this.isDirect=!0))}getTimeOfDay(){const t=(new Date).getHours();return t>=5&&t<12?"早上":t>=12&&t<14?"中午":t>=14&&t<18?"下午":"晚上"}async loadSelf(t,e){if(this.self[t])return this.self[t];let s=Parse.User.current(),i=new Parse.Query(t);i.equalTo(e,s?.id),this.self[t]=await i.first()}async loadTalkSystemPrompt(t){if(!this.isTalkMode)return;if(!t)return;"男"==t?.get("gender")?this.SSMLRoleVoice="zh-CN-YunyeNeural":this.SSMLRoleVoice="zh-CN-XiaoxiaoNeural",this.SSMLRoleVoice=t?.get("voiceConfig")?.voice||this.SSMLRoleVoice;let e=await agentPrompt.getFormatTpl("talk-ssml-output-tpl",{SSMLRoleVoice:this.SSMLRoleVoice}),s=t.get("prompt")||"请你扮演飞码AI的人工智能专家。";s+=e;let i={role:"user",content:s,hidden:!0},o=this.messageList?.map((t=>t?.content)).join();if(o.indexOf(s)>-1)return;let n=this.messageList?.findIndex((t=>"system"==t?.role)),a=n+1;this.messageList.splice(a,0,i)}loadRolePrompt(){let t=this.role?.get("prompt"),e={role:"user",content:t,hidden:!0};if(!t)return;let s=this.messageList?.map((t=>t?.content)).join();if(s.indexOf(t)>-1)return;let i=this.messageList?.findIndex((t=>"system"==t?.role)),o=i+1;this.messageList.splice(o,0,e)}async sendMessage(t="FmodeAiTest测试问题",e,s,i,o){if(this.isPromptMessageAreaShow=!1,this.loadRolePrompt(),e){let s={role:"user",content:[{type:"image_url",image_url:{url:e}},{type:"text",text:t}],complete:!0,createdAt:new Date};o&&(s.voice={id:o?.id}),this.messageList.push({role:"user",content:[{type:"image_url",image_url:{url:e}},{type:"text",text:t}],complete:!0,createdAt:new Date})}else{let e={role:"user",content:t,complete:!0,createdAt:new Date};o&&(e.voice={id:o?.id,duration:o?.duration}),this.messageList.push(e)}let n=new FmodeChatCompletion(this.fixMessageList(this.messageList),{model:this.chatServ?.currentModel?.get("code")||"fmode-4.5-128k"});this.userInput="",this.userImage="";let a=this.isDirect||!1;this.isTalkMode&&(a=!0);let r=n.sendCompletion({isDirect:a,onComplete:s||null}).pipe(finalize((async()=>{if(this.isTalkMode){let t=this.messageList[n.indexOfList]?.content,e=await this.getVoiceByContentText(t,i);i?.onSSMLComplete&&i?.onSSMLComplete(e),this.messageList[n.indexOfList].voice=e,this.playChatVoice(this.voiceMap[e?.id])}this.messageList[n.indexOfList].complete=!0}))).subscribe((t=>{this.messageList[n.indexOfList]=t,this.latestAIResponse=this.getContentText(t?.content);let e=this.chatSession?.get("messageList")?.length;this.messageList?.length>e&&this.saveChatSession(),t?.complete&&(this.saveChatSession(),r.unsubscribe())}))}getVoiceByContentText(t,e,s=!1){let i=this.getContentText(t),o=new(Parse.Object.extend("ChatVoice")),n="";return this.SSMLRoleVoice=this.role?.get("voiceConfig")?.voice||this.SSMLRoleVoice,new Promise((async(t,e)=>{let resolveChatVoice=async()=>{o.set("content",i),o.set("ssml",n),o.set("role","assistant");let e=localStorage.getItem("company");e&&o.set("company",{__type:"Pointer",className:"Company",objectId:e}),Parse.User.current()?.id&&o.set("user",Parse.User.current().toPointer()),this.chatSession?.id&&o.set("session",this.chatSession?.toPointer()),o=await o.save(),this.voiceMap[o?.id]=o,t({id:o?.id})};if(0==s&&(n=`<speak xmlns="http://www.w3.org/2001/10/synthesis" xmlns:mstts="http://www.w3.org/2001/mstts" xmlns:emo="http://www.w3.org/2009/10/emotionml" version="1.0" xml:lang="zh-CN"><voice name="${this.SSMLRoleVoice}">${i}</voice></speak>`,resolveChatVoice()),1==s){let t=await agentPrompt.getFormatTpl("talk-text-ssml-tpl",{content:i,SSMLRoleVoice:this.SSMLRoleVoice});new FmodeChatCompletion(this.fixMessageList([{role:"user",content:t}]),{model:this.chatServ?.currentModel?.get("code")||"fmode-4.5-128k"}).sendCompletion({isDirect:!0}).subscribe((async t=>{t?.complete&&(n=this.getContentText(t?.content),resolveChatVoice())}))}}))}getContentText(t){return"string"==typeof t?t:t?.[0]?.text||""}async initTTS(){let t=await this.ncloud.apig("voice/tts/token",{company:localStorage.getItem("company")});if(console.log(t),t?.token){let e=new FmodeTTS(t,this.uploadServ);this.tts=e}}async playChatVoice(t,e){if(await this.initTTS(),this.tts)try{this.playAnimation("talking"),await this.tts.speakAsync(t?.get("ssml"),t,{onLoaded:t=>{e?.onLoaded&&e?.onLoaded(t)},onStop:()=>{e?.onStop&&e?.onStop(),this.playAnimation("waiting")}})}catch(t){console.error(t)}}async saveChatSession(){if("new"==this.sessionId&&(this.chatSession=new this.ChatSession),this.chatSession.set("title",this.genTitle()),this.chatSession.set("role",this.role?.toPointer()),this.chatSession.set("messageList",this.messageList),this.chatSession.set("user",Parse.User.current()?.toPointer()),this.chatSession=await this.chatSession.save(),this.sessionId=this.chatSession?.id,this.sessionId){let t=`${window.location.origin}/chat/pro/chat/${this.sessionId}`;window.location?.pathname?.indexOf("chat/session")>-1&&(t=`${window.location.origin}/chat/session/chat/${this.sessionId}`),t=this.getInviteUrl(t),window.history.replaceState(null,null,t+window.location.search);let e={sid:this.chatSession?.id,rid:this.role?.id,name:this.role?.get("name"),message:this.chatSession?.get("messageList")?.[this.chatSession?.get("messageList")?.length-1]?.content?.slice(0,20),latest:this.chatSession?.createdAt};this.chatServ?.chatList?.length||(this.chatServ.chatList=[]);let s=this.chatServ?.chatList?.find((t=>t?.sid==e?.sid));s>-1?this.chatServ.chatList[s]=e:this.chatServ?.chatList.unshift(e)}}getInviteUrl(t){let e="?";e=t?.indexOf("?")>-1?"&":"?";let s=Parse.User?.current()?.id;if(-1==t?.indexOf("invite="+s)){if(!s)return t;t+=e+"invite="+s}return t}genTitle(){if(this.title)return this.title;let t=this.messageList.find((t=>"user"==t.role))?.content;return"string"==typeof t&&(this.title=t?.slice(0,15)||""),"object"==typeof t&&(this.title=t?.find((t=>t?.text))?.text||""),this.title}fixMessageList(t){return t.map((t=>({role:t.role,content:t.content})))}nowStr(){let t=new Date;return`${t.getFullYear()}/${t.getMonth()+1}/${t.getDate()} ${t.getHours()}:${t.getMinutes()}:${t.getSeconds()}`}}export class FmodeChatCompletion{constructor(t,e){this.content="",this.contentBuffer=[],this.isCompleted=!1,this.indexOfList=Number(t.length),this.messages=t,this.model=e?.model||"fmode-4.5-128k"}sendCompletion(t={}){t.intTime=t?.intTime||50,t.isDirect=t?.isDirect||!1,t?.isDirect&&(t.intTime=1);let e={messages:this.messages,stream:!0,model:this.model,temperature:.5,presence_penalty:0,frequency_penalty:0};return new Observable((s=>{let i=RequestFmodeChatApi("/v1/chat/completions",e).subscribe((e=>{let o=String(e);if("data: [DONE]"==o&&(this.isCompleted=!0,t?.isDirect&&this.isCompleted&&(s.next({role:"assistant",content:this.content,complete:!0,createdAt:new Date}),i.unsubscribe(),t?.onComplete&&t.onComplete({role:"assistant",content:this.content,complete:!0,createdAt:new Date}),s.complete())),o.indexOf("data: {")>-1){let e=chunkToJson(o),n=e?.choices?.[0]?.delta?.content||"";this.contentBuffer.push(n),t?.isDirect&&(this.content+=n||"",this.isCompleted||s.next({role:"assistant",cid:e?.id,content:this.content,createdAt:new Date})),t?.isDirect||this.contentPusher||(this.contentPusher=setInterval((()=>{this.isCompleted&&0==this.contentBuffer?.length&&(s.next({role:"assistant",cid:e?.id,content:this.content,complete:!0,createdAt:new Date}),i.unsubscribe(),clearInterval(this.contentPusher),s.complete()),this.contentBuffer?.length>=0&&(this.contentBuffer?.length>0&&(this.content+=this.contentBuffer.shift()),s.next({role:"assistant",cid:e?.id,content:this.content,createdAt:new Date}))}),t?.intTime))}}))})).pipe(bufferTime(100),concatMap((t=>t)),delay(200))}}function chunkToJson(t){let e;try{e=JSON.parse(t.replaceAll("data: ",""))}catch(t){console.error(t)}return e||{}}function RequestFmodeChatApi(t,e,s="POST"){return new Observable((i=>{let o=API_BASE+t,n=`Bearer ${Parse.User.current()?.getSessionToken()||localStorage.getItem("FMODE_AI_TOKEN")}`;return e.token=n,e&&(e=JSON.stringify(e)),fetch(o,{headers:{"Content-Type":"text/plain","Cache-Control":"no-cache"},body:e||null,method:s,credentials:"omit",mode:"cors"}).then((t=>{let e="";{let s=t.body?.getReader();const o=new TextDecoder;let n=new ReadableStream({start(t){!function read(){s.read().then((({done:e,value:s})=>{if(e)return t.close(),void i.complete();t.enqueue(s),read()}))}()}}).getReader();n.read().then((function processStream({done:t,value:s}){if(t)return;!function processData(t){let s=(e+t).split("\n");if(s?.length>1){for(let t=0;t<s.length-1;t++){let e=s[t];i.next(e)}e=s[s.length-1]}}(o.decode(s)),n.read().then(processStream)}))}})).catch((t=>i.error(t))),()=>{}}))}function JsonToFormData(t){const e=new FormData;return function appendFormData(t,s=""){Array.isArray(t)?t.forEach(((t,e)=>{appendFormData(t,`${s}[${e}]`)})):"object"==typeof t&&null!==t?Object.keys(t).forEach((e=>{const i=s?`${s}.${e}`:e;appendFormData(t[e],i)})):e.append(s,t)}(t),e}
|
|
8
|
+
import{bufferTime,concatMap,Observable,delay,finalize}from"rxjs";import Parse from"parse";import{AgentPrompt}from"../../agent";import{FmodeTTS}from"../../voice/tts";import{PromptTemplate}from"@langchain/core/prompts";const API_BASE="https://server.fmode.cn/api/apig/aigc/gpt",agentPrompt=new AgentPrompt,PromptTplTalkSSMLOutputCode="talk-ssml-output-tpl",PromptTplTalkTextSSMLCode="talk-text-ssml-tpl";export function getMessageContentText(t){let e="";return"string"==typeof t&&(e=t),"object"==typeof t&&(e=t?.find((t=>t?.text))?.text||""),e}export function getMessageImageUrl(t){return"object"==typeof t?t?.find((t=>t?.image_url))?.image_url?.url||"":null}export class FmodeChat{showAvatar(){this.avatarConfig=this.role?.get("avatarConfig"),this.avatarConfig&&(this.isAvatarShow=!0,this.avatarConfig?.image&&(this.avatarConfig.image.waiting=this.avatarConfig.image.waiting||this.role?.get("thumb")||this.role?.get("avatar"),this.avatarMode="image"),this.avatarConfig?.video&&(this.avatarConfig.video.waiting=this.avatarConfig.video.waiting,this.avatarMode="video"))}constructor(t,e,s,i,o,n,a){this.ChatSession=Parse.Object.extend("ChatSession"),this.messageList=[{role:"system",content:"系统提示:AI仅供参考"}],this.latestAIResponse="",this.userInput="",this.userImage="",this.isDirect=!1,this.isAvatarShow=!1,this.avatarMode="",this.isPromptModalOpen=!1,this.isPromptMessageAreaShow=!0,this.promptList=[],this.leftButtons=[{title:"灵感",icon:"color-wand-outline",onClick:()=>{this.isPromptModalOpen=!0},show:()=>this?.promptList?.length},{title:"角色",icon:"people-outline",onClick:()=>{this.navCtrl?.navigateRoot("/chat/pro/mask")},show:()=>!0},{title:"呼叫",icon:"call-outline",onClick:()=>{this.chatServ?.callRole(this.role)},show:()=>this?.role?.get("voiceConfig")}],this.isVoiceInputMode=!1,this.isTexting=!1,this.isTalkMode=!1,this.SSMLRoleVoice="zh-CN-XiaoxiaoNeural",this.playAnimation=t=>{console.log(t)},this.welcome=async()=>{let t=this.messageList?.filter((t=>"assistant"==t?.role));if(t?.length)return;let e=Parse.User.current(),s=await this.loadSelf("Person","userVerify"),i=await this.loadSelf("Profile","user"),o=e?.get("realname")||i?.get("name")||s?.get("name")||e?.get("nickname")||e?.get("name"),n=this.role.get("voiceConfig")?.welcome?.prompt;if(!n)return;let a=await PromptTemplate.fromTemplate(n,{templateFormat:"mustache"}).format({name:o,timeOfDay:this.getTimeOfDay()}),r=await this.getVoiceByContentText(a),l={role:"assistant",voice:r,content:a,complete:!0};this.voiceMap[r?.id],this.playChatVoice(this.voiceMap[r?.id]),this.messageList.push(l)},this.self={},this.voiceMap={},this.chatServ=i,this.role=e,this.sessionId=t,this.navCtrl=o,this.ncloud=n,this.uploadServ=a,s?.id&&(this.chatSession=s,this.messageList=this.chatSession.get("messageList"),this.sessionId=s?.id),this.role?.id&&(this.voiceConfig=this.role?.get("voiceConfig"),this.voiceConfig?.autoTalk&&(this.isTalkMode=!0,this.isDirect=!0))}getTimeOfDay(){const t=(new Date).getHours();return t>=5&&t<12?"早上":t>=12&&t<14?"中午":t>=14&&t<18?"下午":"晚上"}async loadSelf(t,e){if(this.self[t])return this.self[t];let s=Parse.User.current(),i=new Parse.Query(t);i.equalTo(e,s?.id),this.self[t]=await i.first()}async loadTalkSystemPrompt(t){if(!this.isTalkMode)return;if(!t)return;"男"==t?.get("gender")?this.SSMLRoleVoice="zh-CN-YunyeNeural":this.SSMLRoleVoice="zh-CN-XiaoxiaoNeural",this.SSMLRoleVoice=t?.get("voiceConfig")?.voice||this.SSMLRoleVoice;let e=await agentPrompt.getFormatTpl("talk-ssml-output-tpl",{SSMLRoleVoice:this.SSMLRoleVoice}),s=t.get("prompt")||"请你扮演飞码AI的人工智能专家。";s+=e;let i={role:"user",content:s,hidden:!0},o=this.messageList?.map((t=>t?.content)).join();if(o.indexOf(s)>-1)return;let n=this.messageList?.findIndex((t=>"system"==t?.role)),a=n+1;this.messageList.splice(a,0,i)}loadRolePrompt(){let t=this.role?.get("prompt"),e={role:"user",content:t,hidden:!0};if(!t)return;let s=this.messageList?.map((t=>t?.content)).join();if(s.indexOf(t)>-1)return;let i=this.messageList?.findIndex((t=>"system"==t?.role)),o=i+1;this.messageList.splice(o,0,e)}async sendMessage(t="FmodeAiTest测试问题",e,s,i,o){if(this.isPromptMessageAreaShow=!1,this.loadRolePrompt(),e){let s={role:"user",content:[{type:"image_url",image_url:{url:e}},{type:"text",text:t}],complete:!0,createdAt:new Date};o&&(s.voice={id:o?.id}),this.messageList.push({role:"user",content:[{type:"image_url",image_url:{url:e}},{type:"text",text:t}],complete:!0,createdAt:new Date})}else{let e={role:"user",content:t,complete:!0,createdAt:new Date};o&&(e.voice={id:o?.id,duration:o?.duration}),this.messageList.push(e)}let n=new FmodeChatCompletion(this.fixMessageList(this.messageList),{model:this.chatServ?.currentModel?.get("code")||"fmode-4.5-128k"});this.userInput="",this.userImage="";let a=this.isDirect||!1;this.isTalkMode&&(a=!0);let r=n.sendCompletion({isDirect:a,onComplete:s||null}).pipe(finalize((async()=>{if(this.isTalkMode){let t=this.messageList[n.indexOfList]?.content,e=await this.getVoiceByContentText(t,i);i?.onSSMLComplete&&i?.onSSMLComplete(e),this.messageList[n.indexOfList].voice=e,this.playChatVoice(this.voiceMap[e?.id])}this.messageList[n.indexOfList].complete=!0}))).subscribe((t=>{this.messageList[n.indexOfList]=t,this.latestAIResponse=this.getContentText(t?.content);let e=this.chatSession?.get("messageList")?.length;this.messageList?.length>e&&this.saveChatSession(),t?.complete&&(this.saveChatSession(),r.unsubscribe())}))}getVoiceByContentText(t,e,s=!1){let i=this.getContentText(t),o=new(Parse.Object.extend("ChatVoice")),n="";return this.SSMLRoleVoice=this.role?.get("voiceConfig")?.voice||this.SSMLRoleVoice,new Promise((async(t,e)=>{let resolveChatVoice=async()=>{o.set("content",i),o.set("ssml",n),o.set("role","assistant");let e=localStorage.getItem("company");e&&o.set("company",{__type:"Pointer",className:"Company",objectId:e}),Parse.User.current()?.id&&o.set("user",Parse.User.current().toPointer()),this.chatSession?.id&&o.set("session",this.chatSession?.toPointer()),o=await o.save(),this.voiceMap[o?.id]=o,t({id:o?.id})};if(0==s&&(n=`<speak xmlns="http://www.w3.org/2001/10/synthesis" xmlns:mstts="http://www.w3.org/2001/mstts" xmlns:emo="http://www.w3.org/2009/10/emotionml" version="1.0" xml:lang="zh-CN"><voice name="${this.SSMLRoleVoice}">${i}</voice></speak>`,resolveChatVoice()),1==s){let t=await agentPrompt.getFormatTpl("talk-text-ssml-tpl",{content:i,SSMLRoleVoice:this.SSMLRoleVoice});new FmodeChatCompletion(this.fixMessageList([{role:"user",content:t}]),{model:this.chatServ?.currentModel?.get("code")||"fmode-4.5-128k"}).sendCompletion({isDirect:!0}).subscribe((async t=>{t?.complete&&(n=this.getContentText(t?.content),resolveChatVoice())}))}}))}getContentText(t){return"string"==typeof t?t:t?.[0]?.text||""}async initTTS(){let t=await this.ncloud.apig("voice/tts/token",{company:localStorage.getItem("company")});if(console.log(t),t?.token){let e=new FmodeTTS(t,this.uploadServ);this.tts=e}}async playChatVoice(t,e){if(await this.initTTS(),this.tts)try{this.playAnimation("talking"),await this.tts.speakAsync(t?.get("ssml"),t,{onLoaded:t=>{e?.onLoaded&&e?.onLoaded(t)},onStop:()=>{e?.onStop&&e?.onStop(),this.playAnimation("waiting")}})}catch(t){console.error(t)}}async saveChatSession(){if("new"==this.sessionId&&(this.chatSession=new this.ChatSession),this.chatSession.set("title",this.genTitle()),this.chatSession.set("role",this.role?.toPointer()),this.chatSession.set("messageList",this.messageList),this.chatSession.set("user",Parse.User.current()?.toPointer()),this.chatSession=await this.chatSession.save(),this.sessionId=this.chatSession?.id,this.sessionId){let t=`${window.location.origin}/chat/pro/chat/${this.sessionId}`;window.location?.pathname?.indexOf("chat/session")>-1&&(t=`${window.location.origin}/chat/session/chat/${this.sessionId}`),t=this.getInviteUrl(t),window.history.replaceState(null,null,t+window.location.search);let e={sid:this.chatSession?.id,rid:this.role?.id,name:this.role?.get("name"),message:this.chatSession?.get("messageList")?.[this.chatSession?.get("messageList")?.length-1]?.content?.slice(0,20),latest:this.chatSession?.createdAt};this.chatServ?.chatList?.length||(this.chatServ.chatList=[]);let s=this.chatServ?.chatList?.find((t=>t?.sid==e?.sid));s>-1?this.chatServ.chatList[s]=e:this.chatServ?.chatList.unshift(e)}}getInviteUrl(t){let e="?";e=t?.indexOf("?")>-1?"&":"?";let s=Parse.User?.current()?.id;if(-1==t?.indexOf("invite="+s)){if(!s)return t;t+=e+"invite="+s}return t}genTitle(){if(this.title)return this.title;let t=this.messageList.find((t=>"user"==t.role))?.content;return"string"==typeof t&&(this.title=t?.slice(0,15)||""),"object"==typeof t&&(this.title=t?.find((t=>t?.text))?.text||""),this.title}fixMessageList(t){return t.map((t=>({role:t.role,content:t.content})))}nowStr(){let t=new Date;return`${t.getFullYear()}/${t.getMonth()+1}/${t.getDate()} ${t.getHours()}:${t.getMinutes()}:${t.getSeconds()}`}}export class FmodeChatCompletion{constructor(t,e){this.content="",this.contentBuffer=[],this.isCompleted=!1,this.indexOfList=Number(t.length),this.messages=t,this.model=e?.model||"fmode-4.5-128k"}sendCompletion(t={}){t.intTime=t?.intTime||50,t.isDirect=t?.isDirect||!1,t?.isDirect&&(t.intTime=1);let e={messages:this.messages,stream:!0,model:this.model,temperature:.5,presence_penalty:0,frequency_penalty:0};return new Observable((s=>{let i=RequestFmodeChatApi("/v1/chat/completions",e).subscribe((e=>{let o=String(e);if("data: [DONE]"==o&&(this.isCompleted=!0,t?.isDirect&&this.isCompleted&&(s.next({role:"assistant",content:this.content,complete:!0,createdAt:new Date}),i.unsubscribe(),t?.onComplete&&t.onComplete({role:"assistant",content:this.content,complete:!0,createdAt:new Date}),s.complete())),o.indexOf("data: {")>-1){let e=chunkToJson(o),n=e?.choices?.[0]?.delta?.content||"";this.contentBuffer.push(n),t?.isDirect&&(this.content+=n||"",this.isCompleted||s.next({role:"assistant",cid:e?.id,content:this.content,createdAt:new Date})),t?.isDirect||this.contentPusher||(this.contentPusher=setInterval((()=>{this.isCompleted&&0==this.contentBuffer?.length&&(s.next({role:"assistant",cid:e?.id,content:this.content,complete:!0,createdAt:new Date}),i.unsubscribe(),clearInterval(this.contentPusher),s.complete()),this.contentBuffer?.length>=0&&(this.contentBuffer?.length>0&&(this.content+=this.contentBuffer.shift()),s.next({role:"assistant",cid:e?.id,content:this.content,createdAt:new Date}))}),t?.intTime))}}))})).pipe(bufferTime(100),concatMap((t=>t)),delay(200))}}function chunkToJson(t){let e;try{e=JSON.parse(t.replaceAll("data: ",""))}catch(t){console.error(t)}return e||{}}function RequestFmodeChatApi(t,e,s="POST"){return new Observable((i=>{let o=API_BASE+t,n=`Bearer ${Parse.User.current()?.getSessionToken()||localStorage.getItem("FMODE_AI_TOKEN")}`;return e.token=n,e&&(e=JSON.stringify(e)),fetch(o,{headers:{"Content-Type":"text/plain","Cache-Control":"no-cache"},body:e||null,method:s,credentials:"omit",mode:"cors"}).then((t=>{let e="";{let s=t.body?.getReader();const o=new TextDecoder;let n=new ReadableStream({start(t){!function read(){s.read().then((({done:e,value:s})=>{if(e)return t.close(),void i.complete();t.enqueue(s),read()}))}()}}).getReader();n.read().then((function processStream({done:t,value:s}){if(t)return;!function processData(t){let s=(e+t).split("\n");if(s?.length>1){for(let t=0;t<s.length-1;t++){let e=s[t];i.next(e)}e=s[s.length-1]}}(o.decode(s)),n.read().then(processStream)}))}})).catch((t=>i.error(t))),()=>{}}))}function JsonToFormData(t){const e=new FormData;return function appendFormData(t,s=""){Array.isArray(t)?t.forEach(((t,e)=>{appendFormData(t,`${s}[${e}]`)})):"object"==typeof t&&null!==t?Object.keys(t).forEach((e=>{const i=s?`${s}.${e}`:e;appendFormData(t[e],i)})):e.append(s,t)}(t),e}
|
|
9
9
|
var MODULE_PATH_NEED = `6K+l5paH5Lu25piv5pys6aG555uu55qE5LiA6YOo5YiGIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBDb21wb25lbnRzIGluIEZtb2RlIEluYy4KICAgIOeJiOadg+aJgOaciSDCqSDmnKrmnaXpo57pqawgwqkg5rGf6KW/6ISR5o6n56eR5oqA5pyJ6ZmQ5YWs5Y+4IENvcHlyaWdodCDCqSBGbW9kZSBUZWNobm9sb2d5IENvLiwgTHRkLgogICAg5L+d55WZ5omA5pyJ5p2D5YipIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAgICDkuKXnpoHlnKjmnKrnu4/mjojmnYPnmoTmg4XlhrXkuIvvvIzpgJrov4fku7vkvZXlqpLku4vlpI3liLbmraTmlofku7YgVW5hdXRob3JpemVkIGNvcHlpbmcgb2YgdGhpcyBmaWxlLCB2aWEgYW55IG1lZGl1bSBpcyBzdHJpY3RseSBwcm9oaWJpdGVkCiAgICDor6Xmlofku7bmmK/kuJPmnInnmoTmnLrlr4bmlofku7YgUHJvcHJpZXRhcnkgYW5kIGNvbmZpZGVudGlhbAogICAKICAgIENvcHlyaWdodCAyMDIxLW5vdyBGbW9kZSBJbmMuIHN1cHBvcnRAZm1vZGUuY24uIDE4NjA3MDA3MDczLgogICAg5L+d55WZ5omA5pyJ5p2D5YipIEFsbCByaWdodHMgcmVzZXJ2ZWQuCgogICAgUEFUSDovaG9tZS9yeWFuL3dvcmtzcGFjZS9ub3ZhL25vdmEtYWRtaW4vZGlzdC9mbW9kZS1uZy9lc20yMDIyL2xpYi9haWdjL3NlcnZpY2UtZm1haS9zZXJ2aWNlLWNoYXQvY2hhdC1jbGFzcy5tanM=`
|
|
10
10
|
|
|
@@ -5,6 +5,6 @@
|
|
|
5
5
|
* 保留所有权利 All Rights Reserved.
|
|
6
6
|
* /home/ryan/workspace/nova/nova-admin/dist/fmode-ng/esm2022/lib/social/wechat/wechat-jssdk.service.mjs
|
|
7
7
|
*/
|
|
8
|
-
import{HttpClient}from"@angular/common/http";import{Injectable}from"@angular/core";import{AuthService}from"../../user/login/auth.service";import Parse from"parse";import*as i0 from"@angular/core";import*as i1 from"@angular/common/http";import*as i2 from"../../user/login/auth.service";export class WechatJssdkService{constructor(e,t){this.http=e,this.authServ=t,this.isInit=!1,this.isWechat=!1,this.wechatAccountId="wxb4193c93ae9aa696";let i=-1!==navigator.userAgent.toLowerCase().indexOf("micromessenger");this.isWechat=i,this.company=this.authServ.company||localStorage.getItem("company")}async setCurrentPageShareInfo(e={title:"飞码AI",desc:"解放创意引领未来|国际前沿的AIGC平台",link:location.href,type:"link",imgUrl:"https://file-cloud.fmode.cn/E4KpGvTEto/20230822/3mkf41033623275.png",success:()=>{console.log("分享成功")},error:()=>{console.log("分享失败")},cancel:()=>{console.log("取消分享")}}){const t=await this.getWXSignPackageInWechat();wx.config({debug:!1,appId:t.appid,timestamp:t.timestamp,nonceStr:t.nonceStr,signature:t.signature,jsApiList:["chooseWXPay","onMenuShareTimeline","onMenuShareAppMessage","onMenuShareQQ","onMenuShareQZone","updateAppMessageShareData","updateTimelineShareData"]}),"link"==e?.type&&(e.link=this.getInviteUrl(e.link)),wx.ready((()=>{wx.updateAppMessageShareData(e),wx.updateTimelineShareData(e)})),wx.error((()=>{}))}getInviteUrl(e){let t="?";t=e?.indexOf("?")>-1?"&":"?";let i=Parse.User?.current()?.id;if(-1==e?.indexOf("invite="+i)){if(!i)return e;e+=t+"invite="+i}return e}getWXSignPackageInWechat(){let e={company:this.company,href:encodeURIComponent(location.href)};return new Promise((t=>{this.http.post("https://server.fmode.cn/api/wechat/getconfig",e).subscribe((e=>{let i=e.data;t(i)}))}))}async initUserOpenid(){await this.init();let e=this.getQueryStringByName("code"),t=localStorage.getItem("openid");if(!t){if(!Parse.User.current())return;if(t=Parse?.User?.current()?.get("wechat")?.[this.wechatAccountId]?.openid,this.isWechat&&!t){let t=window.location.pathname;e?await this.getwechat(e,t):this.authWechat(t)}else this.openid=t}}authWechat(e="/account/billing"){if(!localStorage.getItem("openid")){let t="https://ai.fmode.cn"+e;return t=encodeURIComponent(t),void(window.location.href="https://open.weixin.qq.com/connect/oauth2/authorize?appid="+this.wechatAccountId+"&redirect_uri="+t+"&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect")}}getQueryStringByName(e){let t=location.search.match(new RegExp("[?&]"+e+"=([^&]+)","i"));return null==t||t.length<1?"":t[1]}async getwechat(e,t="/account/billing"){return new Promise((async(i,a)=>{this.http.post("https://server.fmode.cn/api/wechat/get_wx",{company:this.company,code:e}).subscribe((async e=>{if(console.log(e),e&&200==e.code&&e.data.openid){let t=e.data.openid;localStorage.setItem("openid",t),localStorage.removeItem("code");let a={};a[this.wechatAccountId]={openid:t},Parse.User.current().set("wechat",a),await Parse.User.current().save(),i(!0)}}),(async e=>{console.log("Error updating items",e),this.authWechat(t),a(!1)}))}))}init(){return new Promise((e=>{this.isWechat||e(!1),this.isInit&&e(!0),wx&&e(!0),this.loadScript("https://res.wx.qq.com/open/js/jweixin-1.6.0.js",(()=>{this.isInit=!0,this.wx=wx,e(!0)}),(()=>{e(!1)}))}))}loadScript(e,t,i){var a=document.createElement("script");a.src=e,a.onload=()=>{t&&t()},a.onerror=()=>{i&&i()},document.body.appendChild(a)}static{this.ɵfac=i0.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"17.3.12",ngImport:i0,type:WechatJssdkService,deps:[{token:i1.HttpClient},{token:i2.AuthService}],target:i0.ɵɵFactoryTarget.Injectable})}static{this.ɵprov=i0.ɵɵngDeclareInjectable({minVersion:"12.0.0",version:"17.3.12",ngImport:i0,type:WechatJssdkService,providedIn:"root"})}}i0.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"17.3.12",ngImport:i0,type:WechatJssdkService,decorators:[{type:Injectable,args:[{providedIn:"root"}]}],ctorParameters:()=>[{type:i1.HttpClient},{type:i2.AuthService}]});
|
|
8
|
+
import{HttpClient}from"@angular/common/http";import{Injectable}from"@angular/core";import{AuthService}from"../../user/login/auth.service";import Parse from"parse";import*as i0 from"@angular/core";import*as i1 from"@angular/common/http";import*as i2 from"../../user/login/auth.service";export class WechatJssdkService{constructor(e,t){this.http=e,this.authServ=t,this.isInit=!1,this.isWechat=!1,this.wechatAccountId=localStorage.getItem("WECHAT_APP_ID")||"wxb4193c93ae9aa696";let i=-1!==navigator.userAgent.toLowerCase().indexOf("micromessenger");this.isWechat=i,this.company=this.authServ.company||localStorage.getItem("company")}async setCurrentPageShareInfo(e={title:"飞码AI",desc:"解放创意引领未来|国际前沿的AIGC平台",link:location.href,type:"link",imgUrl:"https://file-cloud.fmode.cn/E4KpGvTEto/20230822/3mkf41033623275.png",success:()=>{console.log("分享成功")},error:()=>{console.log("分享失败")},cancel:()=>{console.log("取消分享")}}){const t=await this.getWXSignPackageInWechat();wx.config({debug:!1,appId:t.appid,timestamp:t.timestamp,nonceStr:t.nonceStr,signature:t.signature,jsApiList:["chooseWXPay","onMenuShareTimeline","onMenuShareAppMessage","onMenuShareQQ","onMenuShareQZone","updateAppMessageShareData","updateTimelineShareData"]}),"link"==e?.type&&(e.link=this.getInviteUrl(e.link)),wx.ready((()=>{wx.updateAppMessageShareData(e),wx.updateTimelineShareData(e)})),wx.error((()=>{}))}getInviteUrl(e){let t="?";t=e?.indexOf("?")>-1?"&":"?";let i=Parse.User?.current()?.id;if(-1==e?.indexOf("invite="+i)){if(!i)return e;e+=t+"invite="+i}return e}getWXSignPackageInWechat(){let e={company:this.company,href:encodeURIComponent(location.href)};return new Promise((t=>{this.http.post("https://server.fmode.cn/api/wechat/getconfig",e).subscribe((e=>{let i=e.data;t(i)}))}))}async initUserOpenid(){await this.init();let e=this.getQueryStringByName("code"),t=localStorage.getItem("openid");if(!t){if(!Parse.User.current())return;if(t=Parse?.User?.current()?.get("wechat")?.[this.wechatAccountId]?.openid,this.isWechat&&!t){let t=window.location.pathname;e?await this.getwechat(e,t):this.authWechat(t)}else this.openid=t}}authWechat(e="/account/billing"){if(!localStorage.getItem("openid")){let t="https://ai.fmode.cn"+e;return t=encodeURIComponent(t),void(window.location.href="https://open.weixin.qq.com/connect/oauth2/authorize?appid="+this.wechatAccountId+"&redirect_uri="+t+"&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect")}}getQueryStringByName(e){let t=location.search.match(new RegExp("[?&]"+e+"=([^&]+)","i"));return null==t||t.length<1?"":t[1]}async getwechat(e,t="/account/billing"){return new Promise((async(i,a)=>{this.http.post("https://server.fmode.cn/api/wechat/get_wx",{company:this.company,code:e}).subscribe((async e=>{if(console.log(e),e&&200==e.code&&e.data.openid){let t=e.data.openid;localStorage.setItem("openid",t),localStorage.removeItem("code");let a={};a[this.wechatAccountId]={openid:t},Parse.User.current().set("wechat",a),await Parse.User.current().save(),i(!0)}}),(async e=>{console.log("Error updating items",e),this.authWechat(t),a(!1)}))}))}init(){return new Promise((e=>{this.isWechat||e(!1),this.isInit&&e(!0),wx&&e(!0),this.loadScript("https://res.wx.qq.com/open/js/jweixin-1.6.0.js",(()=>{this.isInit=!0,this.wx=wx,e(!0)}),(()=>{e(!1)}))}))}loadScript(e,t,i){var a=document.createElement("script");a.src=e,a.onload=()=>{t&&t()},a.onerror=()=>{i&&i()},document.body.appendChild(a)}static{this.ɵfac=i0.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"17.3.12",ngImport:i0,type:WechatJssdkService,deps:[{token:i1.HttpClient},{token:i2.AuthService}],target:i0.ɵɵFactoryTarget.Injectable})}static{this.ɵprov=i0.ɵɵngDeclareInjectable({minVersion:"12.0.0",version:"17.3.12",ngImport:i0,type:WechatJssdkService,providedIn:"root"})}}i0.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"17.3.12",ngImport:i0,type:WechatJssdkService,decorators:[{type:Injectable,args:[{providedIn:"root"}]}],ctorParameters:()=>[{type:i1.HttpClient},{type:i2.AuthService}]});
|
|
9
9
|
var MODULE_PATH_NEED = `6K+l5paH5Lu25piv5pys6aG555uu55qE5LiA6YOo5YiGIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBDb21wb25lbnRzIGluIEZtb2RlIEluYy4KICAgIOeJiOadg+aJgOaciSDCqSDmnKrmnaXpo57pqawgwqkg5rGf6KW/6ISR5o6n56eR5oqA5pyJ6ZmQ5YWs5Y+4IENvcHlyaWdodCDCqSBGbW9kZSBUZWNobm9sb2d5IENvLiwgTHRkLgogICAg5L+d55WZ5omA5pyJ5p2D5YipIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAgICDkuKXnpoHlnKjmnKrnu4/mjojmnYPnmoTmg4XlhrXkuIvvvIzpgJrov4fku7vkvZXlqpLku4vlpI3liLbmraTmlofku7YgVW5hdXRob3JpemVkIGNvcHlpbmcgb2YgdGhpcyBmaWxlLCB2aWEgYW55IG1lZGl1bSBpcyBzdHJpY3RseSBwcm9oaWJpdGVkCiAgICDor6Xmlofku7bmmK/kuJPmnInnmoTmnLrlr4bmlofku7YgUHJvcHJpZXRhcnkgYW5kIGNvbmZpZGVudGlhbAogICAKICAgIENvcHlyaWdodCAyMDIxLW5vdyBGbW9kZSBJbmMuIHN1cHBvcnRAZm1vZGUuY24uIDE4NjA3MDA3MDczLgogICAg5L+d55WZ5omA5pyJ5p2D5YipIEFsbCByaWdodHMgcmVzZXJ2ZWQuCgogICAgUEFUSDovaG9tZS9yeWFuL3dvcmtzcGFjZS9ub3ZhL25vdmEtYWRtaW4vZGlzdC9mbW9kZS1uZy9lc20yMDIyL2xpYi9zb2NpYWwvd2VjaGF0L3dlY2hhdC1qc3Nkay5zZXJ2aWNlLm1qcw==`
|
|
10
10
|
|
|
@@ -5,6 +5,6 @@
|
|
|
5
5
|
* 保留所有权利 All Rights Reserved.
|
|
6
6
|
* /home/ryan/workspace/nova/nova-admin/dist/fmode-ng/esm2022/lib/user/account/account.service.mjs
|
|
7
7
|
*/
|
|
8
|
-
import{Injectable}from"@angular/core";import{NovaCloudService}from"../../nova-cloud/nova-cloud.service";import Parse from"parse";import{AuthService}from"../login/auth.service";import{HttpClient}from"@angular/common/http";import*as i0 from"@angular/core";import*as i1 from"../../nova-cloud/nova-cloud.service";import*as i2 from"../login/auth.service";import*as i3 from"@angular/common/http";export class AccountService{constructor(e,t,o){this.ncloud=e,this.authServ=t,this.http=o,this.company="",this.billing={credit:{usedDetail:{}}},this.wxAppId="",this.wxpayEnabled=!1,this.appid="wxb4193c93ae9aa696",this.company=this.authServ.company||localStorage.getItem("company"),this.getBilling(),this.getProfile(),this.getUserOpenid()}async getProfile(){let e=Parse.User.current()?.id;if(!e)return;let t=new Parse.Query("Profile");t.equalTo("user",e),t.equalTo("company",this.company),t.notEqualTo("isDeleted",!0);let o=await t.first();o?.id&&(this.profile=o)}async getBilling(){let e;try{e=await this.ncloud.apig("aigc/account",null,"get")}catch(e){}return e?.credit&&(this.billing=e),e}async getUserOpenid(){let e=-1!=navigator.userAgent.toLowerCase().indexOf("micromessenger"),t=this.getQueryStringByName("code"),o=localStorage.getItem("openid");if(!o){if(!Parse.User.current())return;let i=Parse.User.current().get("wechat");o=i?.[this.appid]?.openid,e&&(t?await this.getwechat(t):this.authWechat())}}authWechat(e="/account/billing"){if(!localStorage.getItem("openid")){let
|
|
8
|
+
import{Injectable}from"@angular/core";import{NovaCloudService}from"../../nova-cloud/nova-cloud.service";import Parse from"parse";import{AuthService}from"../login/auth.service";import{HttpClient}from"@angular/common/http";import*as i0 from"@angular/core";import*as i1 from"../../nova-cloud/nova-cloud.service";import*as i2 from"../login/auth.service";import*as i3 from"@angular/common/http";export class AccountService{constructor(e,t,o){this.ncloud=e,this.authServ=t,this.http=o,this.company="",this.billing={credit:{usedDetail:{}}},this.wxAppId="",this.wxpayEnabled=!1,this.appid=localStorage.getItem("WECHAT_APP_ID")||"wxb4193c93ae9aa696",this.company=this.authServ.company||localStorage.getItem("company"),this.getBilling(),this.getProfile(),this.getUserOpenid()}async getProfile(){let e=Parse.User.current()?.id;if(!e)return;let t=new Parse.Query("Profile");t.equalTo("user",e),t.equalTo("company",this.company),t.notEqualTo("isDeleted",!0);let o=await t.first();o?.id&&(this.profile=o)}async getBilling(){let e;try{e=await this.ncloud.apig("aigc/account",null,"get")}catch(e){}return e?.credit&&(this.billing=e),e}async getUserOpenid(){let e=-1!=navigator.userAgent.toLowerCase().indexOf("micromessenger"),t=this.getQueryStringByName("code"),o=localStorage.getItem("openid");if(!o){if(!Parse.User.current())return;let i=Parse.User.current().get("wechat");o=i?.[this.appid]?.openid,e&&(t?await this.getwechat(t):this.authWechat())}}authWechat(e="/account/billing"){if(!localStorage.getItem("openid")){let e=window.location.href;return e=encodeURIComponent(e),void(window.location.href="https://open.weixin.qq.com/connect/oauth2/authorize?appid="+this.appid+"&redirect_uri="+e+"&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect")}}getQueryStringByName(e){let t=location.search.match(new RegExp("[?&]"+e+"=([^&]+)","i"));return null==t||t.length<1?"":t[1]}async getwechat(e,t="/account/billing"){return new Promise((async(o,i)=>{this.http.post("https://server.fmode.cn/api/wechat/get_wx",{company:this.company,code:e}).subscribe((async e=>{if(console.log(e),e&&200==e.code&&e.data.openid){let t=e.data.openid;localStorage.setItem("openid",t),localStorage.removeItem("code");let i={};i[this.appid]={openid:t},Parse.User.current().set("wechat",i),await Parse.User.current().save(),o(!0)}}),(async e=>{console.log("Error updating items",e),this.authWechat(t),i(!1)}))}))}getWXSignPackageInWechat(){let e={company:this.company,href:encodeURIComponent(location.href.split("?")[0])};this.http.post("https://server.fmode.cn/api/wechat/getconfig",e).subscribe((e=>{const t=e.data;this.wxAppId=t.appid,this.wxpayEnabled=!0,wx.config({debug:!1,appId:t.appid,timestamp:t.timestamp,nonceStr:t.nonceStr,signature:t.signature,jsApiList:["chooseWXPay","onMenuShareTimeline","onMenuShareAppMessage","onMenuShareQQ","onMenuShareQZone","updateAppMessageShareData","updateTimelineShareData"]});let o="https://ai.fmode.cn";location.pathname;Parse.User.current()?.id;let i=this.shareInfo||{title:"飞码AI",desc:"解放创意引领未来|国际前沿的AIGC平台",link:o,type:"link",imgUrl:"https://file-cloud.fmode.cn/E4KpGvTEto/20230822/3mkf41033623275.png",success:function(){console.log("分享成功")},error:function(){console.log("分享失败")},cancel:function(){console.log("取消分享")}};wx.ready((()=>{wx.updateAppMessageShareData(i),wx.updateTimelineShareData(i)})),wx.error((()=>{}))}))}async saveAccountLog(e,t,o,i){return new Promise(((a,r)=>{this.http.post("https://test.fmode.cn/api/apig/saveAccountLog",{company:o,uid:Parse.User.current().id,orderid:t,info:e}).subscribe((e=>{console.log(e),a(!0)}),(e=>{console.warn(e),i&&i.error("请求超时,请稍后再试"),r()}))}))}static{this.ɵfac=i0.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"17.3.12",ngImport:i0,type:AccountService,deps:[{token:i1.NovaCloudService},{token:i2.AuthService},{token:i3.HttpClient}],target:i0.ɵɵFactoryTarget.Injectable})}static{this.ɵprov=i0.ɵɵngDeclareInjectable({minVersion:"12.0.0",version:"17.3.12",ngImport:i0,type:AccountService,providedIn:"root"})}}i0.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"17.3.12",ngImport:i0,type:AccountService,decorators:[{type:Injectable,args:[{providedIn:"root"}]}],ctorParameters:()=>[{type:i1.NovaCloudService},{type:i2.AuthService},{type:i3.HttpClient}]});
|
|
9
9
|
var MODULE_PATH_NEED = `6K+l5paH5Lu25piv5pys6aG555uu55qE5LiA6YOo5YiGIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBDb21wb25lbnRzIGluIEZtb2RlIEluYy4KICAgIOeJiOadg+aJgOaciSDCqSDmnKrmnaXpo57pqawgwqkg5rGf6KW/6ISR5o6n56eR5oqA5pyJ6ZmQ5YWs5Y+4IENvcHlyaWdodCDCqSBGbW9kZSBUZWNobm9sb2d5IENvLiwgTHRkLgogICAg5L+d55WZ5omA5pyJ5p2D5YipIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAgICDkuKXnpoHlnKjmnKrnu4/mjojmnYPnmoTmg4XlhrXkuIvvvIzpgJrov4fku7vkvZXlqpLku4vlpI3liLbmraTmlofku7YgVW5hdXRob3JpemVkIGNvcHlpbmcgb2YgdGhpcyBmaWxlLCB2aWEgYW55IG1lZGl1bSBpcyBzdHJpY3RseSBwcm9oaWJpdGVkCiAgICDor6Xmlofku7bmmK/kuJPmnInnmoTmnLrlr4bmlofku7YgUHJvcHJpZXRhcnkgYW5kIGNvbmZpZGVudGlhbAogICAKICAgIENvcHlyaWdodCAyMDIxLW5vdyBGbW9kZSBJbmMuIHN1cHBvcnRAZm1vZGUuY24uIDE4NjA3MDA3MDczLgogICAg5L+d55WZ5omA5pyJ5p2D5YipIEFsbCByaWdodHMgcmVzZXJ2ZWQuCgogICAgUEFUSDovaG9tZS9yeWFuL3dvcmtzcGFjZS9ub3ZhL25vdmEtYWRtaW4vZGlzdC9mbW9kZS1uZy9lc20yMDIyL2xpYi91c2VyL2FjY291bnQvYWNjb3VudC5zZXJ2aWNlLm1qcw==`
|
|
10
10
|
|