feat: api创建
This commit is contained in:
12
package-lock.json
generated
12
package-lock.json
generated
@@ -9,6 +9,7 @@
|
||||
"version": "0.0.0",
|
||||
"hasInstallScript": true,
|
||||
"dependencies": {
|
||||
"@microsoft/fetch-event-source": "^2.0.1",
|
||||
"axios": "^1.3.6",
|
||||
"gsap": "^3.13.0",
|
||||
"normalize.css": "^8.0.1",
|
||||
@@ -581,6 +582,12 @@
|
||||
"@jridgewell/sourcemap-codec": "^1.4.14"
|
||||
}
|
||||
},
|
||||
"node_modules/@microsoft/fetch-event-source": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@microsoft/fetch-event-source/-/fetch-event-source-2.0.1.tgz",
|
||||
"integrity": "sha512-W6CLUJ2eBMw3Rec70qrsEW0jOm/3twwJv21mrmj2yORiaVmVYGS4sSS5yUwvQc1ZlDLYGPnClVWmUUMagKNsfA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@nodelib/fs.scandir": {
|
||||
"version": "2.1.5",
|
||||
"resolved": "https://registry.npmmirror.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
|
||||
@@ -8827,6 +8834,11 @@
|
||||
"@jridgewell/sourcemap-codec": "^1.4.14"
|
||||
}
|
||||
},
|
||||
"@microsoft/fetch-event-source": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@microsoft/fetch-event-source/-/fetch-event-source-2.0.1.tgz",
|
||||
"integrity": "sha512-W6CLUJ2eBMw3Rec70qrsEW0jOm/3twwJv21mrmj2yORiaVmVYGS4sSS5yUwvQc1ZlDLYGPnClVWmUUMagKNsfA=="
|
||||
},
|
||||
"@nodelib/fs.scandir": {
|
||||
"version": "2.1.5",
|
||||
"resolved": "https://registry.npmmirror.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
"postinstall": "husky install"
|
||||
},
|
||||
"dependencies": {
|
||||
"@microsoft/fetch-event-source": "^2.0.1",
|
||||
"axios": "^1.3.6",
|
||||
"gsap": "^3.13.0",
|
||||
"normalize.css": "^8.0.1",
|
||||
|
||||
33
src/api/login.ts
Normal file
33
src/api/login.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
interface LoginParamsType {
|
||||
name?: string // 姓名
|
||||
email: string // 邮箱
|
||||
password: string // 密码
|
||||
operationType: 'REGISTER' | 'LOGIN' | 'FORGET_PWD'
|
||||
verifyCode?: string // 验证码
|
||||
}
|
||||
|
||||
export const precheckAndSendEmail = (data: LoginParamsType) => {
|
||||
return request({
|
||||
url: '/api/auth/precheckAndSendEmail',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export const fetchLogin = (data: LoginParamsType) => {
|
||||
return request({
|
||||
url: '/api/auth/registerOrLogin',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export const resetPassword = (data: LoginParamsType) => {
|
||||
return request({
|
||||
url: '/api/auth/forgotPwd',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
@@ -7,3 +7,4 @@ store.use(createPersistedState())
|
||||
export default store
|
||||
export * from './modules/generate'
|
||||
export * from './modules/overall'
|
||||
export * from './modules/userInfo'
|
||||
|
||||
@@ -3,40 +3,73 @@ import { defineStore } from 'pinia'
|
||||
import { ref, computed } from 'vue'
|
||||
|
||||
export const useUserInfoStore = defineStore('userInfo', () => {
|
||||
// state
|
||||
const num = ref(0)
|
||||
const name = ref('张三')
|
||||
const token = ref('')
|
||||
const state = ref({
|
||||
userInfo: {},
|
||||
customerId: '',
|
||||
token: '',
|
||||
generateParams: {
|
||||
stylistId: '',
|
||||
sex: ''
|
||||
}
|
||||
})
|
||||
|
||||
// getters
|
||||
const getUserInfo = computed(() => ({
|
||||
num: num.value,
|
||||
name: name.value,
|
||||
token: token.value
|
||||
}))
|
||||
const getUserInfo = computed(() => state.value.userInfo)
|
||||
|
||||
// actions
|
||||
const setUserInfo = (data: any) => {
|
||||
name.value = data.name
|
||||
token.value = data.token
|
||||
state.value.userInfo = data
|
||||
}
|
||||
|
||||
const loginOut = () => {
|
||||
const setCustomerId = (data: string) => {
|
||||
state.value.customerId = data
|
||||
}
|
||||
|
||||
const setToken = (data: string) => {
|
||||
state.value.token = data
|
||||
}
|
||||
|
||||
const getGenerateParams = () => {
|
||||
return state.value.generateParams
|
||||
}
|
||||
|
||||
const setGenerateParams = (data: any) => {
|
||||
state.value.generateParams = data
|
||||
}
|
||||
|
||||
const resetGenerateParams = () => {
|
||||
state.value.customerId = ''
|
||||
state.value.generateParams = {
|
||||
stylistId: '',
|
||||
sex: ''
|
||||
}
|
||||
}
|
||||
|
||||
const login = async (data: any) => {
|
||||
return new Promise((resolve, reject) => {})
|
||||
}
|
||||
|
||||
const logOut = () => {
|
||||
// 处理退出登录的一些逻辑
|
||||
return new Promise((rez) => {
|
||||
rez('111')
|
||||
return new Promise((resolve) => {
|
||||
state.value.token = ''
|
||||
state.value.userInfo = {}
|
||||
state.value.customerId = ''
|
||||
resetGenerateParams()
|
||||
resolve('')
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
// state
|
||||
num,
|
||||
name,
|
||||
token,
|
||||
// getters
|
||||
state,
|
||||
getUserInfo,
|
||||
// actions
|
||||
setToken,
|
||||
setUserInfo,
|
||||
loginOut
|
||||
setCustomerId,
|
||||
setGenerateParams,
|
||||
getGenerateParams,
|
||||
resetGenerateParams,
|
||||
logOut,
|
||||
login
|
||||
}
|
||||
})
|
||||
|
||||
@@ -10,7 +10,7 @@ import { useOverallStore } from '@/stores'
|
||||
// 创建axios实例
|
||||
console.log(import.meta.env.VITE_APP_URL,123)
|
||||
const service = axios.create({
|
||||
baseURL: import.meta.env.VITE_APP_URL, // api的base_url
|
||||
// baseURL: import.meta.env.VITE_APP_URL, // api的base_url
|
||||
// baseURL: import.meta.env.VITE_APP_URL, // api的base_url
|
||||
timeout: 20000, // 请求超时时间
|
||||
})
|
||||
|
||||
@@ -13,8 +13,7 @@
|
||||
<div class="message-text">
|
||||
{{ value.content }}
|
||||
</div>
|
||||
<!-- AI消息显示操作栏 -->
|
||||
<div v-if="!isMyself" class="message-actions flex">
|
||||
<!-- <div v-if="!isMyself" class="message-actions flex">
|
||||
<SvgIcon
|
||||
v-for="item in actionList"
|
||||
:key="item.value"
|
||||
@@ -22,7 +21,7 @@
|
||||
size="39"
|
||||
@click.stop="handleClickAction(item.value)"
|
||||
/>
|
||||
</div>
|
||||
</div> -->
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="chat-list" ref="chatListRef">
|
||||
<div class="chat-message-item" v-for="message in list" :key="message.id">
|
||||
<NoticeItem :value="message" @send-message="handleSendMessage" />
|
||||
<NoticeItem :value="message" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
</div>
|
||||
<template v-else>
|
||||
<div class="content flex-1" v-if="!isLoading">
|
||||
<NoticeList ref="noticeListRef" :list="messageList" @send-message="handleSendMessage" />
|
||||
<NoticeList ref="noticeListRef" :list="messageList" />
|
||||
</div>
|
||||
<div class="footer" v-if="!isLoading">
|
||||
<InputArea @send-message="handleSendMessage" />
|
||||
@@ -24,12 +24,14 @@ import HeaderTitle from '@/components/HeaderTitle.vue'
|
||||
import NoticeList from './components/NoticeList.vue'
|
||||
import InputArea from './components/InputArea.vue'
|
||||
import GenerateLoading from './components/GenerateLoading.vue'
|
||||
import { ref, onMounted, onActivated } from 'vue'
|
||||
import { ref, onMounted, onUnmounted } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { fetchEventSource } from '@microsoft/fetch-event-source'
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
defineOptions({
|
||||
name:'asistant'
|
||||
name: 'asistant'
|
||||
})
|
||||
|
||||
// 定义NoticeList组件引用类型
|
||||
@@ -80,26 +82,38 @@ const messageList = ref<ChatMessage[]>([
|
||||
}
|
||||
])
|
||||
|
||||
onMounted(() => {
|
||||
console.log('🚀 组件挂载 - onMounted 触发')
|
||||
// handleSendMessage('123')
|
||||
})
|
||||
onMounted(() => {})
|
||||
|
||||
onActivated(() => {
|
||||
console.log('🔄 缓存页面激活 - onActivated 触发')
|
||||
console.log('当前消息数量:', messageList.value.length)
|
||||
onUnmounted(() => {
|
||||
abort.abort()
|
||||
})
|
||||
|
||||
const handleSendMessage = (message: string): void => {
|
||||
console.log('收到消息:', message)
|
||||
messageList.value.push({
|
||||
id: '1',
|
||||
content: message,
|
||||
userId: '1',
|
||||
time: new Date().toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit' }),
|
||||
thumb: ''
|
||||
console.log('发送:', message)
|
||||
handleFetchMessage()
|
||||
}
|
||||
|
||||
const abort = new AbortController()
|
||||
const handleFetchMessage = () => {
|
||||
fetchEventSource('/api/sse', {
|
||||
method: 'POST',
|
||||
openWhenHidden: true,
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({}),
|
||||
signal: abort.signal,
|
||||
onopen: async (res) => {
|
||||
console.log('连接建立', res)
|
||||
},
|
||||
onmessage: (event) => {
|
||||
console.log('收到消息', event)
|
||||
},
|
||||
onerror: (error) => {
|
||||
console.log('错误', error)
|
||||
},
|
||||
onclose: () => {
|
||||
console.log('连接关闭')
|
||||
}
|
||||
})
|
||||
//
|
||||
}
|
||||
|
||||
const handleContinue = () => {
|
||||
|
||||
@@ -48,6 +48,7 @@ import { ref, reactive, computed } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { showToast } from 'vant'
|
||||
import { google } from '@/assets/base64'
|
||||
import { fetchLogin } from '@/api/login'
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
@@ -108,23 +109,19 @@ const handleLogin = async () => {
|
||||
|
||||
isLoading.value = true
|
||||
|
||||
try {
|
||||
// 模拟登录API调用
|
||||
await new Promise((resolve) => setTimeout(resolve, 2000))
|
||||
|
||||
// 这里添加实际的登录API调用
|
||||
// const response = await loginAPI(formData)
|
||||
|
||||
showToast('登录成功')
|
||||
|
||||
// 登录成功后跳转到主页或工作台
|
||||
router.push('/stylist/customer')
|
||||
} catch (error) {
|
||||
console.error('登录失败:', error)
|
||||
showToast('登录失败,请重试')
|
||||
} finally {
|
||||
isLoading.value = false
|
||||
const response: any = await fetchLogin({ ...formData, operationType: 'LOGIN' } as any)
|
||||
if (response.code === 200) {
|
||||
console.log('登录成功', response)
|
||||
// showToast('登录成功')
|
||||
// router.push('/stylist/customer')
|
||||
} else {
|
||||
showToast(response.message)
|
||||
}
|
||||
|
||||
// showToast('登录成功')
|
||||
|
||||
// 登录成功后跳转到主页或工作台
|
||||
// router.push('/stylist/customer')
|
||||
}
|
||||
|
||||
// 处理忘记密码
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
</div>
|
||||
|
||||
<div class="login-container">
|
||||
<form @submit.prevent="handleLogin" class="login-form">
|
||||
<form @submit.prevent="handleConfirm" class="login-form">
|
||||
<div class="input-group">
|
||||
<input
|
||||
type="text"
|
||||
@@ -68,6 +68,7 @@ import { ref, reactive, computed } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { showToast } from 'vant'
|
||||
import { google } from '@/assets/base64'
|
||||
import { fetchLogin } from '@/api/login'
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
@@ -151,7 +152,7 @@ const goBack = () => {
|
||||
}
|
||||
|
||||
// 处理登录
|
||||
const handleLogin = async () => {
|
||||
const handleConfirm = async () => {
|
||||
if (!validateForm()) {
|
||||
showToast('请检查输入信息')
|
||||
return
|
||||
@@ -159,22 +160,13 @@ const handleLogin = async () => {
|
||||
|
||||
isLoading.value = true
|
||||
|
||||
try {
|
||||
// 模拟登录API调用
|
||||
await new Promise((resolve) => setTimeout(resolve, 2000))
|
||||
|
||||
// 这里添加实际的登录API调用
|
||||
// const response = await loginAPI(formData)
|
||||
|
||||
showToast('登录成功')
|
||||
|
||||
// 登录成功后跳转到主页或工作台
|
||||
router.push('/workshop')
|
||||
} catch (error) {
|
||||
console.error('登录失败:', error)
|
||||
showToast('登录失败,请重试')
|
||||
} finally {
|
||||
isLoading.value = false
|
||||
const res:any = await fetchLogin({...formData, operationType: 'REGISTER'} as any)
|
||||
if(res.code === 200) {
|
||||
console.log('注册成功', res)
|
||||
// showToast('注册成功')
|
||||
// router.push('/stylist/customer')
|
||||
} else {
|
||||
showToast(res.message)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -26,11 +26,11 @@
|
||||
<div class="glass-form">
|
||||
<div class="form-field">
|
||||
<label class="field-label">Customer Name</label>
|
||||
<input type="text" placeholder="Name" class="form-input" />
|
||||
<input v-model="customeData.name" type="text" placeholder="Name" class="form-input" />
|
||||
</div>
|
||||
<div class="form-field email">
|
||||
<label class="field-label">Customer Email</label>
|
||||
<input type="email" placeholder="Email" class="form-input" />
|
||||
<input v-model="customeData.email" type="email" placeholder="Email" class="form-input" />
|
||||
</div>
|
||||
<button class="confirm-btn" @click="handleConfirm">Confirm</button>
|
||||
</div>
|
||||
@@ -42,6 +42,9 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { useUserInfoStore } from '@/stores'
|
||||
import { showToast } from 'vant'
|
||||
const userInfoStore = useUserInfoStore()
|
||||
const router = useRouter()
|
||||
|
||||
type PageMode = 'form' | 'entry'
|
||||
@@ -51,8 +54,20 @@ const handleChangeMode = (mode: PageMode) => {
|
||||
pageMode.value = mode
|
||||
}
|
||||
|
||||
const handleConfirm = () => {
|
||||
console.log('handleConfirm')
|
||||
const customeData = ref({
|
||||
name: '',
|
||||
email: ''
|
||||
})
|
||||
|
||||
const handleConfirm = async () => {
|
||||
if (customeData.value.name === '' || customeData.value.email === '') {
|
||||
showToast('please input name and email')
|
||||
return
|
||||
}
|
||||
|
||||
// await 查找顾客ID
|
||||
// userInfoStore.setCustomerId('')
|
||||
|
||||
router.push('/stylist/index')
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
<van-icon name="arrow-left" color="#fff" size="40" />
|
||||
</div>
|
||||
|
||||
<van-swipe touchable ref="swiperRef">
|
||||
<van-swipe touchable ref="swiperRef" @change="handleChangeCurrent">
|
||||
<van-swipe-item v-for="item in stylists" :key="item.id">
|
||||
<div class="swiper-container" @click="handleClickStylist(item)">
|
||||
<img :src="item.image" />
|
||||
@@ -64,9 +64,10 @@
|
||||
import { ref, watch } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import Video from './components/Video.vue'
|
||||
import { useUserInfoStore } from '@/stores'
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
const userInfoStore = useUserInfoStore()
|
||||
// stylist数据
|
||||
const stylists = ref<any[]>([
|
||||
{
|
||||
@@ -94,11 +95,17 @@ const stylists = ref<any[]>([
|
||||
image: '/src/assets/images/male.png'
|
||||
}
|
||||
])
|
||||
const currentChoosed=ref('')
|
||||
|
||||
const swiperRef = ref<any>(null)
|
||||
const showVideo = ref<boolean>(false)
|
||||
const videoRef = ref<any>(null)
|
||||
|
||||
|
||||
const handleChangeCurrent=(index:number)=>{
|
||||
currentChoosed.value = stylists.value[index].id
|
||||
}
|
||||
|
||||
const handleChangeSwiper = (type: 'next' | 'prev') => {
|
||||
if (type === 'next') {
|
||||
swiperRef.value.next()
|
||||
@@ -113,7 +120,10 @@ const handleClickStylist = (item: any) => {
|
||||
}
|
||||
|
||||
const handleContinue = () => {
|
||||
// 跳转到下一个页面
|
||||
const generateParams = userInfoStore.getGenerateParams()
|
||||
generateParams.stylistId = currentChoosed.value
|
||||
userInfoStore.setGenerateParams(generateParams)
|
||||
|
||||
router.push('/stylist/sex')
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,9 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import {useUserInfoStore} from '@/stores'
|
||||
const router = useRouter()
|
||||
const userInfoStore = useUserInfoStore()
|
||||
|
||||
const options = ref<any[]>([
|
||||
{ label: 'Female', value: '1' },
|
||||
@@ -26,7 +28,9 @@ const options = ref<any[]>([
|
||||
])
|
||||
|
||||
const handleSelect = (value: string) => {
|
||||
console.log(value)
|
||||
const generateParams = userInfoStore.getGenerateParams()
|
||||
generateParams.sex = value
|
||||
userInfoStore.setGenerateParams(generateParams)
|
||||
router.push('/stylist/dressfor')
|
||||
}
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user