2025/2/8第一次更新

This commit is contained in:
爱吃咸鱼小猫咪
2025-02-08 18:50:38 +08:00
commit d7af560866
26519 changed files with 5046029 additions and 0 deletions
+57
View File
@@ -0,0 +1,57 @@
import {request} from "@/utils/request.ts";
import {useAppStore} from "@/stores/appStore.ts";
import type {
IPayOrder,
IPayOrderCreatWechatMiniProgramPay,
IWechatPrePay,
IProduct,
User,
IMember,
IMiniProgramContent, IWorkFlow
} from "@/types";
import {computed} from "vue";
import {storeToRefs} from "pinia";
import {EventType} from "@/types/event.types.ts";
import {emit} from "@/utils/emitter.ts";
/** 微信登录 */
export const loginByWechatCode=(code:string)=>request<User>(`auth/loginByWechatMiniProgram?code=${code}`)
/** 用户名密码登录 */
export const loginByUsername=(data:{username: string, password: string})=>request('/users/loginByUsername',{method:'POST',data})
/** 退出登录 */
export const loginOut=()=>{useAppStore().clearUser();emit(EventType.AUTH_LOGOUT, null)}
/** 保存登录信息到本地 */
export const saveLoginInfo=(user:Partial<User>)=>useAppStore().setUser(user)
/** 获取登录信息 */
export const getLoginInfo=()=>useAppStore().getUser()
/** 修改用户的昵称和头像 */
export const updateUserInfo=(data:Partial<User>)=>request<User>('/users/update',{method:'POST',data})
/** 重新获取用户信息 */
export const refreshUserInfo=(user=getLoginInfo())=>request<User>(`/users/${user._id}`).then(res=>{useAppStore().setUser(res)})
/** 是否为登录状态 */
export const isLogin =computed(()=>{
const {user}=storeToRefs(useAppStore())
return !!user.value.refresh_token
})
/** 获取用户的会员信息,获取用户最高的权限等级会员信息*/
export const getUserVipInfo=()=>request<IMember>('/member/topLevel',{method:'POST'})
/** 产品套餐相关 */
/** 获取所有的套餐 */
export const getProductList=()=>request<IProduct[]>('/product')
/** 获取订单详情 */
export const getOrderInfoById=(order_id:string)=>request<IPayOrder[]>(`/pay/query`,{method:'POST',data:{_id:order_id}})
/**支付相关*/
export const creatOrder=(data:IPayOrderCreatWechatMiniProgramPay)=>request<IPayOrder>(`/pay/order`,{method:'POST',data})
/** 预支付 */
export const getPrePay=(order_id:string)=>request<IWechatPrePay>(`pay/prePay/${order_id}`)
/** 获取所有的应用 */
export const getApps=()=>request<IWorkFlow[]>('workflow/getAllWorkflowApps/mp')
/** 页面配置相关 */
/** 获取页面配置信息 */
export const getPageContent=()=>request<IMiniProgramContent>(`content/mp/content`)
+43
View File
@@ -0,0 +1,43 @@
import type {IProduct} from "@/types";
import {creatOrder, getLoginInfo, getPrePay} from "@/composables/useCommon.ts";
import {IPayChannel} from "@/types";
export const usePayHandlePayment=async (product:IProduct) => {
// 创建订单
const user = getLoginInfo()
if(!user){
throw new Error('未登录不允许支付')
}
const order =await creatOrder({
user_id:user._id,
product_id:product._id,
amount:{
total:product.amount,
currency:'CNY'
},
payer:{
openid:getLoginInfo().wx_openid_mp as string
},
order_channel:IPayChannel.MP_WEIXIN
})
const {nonceStr,package:_,signType,paySign,timeStamp} =await getPrePay(order._id)
console.log("paySign",paySign)
//调起支付
console.log("created order",order)
uni.requestPayment({
provider:'wxpay',
orderInfo:order.product_id.name,
timeStamp,
nonceStr,
package:_,
signType,
paySign,
success:function (res) {
console.log('success', res)
},
fail:function (err) {
console.log('fail', err)
}
})
}
+346
View File
@@ -0,0 +1,346 @@
import {
type IComfyUIProperties,
type IComfyUIRequestParams,
type IDrawHistoryItem,
type IDrawHistoryItemCreat,
type IDrawResponse,
type IDrawTaskStatus, type IWebSocketParams, IWebsocketSceneType,
type IWorkFlow,
type IWorkflowParam, type SocketState,
} from '@/types';
import {computed, ref,inject} from 'vue'
import {getBaseWsURL, request} from "@/utils/request.ts";
import type {ParamToComponentMapping} from "@/pages/draw/apps/apps.vue";
import {getLoginInfo, isLogin, refreshUserInfo} from "@/composables/useCommon.ts";
import {storeToRefs} from "pinia";
import {useAppStore} from "@/stores/appStore.ts";
import {emit} from "@/utils/emitter.ts";
import {EventType} from "@/types/event.types.ts";
import { parseJSONToObject } from '@/utils/common.ts';
export interface SocketInitOptions {
params?:IWebSocketParams
forceReConnect?: boolean;
onConnect?: () => void;
onReconnect?: (attemptNumber: number) => void;
onReconnectFailed?: () => void;
onDisconnect?: (reason: string) => void;
onConnectError?: (error: any) => void;
onConnectTimeout?: () => void;
onMessage?: (msg: any) => void;
onPayMessage?: (msg: any) => void;
}
/** 提交自定义工作流 */
export const submitCustomWorkflow = (data: IComfyUIRequestParams) => request<IDrawResponse>('/draw/customWorkflow', {
method: 'POST',
data
})
/** 根据工作流的ID获取大模型清单 **/
export const getModelListByWorkflowId = (workflow_id: string) => request<string[]>(`/draw/getModelListById/${workflow_id}`)
/** 创建任务 **/
export const creatDrawHistoryTask = (data: IDrawHistoryItem) => request<IDrawHistoryItem>('/draw/history', {method: 'POST', data})
export default function useWorkFlow() {
const workflow = ref<IWorkFlow>({} as IWorkFlow);
/** 工作流的参数列表 */
const params_component_list = [
{param: 'seed', component: 'Seed', title: '随机种子'},
{param: 'seed_2', component: 'Seed', title: '随机种子'},
{param: 'seed_3', component: 'Seed', title: '随机种子'},
{param: 'seed_4', component: 'Seed', title: '随机种子'},
{param: 'seed_5', component: 'Seed', title: '随机种子'},
{param: 'ckpt_name', component: 'ModeSelect', title: '大模型选择'},
{param: 'positive', component: 'Positive', title: '正向提示词'},
{param: 'width', component: 'Width', title: '图片宽度'},
{param: 'height', component: 'Height', title: '图片高度'},
{param: 'batch_size', component: 'CustomNumberBox', title: '生成批次'},
{param: 'image_path_origin', component: 'ImageUpload', title: '原图上传'},
{param: 'image_path_mask', component: 'ImageUpload', title: '遮罩上传'},
{param: 'image_path_face', component: 'ImageUpload', title: '参考上传'},
{param: 'image_path_style', component: 'ImageUpload', title: '参考上传'},
{param: 'advance_select_image_preview', component: 'ImageSelectPreview', title: '高级-图像预览选择'},
{param: 'advance_select_image_preview_2', component: 'ImageSelectPreview', title: '高级-图像预览选择'},
{param: 'advance_select_image_preview_3', component: 'ImageSelectPreview', title: '高级-图像预览选择'},
{param: 'advance_select_image_preview_4', component: 'ImageSelectPreview', title: '高级-图像预览选择'},
] as ParamToComponentMapping[]
/** 绘图参数 */
const bindParam = ref<IComfyUIProperties>({})
const handleGetWorkFlwById = async (id: string) => {
workflow.value = await request<IWorkFlow>(`/workflow/${id}`)
handleWorkFlowParamsToBindParam()
}
/** 本地绘画任务列表*/
const {localTasks} = storeToRefs(useAppStore())
/** 工作流的参数列表,过滤点产出节点 */
const workFlowParamLists = computed<IWorkflowParam[]>(() => {
if (!workflow.value || !workflow.value.params) {
return [];
}
return workflow.value.params.filter(item => item.name !== 'output') as IWorkflowParam[]
})
/** 产互类型参数 */
const outputType = computed(() => {
if (!workflow.value || !workflow.value.params) {
return 'image'
}
return workflow.value.params.find(item => item.name === 'output')?.outputType || 'image'
})
/** 根据参数名称找组件名称 */
const handleFindComponentName = (param: keyof IComfyUIProperties) => {
const component = params_component_list.find(item => item.param === param);
return component?.component;
}
/** 将工作流的默认参数赋值给bindParams */
const handleWorkFlowParamsToBindParam = () => {
if (!workflow.value || !workflow.value.params) {
return;
}
workflow.value.params.forEach(item => {
bindParam.value[item.name] = item.param;
})
}
const socketState = inject<SocketState>('socketState');
if (!socketState) {
throw new Error('socketState is not provided');
}
const closeSocketAsync = () => {
return new Promise((resolve)=>{
uni.closeSocket({
code:1000,
reason:'Initializing new WebSocket',
success(result) {
resolve(true);
},
fail(result) {
resolve(false);
},
})
})
}
const socketInit = async (options:SocketInitOptions= {params:{type:IWebsocketSceneType.drawProcessPush,data:{scene_str:''}}}) => {
//如果未登录状态,不初始化WebSocket
if(!isLogin.value){
throw new Error('未登录状态,不允许初始化Websocket')
}
console.log('socket init executionstatus',socketState.socket?.readyState)
if(socketState?.isInitialized && socketState.options?.params?.type ===options.params?.type){
console.log('WebSocket is already initialized');
return;
}
if(socketState?.isInitialized && socketState?.options.params?.type !==options.params?.type){
//说明场景不一样,需要重新初始化
console.log('WebSocket is already initialized,but scene is different,reinitialize')
await closeSocketAsync()
socketState.isInitialized=false
}
const { params}=options
const {type,data}=params as IWebSocketParams
const {uniPlatform}=uni.getSystemInfoSync()
socketState.socket= uni.connectSocket({
url: `${getBaseWsURL()}?user_id=${getLoginInfo()._id}&type=${type}&platform=${uniPlatform}&data=${data}`,
complete:()=>{
console.log('WebSocket connect complete')
}
});
socketState.isInitialized = true;
uni.onSocketOpen((result) => {
console.log('WebSocket opened',result);
// 保存options
socketState.options = options
if (options.onConnect){
options.onConnect()
}
});
uni.onSocketMessage((msg) => {
if (options.onMessage){
options.onMessage(msg.data)
}
handleSocketMessage(msg.data);
});
uni.onSocketError((err) => {
console.error('WebSocket onError',err);
socketState.isInitialized=false
if (options.onConnectError){
options.onConnectError(err)
}
});
uni.onSocketClose(()=>{
socketState.isInitialized=false
console.log('WebSocket onClose');
if (options.onDisconnect){
options.onDisconnect()
}
})
};
/** 握手消息 */
const handleSocketHandShake = (timeout=200) => {
return new Promise(resolve => {
const timeoutID = setTimeout(() => {
resolve(false)
}, timeout);
if(!socketState || !socketState.socket || !socketState.isInitialized){
resolve(false)
return
}
socketState.socket?.send({
data:'ping',
success(result) {
console.log(result)
clearTimeout(timeoutID)
resolve(true)
},
})
})
}
/** 处理Websocket消息 */
const handleSocketMessage = (msg: any,callback?:(messageObj:any)=>void) => {
console.log('原始消息', msg);
const msgObj = parseJSONToObject<{type:any,data:any,queue_status:IDrawTaskStatus}>(msg)
console.log('handleSocketMessage', msgObj);
//自定义回调
if(callback){
callback(msgObj)
}
const {type, data, queue_status} = msgObj
if (queue_status) {
// 从websocket消息中获取output
const index = localTasks.value.findIndex(item => item._id === queue_status.task_id)
if(index!==-1){
localTasks.value[index].progress=queue_status.progress
localTasks.value[index].queue=queue_status.queue
queue_status.time_remained?localTasks.value[index].time_remained=queue_status.time_remained:null
queue_status.message?localTasks.value[index].message=queue_status.message:null
}
if(queue_status.status ==='started' && index !==-1){
localTasks.value[index].status=4
localTasks.value[index].message='任务开始'
}
if (queue_status.status !== 'failed' && index !== -1 && localTasks.value[index].status === 3) {
localTasks.value[index].status = 0
localTasks.value[index].message = queue_status.message
}
if (queue_status.status === 'success' && index !== -1 && localTasks.value[index].status !== 1) {
localTasks.value[index].output = queue_status.data.output
localTasks.value[index].type = queue_status.data.type
localTasks.value[index].status = 1
console.log('localTasks', localTasks)
refreshUserInfo().then()
}
if (queue_status.status === 'failed') {
if (index !== -1 && localTasks.value[index].status !== 2) {
localTasks.value[index].status = 2
localTasks.value[index].message = queue_status.message
}
}
}
}
/** 创建任务 */
const handleCreateTask = async () => {
const item: IDrawHistoryItemCreat = {
params: {...bindParam.value},
workflow_id: workflow.value._id,
user_id:getLoginInfo()._id,
options: {
workflow_id: workflow.value._id,
workflow_title: workflow.value.title,
workflow_name: workflow.value.name,
},
type: outputType.value
}
return await creatDrawHistoryTask(item)
}
/** 更新本地任务的状态 */
const handleUpdateTaskStatus = async (taskItem:IDrawHistoryItem,output:IDrawResponse) => {
const index = localTasks.value.findIndex(item => item._id === taskItem._id)
if (index !== -1) {
localTasks.value[index].output = output.output
localTasks.value[index].status=1
localTasks.value=[...localTasks.value]
}
}
/** 提交绘画任务到服务器 */
const handleSubmitTaskTask = async () => {
if(!isLogin.value){
uni.showToast({
title: '请先登录',
icon:'none',
duration: 2000
})
return
}
if(!await handleSocketHandShake()){
await socketInit()
}
const newTask = await handleCreateTask()
console.log('newTask',newTask)
if (!newTask) {
return
}
//深拷贝绘图参数
localTasks.value.unshift(newTask)
const requestParams: IComfyUIRequestParams = {
params: {...bindParam.value},
options: {
workflow_id: workflow.value._id,
task_id:newTask._id //重要,已经创建任务的时候传入任务ID,否则系统会新建
}
}
const result= await submitCustomWorkflow(requestParams)
if(result.status==='success' && result.output && result.output.length>0){
await handleUpdateTaskStatus(newTask,result)
refreshUserInfo().then()
}
if (result.status ==='failed'|| result.status==='rejected'){
uni.showToast({
title: result.message,
icon:'none',
duration: 2000
})
}
}
return {
workflow,
workFlowParamLists,
bindParam,
params_component_list,
socketInit,
// socketState,
// closeSocketAsync,
handleFindComponentName,
handleGetWorkFlwById,
handleSubmitTaskTask
}
}