save progress

This commit is contained in:
梁泽军 2025-03-11 18:00:08 +08:00
parent dbf485e0d5
commit 25ea5f2781
25 changed files with 1047 additions and 2901 deletions

View File

@ -1,3 +0,0 @@
# 请求域名
VITE_APP_BASE_URL=''

View File

@ -1,3 +0,0 @@
# 请求域名
VITE_APP_BASE_URL=''

11
.env.test Normal file
View File

@ -0,0 +1,11 @@
#mode 环境
VITE_MODE = test
#服务器域名
VITE_HOST = https://test.szxgl.cn/
# 请求域名
VITE_APP_BASE_URL='https://test.szxgl.cn/ai-agent-admin-server'
#静态资源目录
VITE_CDN_DIR = 'https://agent-admin-test.szxgl.cn/'

View File

@ -56,9 +56,10 @@
"github-markdown-css": "5.2.0", "github-markdown-css": "5.2.0",
"highlight.js": "11.0.0", "highlight.js": "11.0.0",
"howler": "2.2.4", "howler": "2.2.4",
"js-base64": "^3.7.5",
"js-cookie": "^3.0.5",
"js-mp3": "0.1.0", "js-mp3": "0.1.0",
"jsonc-parser": "3.2.1", "jsonc-parser": "3.2.1",
"js-base64": "^3.7.5",
"lodash-es": "4.17.21", "lodash-es": "4.17.21",
"markdown-it": "^13.0.1", "markdown-it": "^13.0.1",
"markdown-it-math": "4.1.1", "markdown-it-math": "4.1.1",

View File

@ -8,6 +8,7 @@ import { useSharedId } from './hooks/useShareMessage'
import { SHARE_ID, USER_SN } from './enums/constantEnums' import { SHARE_ID, USER_SN } from './enums/constantEnums'
import { strToParams } from './utils/util' import { strToParams } from './utils/util'
import cache from './utils/cache' import cache from './utils/cache'
import Cookies from 'js-cookie'
const appStore = useAppStore() const appStore = useAppStore()
const { getUser } = useUserStore() const { getUser } = useUserStore()
@ -44,6 +45,9 @@ const setH5WebIcon = () => {
//#endif //#endif
const getConfig = async () => { const getConfig = async () => {
await setLocalStorage()
//
await appStore.getConfig() await appStore.getConfig()
//h5 //h5
// #ifdef H5 // #ifdef H5
@ -55,6 +59,40 @@ const getConfig = async () => {
// #endif // #endif
} }
//
const setLocalStorage = async () => {
const isWeCom = isWechatWork()
// localStorage
const token = localStorage.getItem('app_token')
const cookiesToken = Cookies.get('token')
if (!cookiesToken) {
if (isWeCom) {
// cookie
const redirect = location.href
Cookies.set('redirect', redirect)
location.href = `${import.meta.env.VITE_APP_BASE_URL}/qywx/getWxUserByInside?terminal=3`
return
}
} else {
const obj = { expire: "", value: cookiesToken }
console.log('obj', obj);
console.log('写入前 token', token);
localStorage.setItem("app_token", JSON.stringify(obj));
}
}
//
const isWechatWork = () => {
const ua = navigator.userAgent.toLowerCase();
// "micromessenger" "wxwork"
return ua.includes('micromessenger') && ua.includes('wxwork');
}
onLaunch(async (opinion) => { onLaunch(async (opinion) => {
getConfig() getConfig()
getTheme() getTheme()
@ -72,5 +110,4 @@ onShow(() => {
}) })
</script> </script>
<style lang="scss"> <style lang="scss">
// //</style>
</style>

View File

@ -1 +1,79 @@
<template> <view class="agreement" v-if="isOpenAgreement" :class="{ shake: isShake }"> <view> <u-checkbox v-model="isActive" shape="circle"> <view class="text-xs flex"> 已阅读并同意 <view @click.stop> <router-navigate class="text-primary" to="/packages/pages/agreement/agreement?type=service" > 《服务协议》 </router-navigate> </view> <view @click.stop> <router-navigate class="text-primary" to="/packages/pages/agreement/agreement?type=privacy" > 《隐私协议》 </router-navigate> </view> </view> </u-checkbox> </view> </view> </template> <script lang="ts" setup> import { useAppStore } from '@/stores/app' import { computed, ref } from 'vue' const appStore = useAppStore() const isActive = ref(false) const isShake = ref(false) const isOpenAgreement = computed( () => appStore.getLoginConfig.openAgreement == 1 ) const checkAgreement = () => { if (!isActive.value && isOpenAgreement.value) { uni.$u.toast('请勾选已阅读并同意《服务协议》和《隐私协议》') isShake.value = true setTimeout(() => { isShake.value = false }, 1000) } else if (!isOpenAgreement.value) { return true } return isActive.value } defineExpose({ checkAgreement }) </script> <style lang="scss"> .shake { animation: shake 0.82s cubic-bezier(0.36, 0.07, 0.19, 0.97) both; transform: translate3d(0, 0, 0); } @keyframes shake { 10%, 90% { transform: translate3d(-1px, 0, 0); } 20%, 80% { transform: translate3d(2px, 0, 0); } 30%, 50%, 70% { transform: translate3d(-4px, 0, 0); } 40%, 60% { transform: translate3d(4px, 0, 0); } } </style> <template>
<view class="agreement" v-if="isOpenAgreement" :class="{ shake: isShake }">
<view>
<u-checkbox v-model="isActive" shape="circle">
<view class="text-xs flex">
已阅读并同意
<view @click.stop>
<router-navigate class="text-primary" to="/packages/pages/agreement/agreement?type=service">
服务协议
</router-navigate>
</view>
<view @click.stop>
<router-navigate class="text-primary" to="/packages/pages/agreement/agreement?type=privacy">
隐私协议
</router-navigate>
</view>
</view>
</u-checkbox>
</view>
</view>
</template>
<script lang="ts" setup>
import { useAppStore } from '@/stores/app'
import { computed, ref } from 'vue'
const appStore = useAppStore()
const isActive = ref(false)
const isShake = ref(false)
const isOpenAgreement = computed(
() => appStore.getLoginConfig.openAgreement == 1
)
const checkAgreement = () => {
if (!isActive.value && isOpenAgreement.value) {
uni.$u.toast('请勾选已阅读并同意《服务协议》和《隐私协议》')
isShake.value = true
setTimeout(() => {
isShake.value = false
}, 1000)
} else if (!isOpenAgreement.value) {
return true
}
return isActive.value
}
defineExpose({
checkAgreement
})
</script>
<style lang="scss">
.shake {
animation: shake 0.82s cubic-bezier(0.36, 0.07, 0.19, 0.97) both;
transform: translate3d(0, 0, 0);
}
@keyframes shake {
10%,
90% {
transform: translate3d(-1px, 0, 0);
}
20%,
80% {
transform: translate3d(2px, 0, 0);
}
30%,
50%,
70% {
transform: translate3d(-4px, 0, 0);
}
40%,
60% {
transform: translate3d(4px, 0, 0);
}
}
</style>

View File

@ -1,8 +1,6 @@
<template> <template>
<view <view class="px-[20rpx] h-[90rpx] text-sm flex items-center justify-between bg-white">
class="px-[20rpx] h-[90rpx] text-sm flex items-center justify-between bg-white" <!-- <view class="flex">
>
<view class="flex">
<u-button <u-button
type="primary" type="primary"
plain plain
@ -23,7 +21,7 @@
}} }}
</router-navigate> </router-navigate>
</u-button> </u-button>
</view> </view> -->
<view> <view>
<view v-if="plugin.key" class="text-muted mr-2 text-xs"> <view v-if="plugin.key" class="text-muted mr-2 text-xs">

View File

@ -1,21 +1,11 @@
<template> <template>
<view class="chat-scroll-view h-full flex flex-col"> <view class="chat-scroll-view h-full flex flex-col">
<view class="flex-1 min-h-0"> <view class="flex-1 min-h-0">
<z-paging <z-paging ref="pagingRef" v-model="chatList" use-chat-record-mode :auto="false" :refresher-enabled="false"
ref="pagingRef" :safe-area-inset-bottom="true" :auto-clean-list-when-reload="false"
v-model="chatList" :show-chat-loading-when-reload="true" :paging-style="{ bottom: keyboardIsShow ? 0 : bottom }"
use-chat-record-mode :default-page-size="20" @query="queryList" @keyboardHeightChange="keyboardHeightChange"
:auto="false" @hidedKeyboard="hidedKeyboard">
:refresher-enabled="false"
:safe-area-inset-bottom="true"
:auto-clean-list-when-reload="false"
:show-chat-loading-when-reload="true"
:paging-style="{ bottom: keyboardIsShow ? 0 : bottom }"
:default-page-size="20"
@query="queryList"
@keyboardHeightChange="keyboardHeightChange"
@hidedKeyboard="hidedKeyboard"
>
<!-- 顶部提示文字 --> <!-- 顶部提示文字 -->
<!-- style="transform: scaleY(-1)"必须写否则会导致列表倒置必须写在for循环标签上不得写在容器上 --> <!-- style="transform: scaleY(-1)"必须写否则会导致列表倒置必须写在for循环标签上不得写在容器上 -->
@ -23,46 +13,26 @@
<template #top> <template #top>
<slot name="top" /> <slot name="top" />
<model-picker <model-picker v-if="!pluginOptions.pluginId" v-model:chatKey="chatKey"
v-if="!pluginOptions.pluginId" v-model:modelKey="modelKey" />
v-model:chatKey="chatKey" <VipUse v-if="pluginOptions.pluginId" :plugin="pluginOptions.current" />
v-model:modelKey="modelKey"
/>
<VipUse
v-if="pluginOptions.pluginId"
:plugin="pluginOptions.current"
/>
</template> </template>
<view class="scroll-view-content pb-[20rpx]" ref="contentRef"> <view class="scroll-view-content pb-[20rpx]" ref="contentRef">
<view <view v-for="(item, index) in chatList" :key="`${item.id} + ${index} + ''`"
v-for="(item, index) in chatList" style="transform: scaleY(-1)">
:key="`${item.id} + ${index} + ''`"
style="transform: scaleY(-1)"
>
<view class="chat-record mt-[20rpx] pb-[40rpx]"> <view class="chat-record mt-[20rpx] pb-[40rpx]">
<chat-record-item <chat-record-item :record-id="item.id" :type="item.type == 1 ? 'right' : 'left'"
:record-id="item.id" :content="item.content" :loading="item.loading" :audio="item.voiceFile" :index="index"
:type="item.type == 1 ? 'right' : 'left'"
:content="item.content"
:loading="item.loading"
:audio="item.voiceFile"
:index="index"
:time="item.type == 2 ? item.createTime : ''" :time="item.type == 2 ? item.createTime : ''"
:model-name="appStore.getChatConfig.show_model ? item.model : ''" :model-name="appStore.getChatConfig.show_model ? item.model : ''"
:is-collect="item.is_collect" :is-collect="item.is_collect" :avatar="avatar" :showRewriteBtn="index === 0"
:avatar="avatar" :showPosterBtn="true" :showCopyBtn="true" :file="{
:showRewriteBtn="index === 0"
:showPosterBtn="true"
:showCopyBtn="true"
:file="{
url: item.fileUrl, url: item.fileUrl,
name: item.fileName, name: item.fileName,
type: item.fileType type: item.fileType
}" }" @rewrite="rewrite(index)"
@rewrite="rewrite(index)"
@update="(e: any) => chatList[e.index].is_collect = e.value" @update="(e: any) => chatList[e.index].is_collect = e.value"
@click-poster="handleDrawPoster" @click-poster="handleDrawPoster">
>
</chat-record-item> </chat-record-item>
</view> </view>
</view> </view>
@ -73,52 +43,33 @@
<template #bottom> <template #bottom>
<view class="send-area"> <view class="send-area">
<view class="float-btn"> <view class="float-btn">
<view <view v-if="chatList.length && !isReceiving"
v-if="chatList.length && !isReceiving" class="px-[20rpx] py-[10rpx] text-xs flex items-center" @click="sendLock('继续')">
class="px-[20rpx] py-[10rpx] text-xs flex items-center"
@click="sendLock('继续')"
>
<u-icon name="play-circle" class="mr-[8rpx]" size="36" /> <u-icon name="play-circle" class="mr-[8rpx]" size="36" />
继续 继续
</view> </view>
<view <view v-if="isReceiving" class="px-[20rpx] py-[10rpx] text-xs flex items-center"
v-if="isReceiving" @click="chatClose()">
class="px-[20rpx] py-[10rpx] text-xs flex items-center"
@click="chatClose()"
>
<u-icon name="pause-circle" class="mr-[8rpx]" size="36" /> <u-icon name="pause-circle" class="mr-[8rpx]" size="36" />
停止 停止
</view> </view>
</view> </view>
<view class="mb-[20rpx]" v-if="isShowFileUpload"> <view class="mb-[20rpx]" v-if="isShowFileUpload">
<file-upload <file-upload v-model="pluginOptions.file" return-type="object"
v-model="pluginOptions.file" :file-type="pluginOptions.type" :file-extname="getFileExtname" :data="{
return-type="object"
:file-type="pluginOptions.type"
:file-extname="getFileExtname"
:data="{
type: type:
pluginOptions.type == 'file' pluginOptions.type == 'file'
? 'docs' ? 'docs'
: '', : '',
key: pluginOptions.type != 'image' ? pluginOptions.pluginId : '' key: pluginOptions.type != 'image' ? pluginOptions.pluginId : ''
}" }" />
/>
</view> </view>
<view class="mb-[20rpx] flex items-center"> <view class="mb-[20rpx] flex items-center">
<view class="flex items-center mr-auto"> <view class="flex items-center mr-auto">
<chat-plugins <chat-plugins v-if="type === 1" v-model="pluginOptions.pluginId"
v-if="type === 1" v-model:current="pluginOptions.current" @change="pluginChange">
v-model="pluginOptions.pluginId"
v-model:current="pluginOptions.current"
@change="pluginChange"
>
</chat-plugins> </chat-plugins>
<network-switch <network-switch v-if="!pluginOptions.pluginId" v-model="network"></network-switch>
v-if="!pluginOptions.pluginId"
v-model="network"
></network-switch>
</view> </view>
<view class="flex text-content items-center flex-none"> <view class="flex text-content items-center flex-none">
<view class="text-xs flex items-center" @click="cleanChatLock"> <view class="text-xs flex items-center" @click="cleanChatLock">
@ -127,56 +78,30 @@
</view> </view>
</view> </view>
</view> </view>
<view <view class="send-area__content bg-page-base"
class="send-area__content bg-page-base" :class="[safeAreaInsetBottom ? 'safe-area-inset-bottom' : '']">
:class="[safeAreaInsetBottom ? 'safe-area-inset-bottom' : '']"
>
<view class="flex-1 min-w-0 relative"> <view class="flex-1 min-w-0 relative">
<view <view v-if="showPressBtn"
v-if="showPressBtn"
class="absolute left-[-10rpx] top-[-15rpx] bottom-[-15rpx] bg-primary text-btn-text right-[0] z-[9999] flex items-center justify-center rounded-[12rpx]" class="absolute left-[-10rpx] top-[-15rpx] bottom-[-15rpx] bg-primary text-btn-text right-[0] z-[9999] flex items-center justify-center rounded-[12rpx]"
@longpress="handleLongpress" @longpress="handleLongpress" @touchend="touchEnd" @touchcancel="touchEnd">
@touchend="touchEnd"
@touchcancel="touchEnd"
>
按住说话 按住说话
</view> </view>
<u-input <u-input type="textarea" v-model="userInput" :placeholder="placeholder" maxlength="-1"
type="textarea" :auto-height="true" confirm-type="send" :adjust-position="false" :fixed="false"
v-model="userInput" adjust-keyboard-to="bottom" @click="handleClick" @focus="scrollToBottom" />
:placeholder="placeholder"
maxlength="-1"
:auto-height="true"
confirm-type="send"
:adjust-position="false"
:fixed="false"
adjust-keyboard-to="bottom"
@click="handleClick"
@focus="scrollToBottom"
/>
</view> </view>
<view class="ml-[20rpx] my-[-12rpx]"> <view class="ml-[20rpx] my-[-12rpx]">
<view v-if="userInput"> <view v-if="userInput">
<u-button <u-button type="primary" :custom-style="{
type="primary"
:custom-style="{
width: '100rpx', width: '100rpx',
height: '52rpx', height: '52rpx',
margin: '0' margin: '0'
}" }" size="mini" :disabled="isReceiving" @click.stop="sendLock()">
size="mini"
:disabled="isReceiving"
@click.stop="sendLock()"
>
发送 发送
</u-button> </u-button>
</view> </view>
<view v-else-if="appStore.getIsVoiceTransfer"> <view v-else-if="appStore.getIsVoiceTransfer">
<view <view v-if="showPressBtn" class="text-content" @click="triggerRecordShow">
v-if="showPressBtn"
class="text-content"
@click="triggerRecordShow"
>
<u-icon name="more-circle" :size="52" /> <u-icon name="more-circle" :size="52" />
</view> </view>
<view v-else class="text-content" @click="triggerRecordShow"> <view v-else class="text-content" @click="triggerRecordShow">
@ -190,24 +115,16 @@
<dragon-button :size="184" :yEdge="160"> <dragon-button :size="184" :yEdge="160">
<view class="p-[20rpx]" @click="triggerVoiceShow"> <view class="p-[20rpx]" @click="triggerVoiceShow">
<view class="flex justify-center mb-[-20rpx] relative z-[99]"> <view class="flex justify-center mb-[-20rpx] relative z-[99]">
<image <image class="w-[70rpx] h-[70rpx] mb-[10rpx]" :src="loadingPath" />
class="w-[70rpx] h-[70rpx] mb-[10rpx]"
:src="loadingPath"
/>
</view> </view>
<view> <view>
<u-button <u-button hover-class="none" :custom-style="{
hover-class="none"
:custom-style="{
width: '100%', width: '100%',
height: '58rpx', height: '58rpx',
fontSize: '24rpx', fontSize: '24rpx',
background: '#28C840', background: '#28C840',
'box-shadow': '0 3px 10px #00000033' 'box-shadow': '0 3px 10px #00000033'
}" }" type="primary" shape="circle">
type="primary"
shape="circle"
>
在线语音 在线语音
</u-button> </u-button>
</view> </view>
@ -220,26 +137,17 @@
<guided-popup ref="guidedPopupRef" /> <guided-popup ref="guidedPopupRef" />
<!--#ifdef APP-PLUS--> <!--#ifdef APP-PLUS-->
<appChat <appChat @onmessage="appOnmessage" @onclose="appOnclose" @onstart="appOnstart" ref="appChatRef"></appChat>
@onmessage="appOnmessage"
@onclose="appOnclose"
@onstart="appOnstart"
ref="appChatRef"
></appChat>
<!--#endif--> <!--#endif-->
<recorder ref="recorderRef" v-model:show="showRecorder" @success="sendLock" /> <recorder ref="recorderRef" v-model:show="showRecorder" @success="sendLock" />
</view> </view>
<online-voice <online-voice v-model:show="showOnlineVoice" :data="{
v-model:show="showOnlineVoice"
:data="{
chatKey: chatKey, chatKey: chatKey,
modelKey: modelKey, modelKey: modelKey,
type: type, type: type,
categoryId: otherId, categoryId: otherId,
network: network network: network
}" }" @update="pagingRef?.reload()" />
@update="pagingRef?.reload()"
/>
<!-- 生产对话海报 --> <!-- 生产对话海报 -->
<dialog-poster ref="posterRef"></dialog-poster> <dialog-poster ref="posterRef"></dialog-poster>
@ -753,7 +661,7 @@ const appOnmessage = (value: any) => {
chatContent.value.loading = false chatContent.value.loading = false
return return
} }
} catch (error) {} } catch (error) { }
} }
}) })
} }
@ -813,6 +721,7 @@ defineExpose({
position: relative; position: relative;
padding: 20rpx 30rpx; padding: 20rpx 30rpx;
background-color: #fff; background-color: #fff;
.float-btn { .float-btn {
position: absolute; position: absolute;
left: 50%; left: 50%;
@ -823,6 +732,7 @@ defineExpose({
border-radius: 20rpx; border-radius: 20rpx;
@apply bg-white border-light; @apply bg-white border-light;
} }
&__content { &__content {
border-radius: 16rpx; border-radius: 16rpx;
padding: 25rpx 20rpx; padding: 25rpx 20rpx;
@ -841,12 +751,14 @@ defineExpose({
box-sizing: border-box; box-sizing: border-box;
padding: 0; padding: 0;
line-height: var(--line-height); line-height: var(--line-height);
.uni-textarea-textarea { .uni-textarea-textarea {
max-height: calc(var(--line-height) * var(--line-num)); max-height: calc(var(--line-height) * var(--line-num));
overflow-y: auto !important; overflow-y: auto !important;
} }
} }
} }
.send-btn { .send-btn {
width: 100%; width: 100%;
position: absolute; position: absolute;
@ -858,6 +770,7 @@ defineExpose({
} }
} }
} }
.chat-bubble { .chat-bubble {
width: 70rpx; width: 70rpx;
height: 70rpx; height: 70rpx;

View File

@ -4,25 +4,15 @@
<view class="p-[28rpx] text-center font-medium text-xl"> 对话余额不足 </view> <view class="p-[28rpx] text-center font-medium text-xl"> 对话余额不足 </view>
<view class="border-t border-solid border-light border-0 px-[40rpx] py-[30rpx]"> <view class="border-t border-solid border-light border-0 px-[40rpx] py-[30rpx]">
<view>你可以通过以下渠道获取对话条数</view> <view>你可以通过以下渠道获取对话条数</view>
<view <view class="mt-[40rpx] flex items-center" v-for="(item, index) in channelList" :key="index">
class="mt-[40rpx] flex items-center"
v-for="(item, index) in channelList"
:key="index"
>
<view class="mr-[20rpx] font-medium"> <view class="mr-[20rpx] font-medium">
{{ item.title }} {{ item.title }}
</view> </view>
<view class="ml-auto"> <view class="ml-auto">
<u-button <u-button type="primary" shape="circle" size="medium" :customStyle="{
type="primary"
shape="circle"
size="medium"
:customStyle="{
padding: '0 24rpx', padding: '0 24rpx',
height: '56rpx' height: '56rpx'
}" }" @click="jump(item.path)">
@click="jump(item.path)"
>
{{ item.btnText }} {{ item.btnText }}
</u-button> </u-button>
</view> </view>

View File

@ -1,11 +1,9 @@
<template> <template>
<view <view v-if="userStore.isLogin && !chatModel.loading"
v-if="userStore.isLogin && !chatModel.loading" class="px-[20rpx] py-[15rpx] text-sm flex items-center justify-between bg-white">
class="px-[20rpx] py-[15rpx] text-sm flex items-center justify-between bg-white"
>
<view class="flex-none mr-[20rpx]"> <view class="flex-none mr-[20rpx]">
<view class="flex items-center"> <view class="flex items-center">
<u-button <!-- <u-button
type="primary" type="primary"
plain plain
size="medium" size="medium"
@ -21,12 +19,9 @@
: '开通会员' : '开通会员'
}} }}
</router-navigate> </router-navigate>
</u-button> </u-button> -->
<view class="ml-[20rpx]" v-if="!chatModel.modelList.length"> <view class="ml-[20rpx]" v-if="!chatModel.modelList.length">
<text <text v-if="userInfo.isMember && userInfo.memberExpired !== 1" class="flex-1 min-w-0">
v-if="userInfo.isMember && userInfo.memberExpired !== 1"
class="flex-1 min-w-0"
>
已开通会员不消耗次数 已开通会员不消耗次数
</text> </text>
<text v-else> <text v-else>
@ -37,22 +32,16 @@
</view> </view>
</view> </view>
</view> </view>
<view <view v-if="chatModel.billing_is_open * 1" @click="chatModel.show = true"
v-if="chatModel.billing_is_open * 1" class="flex ml-auto justify-center items-center rounded-[30px] h-[60rpx]">
@click="chatModel.show = true"
class="flex ml-auto justify-center items-center rounded-[30px] h-[60rpx]"
>
<text class="text-[#415058] mr-[6px] flex"> <text class="text-[#415058] mr-[6px] flex">
<text class="line-clamp-1"> <text class="line-clamp-1">
{{ chatModel.current.alias }} / {{ chatModel.current.alias }} /
<text <text v-if="
v-if="
chatModel?.current?.member_free && chatModel?.current?.member_free &&
chatModel?.current?.is_member chatModel?.current?.is_member
" " class="text-muted">
class="text-muted"
>
会员免费 会员免费
</text> </text>
<text v-else class="flex-1 min-w-0 text-muted"> <text v-else class="flex-1 min-w-0 text-muted">
@ -80,26 +69,14 @@
<template v-else> 免费 </template> <template v-else> 免费 </template>
</view> </view>
</view> </view>
<u-popup <u-popup v-model="chatModel.show" mode="bottom" border-radius="14" :safe-area-inset-bottom="true" height="980rpx"
v-model="chatModel.show" closeable>
mode="bottom"
border-radius="14"
:safe-area-inset-bottom="true"
height="980rpx"
closeable
>
<view class="p-[20rpx] text-xl font-bold"> 切换模型通道 </view> <view class="p-[20rpx] text-xl font-bold"> 切换模型通道 </view>
<scroll-view class="h-[890rpx] box-border" scroll-y> <scroll-view class="h-[890rpx] box-border" scroll-y>
<view class="pb-[200rpx] px-[30rpx]"> <view class="pb-[200rpx] px-[30rpx]">
<view <view class="model-card" v-for="(item, index) in chatModel.modelList" :key="item.key" :class="{
class="model-card"
v-for="(item, index) in chatModel.modelList"
:key="item.key"
:class="{
'model-card__active': chatModel.currentIndex === index 'model-card__active': chatModel.currentIndex === index
}" }" @click="chatModel.currentIndex = index">
@click="chatModel.currentIndex = index"
>
<view> <view>
<view class="flex items-center"> <view class="flex items-center">
<view class="mr-2" v-if="item.image"> <view class="mr-2" v-if="item.image">
@ -112,28 +89,19 @@
</view> </view>
</view> </view>
<view class="mt-4"> <view class="mt-4">
<view <view class="mt-[20rpx] min-h-[50rpx] flex items-center justify-between"
class="mt-[20rpx] min-h-[50rpx] flex items-center justify-between" v-for="citem in item.model_list" :key="citem.key" @click="handleChoiceModel(citem)">
v-for="citem in item.model_list"
:key="citem.key"
@click="handleChoiceModel(citem)"
>
<view class="mr-[6px] flex-1 min-w-0"> <view class="mr-[6px] flex-1 min-w-0">
{{ citem.alias }} {{ citem.alias }}
</view> </view>
<view class="ml-[10rpx] flex items-center"> <view class="ml-[10rpx] flex items-center">
<view <view class="text-muted mr-2" :class="{
class="text-muted mr-2"
:class="{
'!text-primary': modelKey === citem.key && chatModel.currentIndex === index '!text-primary': modelKey === citem.key && chatModel.currentIndex === index
}" }">
> <text v-if="
<text
v-if="
citem.member_free && citem.member_free &&
citem.is_member citem.is_member
" ">
>
会员免费 会员免费
</text> </text>
<text v-else> <text v-else>
@ -147,20 +115,12 @@
<template v-else> 免费 </template> <template v-else> 免费 </template>
</text> </text>
</view> </view>
<view <view class="text-muted ml-1 mr-[2px]"
class="text-muted ml-1 mr-[2px]" v-if="modelKey !== citem.key || chatModel.currentIndex !== index">
v-if="modelKey !== citem.key || chatModel.currentIndex !== index" <u-image :src="IconUnSelect" width="32rpx" height="32rpx"></u-image>
>
<u-image
:src="IconUnSelect"
width="32rpx"
height="32rpx"
></u-image>
</view> </view>
<view <view class="text-primary mt-[3px]"
class="text-primary mt-[3px]" v-if="modelKey === citem.key && chatModel.currentIndex === index">
v-if="modelKey === citem.key && chatModel.currentIndex === index"
>
<u-icon name="checkmark-circle-fill" size="40rpx"></u-icon> <u-icon name="checkmark-circle-fill" size="40rpx"></u-icon>
</view> </view>
</view> </view>

View File

@ -1,12 +1,6 @@
<template> <template>
<u-tabbar <u-tabbar v-if="showTabbar" v-model="current" v-bind="tabbarStyle" :list="tabbarList" @change="handleChange"
v-if="showTabbar" :hide-tab-bar="true"></u-tabbar>
v-model="current"
v-bind="tabbarStyle"
:list="tabbarList"
@change="handleChange"
:hide-tab-bar="true"
></u-tabbar>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>

View File

@ -18,19 +18,13 @@
</view> </view>
</view> </view>
<view class="flex flex-col justify-center" v-if="isLogin"> <view class="flex flex-col justify-center" v-if="isLogin">
<u-button <u-button v-if="appStore.getIsShowVip && !user.memberPerpetual" shape="circle" size="medium"
v-if="appStore.getIsShowVip && !user.memberPerpetual"
shape="circle"
size="medium"
:customStyle="{ :customStyle="{
padding: '0 24rpx', padding: '0 24rpx',
height: '56rpx', height: '56rpx',
background: '#333333', background: '#333333',
color: '#F8C596' color: '#F8C596'
}" }" hover-class="none" @click="navigateTo('/packages/pages/open_vip/open_vip')">
hover-class="none"
@click="navigateTo('/packages/pages/open_vip/open_vip')"
>
{{ user.isMember ? '立即续费' : content.btn }} {{ user.isMember ? '立即续费' : content.btn }}
</u-button> </u-button>
</view> </view>

View File

@ -1,35 +1,35 @@
{ {
"name" : "码多多AI", "name": "信广龙AI",
"appid" : "__UNI__2A068A4", "appid": "__UNI__2A068A4",
"description" : "", "description": "",
"versionName" : "3.2.1", "versionName": "3.2.1",
"versionCode" : 201, "versionCode": 201,
"transformPx" : false, "transformPx": false,
/* 5+App */ /* 5+App */
"app-plus" : { "app-plus": {
"compatible" : { "compatible": {
"ignoreVersion" : true //trueHBuilderX1.9.0 "ignoreVersion": true //trueHBuilderX1.9.0
}, },
"usingComponents" : true, "usingComponents": true,
"nvueStyleCompiler" : "uni-app", "nvueStyleCompiler": "uni-app",
"compilerVersion" : 3, "compilerVersion": 3,
"splashscreen" : { "splashscreen": {
"alwaysShowBeforeRender" : true, "alwaysShowBeforeRender": true,
"waiting" : true, "waiting": true,
"autoclose" : true, "autoclose": true,
"delay" : 0 "delay": 0
}, },
/* */ /* */
"modules" : { "modules": {
"Payment" : {}, "Payment": {},
"OAuth" : {}, "OAuth": {},
"Share" : {} "Share": {}
}, },
/* */ /* */
"distribute" : { "distribute": {
/* android */ /* android */
"android" : { "android": {
"permissions" : [ "permissions": [
"<uses-feature android:name=\"android.hardware.camera\"/>", "<uses-feature android:name=\"android.hardware.camera\"/>",
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>", "<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_COARSE_LOCATION\"/>", "<uses-permission android:name=\"android.permission.ACCESS_COARSE_LOCATION\"/>",
@ -50,123 +50,133 @@
"<uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\"/>", "<uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\"/>",
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>" "<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
], ],
"abiFilters" : [ "armeabi-v7a", "arm64-v8a", "x86" ] "abiFilters": [
"armeabi-v7a",
"arm64-v8a",
"x86"
]
}, },
/* ios */ /* ios */
"ios" : { "ios": {
"dSYMs" : false, "dSYMs": false,
"privacyDescription" : { "privacyDescription": {
"NSCameraUsageDescription" : "您可以拍照设置头像、拍照上传图片", "NSCameraUsageDescription": "您可以拍照设置头像、拍照上传图片",
"NSPhotoLibraryAddUsageDescription" : "您可以设置头像、保存图片到相册,还可以上传图片", "NSPhotoLibraryAddUsageDescription": "您可以设置头像、保存图片到相册,还可以上传图片",
"NSPhotoLibraryUsageDescription" : "您可以设置头像、保存图片到相册,还可以上传图片", "NSPhotoLibraryUsageDescription": "您可以设置头像、保存图片到相册,还可以上传图片",
"NSUserTrackingUsageDescription" : "根据您的习惯为您推荐" "NSUserTrackingUsageDescription": "根据您的习惯为您推荐"
}, },
"capabilities" : { "capabilities": {
"entitlements" : { "entitlements": {
"com.apple.developer.associated-domains" : [ "com.apple.developer.associated-domains": [
"applinks:static-mp-62a38312-a6b8-4502-9a4c-9bb095d26ddd.next.bspapp.com" "applinks:static-mp-62a38312-a6b8-4502-9a4c-9bb095d26ddd.next.bspapp.com"
] ]
} }
} }
}, },
/* SDK */ /* SDK */
"sdkConfigs" : { "sdkConfigs": {
"payment" : { "payment": {
"weixin" : { "weixin": {
"__platform__" : [ "ios", "android" ], "__platform__": [
"appid" : "wxee7d4a85331633e4", "ios",
"UniversalLinks" : "https://static-mp-62a38312-a6b8-4502-9a4c-9bb095d26ddd.next.bspapp.com/uni-universallinks/__UNI__1FC79BE/" "android"
],
"appid": "wxee7d4a85331633e4",
"UniversalLinks": "https://static-mp-62a38312-a6b8-4502-9a4c-9bb095d26ddd.next.bspapp.com/uni-universallinks/__UNI__1FC79BE/"
}, },
"alipay" : { "alipay": {
"__platform__" : [ "ios", "android" ] "__platform__": [
"ios",
"android"
]
} }
}, },
"ad" : {}, "ad": {},
"oauth" : { "oauth": {
"weixin" : { "weixin": {
"appid" : "wxee7d4a85331633e4", "appid": "wxee7d4a85331633e4",
"UniversalLinks" : "https://static-mp-62a38312-a6b8-4502-9a4c-9bb095d26ddd.next.bspapp.com/uni-universallinks/__UNI__1FC79BE/" "UniversalLinks": "https://static-mp-62a38312-a6b8-4502-9a4c-9bb095d26ddd.next.bspapp.com/uni-universallinks/__UNI__1FC79BE/"
} }
}, },
"share" : { "share": {
"weixin" : { "weixin": {
"appid" : "wxee7d4a85331633e4", "appid": "wxee7d4a85331633e4",
"UniversalLinks" : "https://static-mp-62a38312-a6b8-4502-9a4c-9bb095d26ddd.next.bspapp.com/uni-universallinks/__UNI__1FC79BE/" "UniversalLinks": "https://static-mp-62a38312-a6b8-4502-9a4c-9bb095d26ddd.next.bspapp.com/uni-universallinks/__UNI__1FC79BE/"
} }
} }
}, },
"icons" : { "icons": {
"android" : { "android": {
"hdpi" : "unpackage/res/icons/72x72.png", "hdpi": "unpackage/res/icons/72x72.png",
"xhdpi" : "unpackage/res/icons/96x96.png", "xhdpi": "unpackage/res/icons/96x96.png",
"xxhdpi" : "unpackage/res/icons/144x144.png", "xxhdpi": "unpackage/res/icons/144x144.png",
"xxxhdpi" : "unpackage/res/icons/192x192.png" "xxxhdpi": "unpackage/res/icons/192x192.png"
}, },
"ios" : { "ios": {
"appstore" : "unpackage/res/icons/1024x1024.png", "appstore": "unpackage/res/icons/1024x1024.png",
"ipad" : { "ipad": {
"app" : "unpackage/res/icons/76x76.png", "app": "unpackage/res/icons/76x76.png",
"app@2x" : "unpackage/res/icons/152x152.png", "app@2x": "unpackage/res/icons/152x152.png",
"notification" : "unpackage/res/icons/20x20.png", "notification": "unpackage/res/icons/20x20.png",
"notification@2x" : "unpackage/res/icons/40x40.png", "notification@2x": "unpackage/res/icons/40x40.png",
"proapp@2x" : "unpackage/res/icons/167x167.png", "proapp@2x": "unpackage/res/icons/167x167.png",
"settings" : "unpackage/res/icons/29x29.png", "settings": "unpackage/res/icons/29x29.png",
"settings@2x" : "unpackage/res/icons/58x58.png", "settings@2x": "unpackage/res/icons/58x58.png",
"spotlight" : "unpackage/res/icons/40x40.png", "spotlight": "unpackage/res/icons/40x40.png",
"spotlight@2x" : "unpackage/res/icons/80x80.png" "spotlight@2x": "unpackage/res/icons/80x80.png"
}, },
"iphone" : { "iphone": {
"app@2x" : "unpackage/res/icons/120x120.png", "app@2x": "unpackage/res/icons/120x120.png",
"app@3x" : "unpackage/res/icons/180x180.png", "app@3x": "unpackage/res/icons/180x180.png",
"notification@2x" : "unpackage/res/icons/40x40.png", "notification@2x": "unpackage/res/icons/40x40.png",
"notification@3x" : "unpackage/res/icons/60x60.png", "notification@3x": "unpackage/res/icons/60x60.png",
"settings@2x" : "unpackage/res/icons/58x58.png", "settings@2x": "unpackage/res/icons/58x58.png",
"settings@3x" : "unpackage/res/icons/87x87.png", "settings@3x": "unpackage/res/icons/87x87.png",
"spotlight@2x" : "unpackage/res/icons/80x80.png", "spotlight@2x": "unpackage/res/icons/80x80.png",
"spotlight@3x" : "unpackage/res/icons/120x120.png" "spotlight@3x": "unpackage/res/icons/120x120.png"
} }
} }
}, },
"splashscreen" : { "splashscreen": {
"useOriginalMsgbox" : true "useOriginalMsgbox": true
} }
} }
}, },
/* */ /* */
"quickapp" : {}, "quickapp": {},
/* */ /* */
"mp-weixin" : { "mp-weixin": {
"appid" : "wx386a75e518b38935", "appid": "wx386a75e518b38935",
"optimization" : { "optimization": {
"subPackages" : true "subPackages": true
}, },
"setting" : { "setting": {
"urlCheck" : false, "urlCheck": false,
"es6" : true, "es6": true,
"minified" : true "minified": true
}, },
"__usePrivacyCheck__" : true, "__usePrivacyCheck__": true,
"usingComponents" : true "usingComponents": true
}, },
"mp-alipay" : { "mp-alipay": {
"usingComponents" : true "usingComponents": true
}, },
"mp-baidu" : { "mp-baidu": {
"usingComponents" : true "usingComponents": true
}, },
"mp-toutiao" : { "mp-toutiao": {
"usingComponents" : true "usingComponents": true
}, },
"uniStatistics" : { "uniStatistics": {
"enable" : false "enable": false
}, },
"vueVersion" : "3", "vueVersion": "3",
"h5" : { "h5": {
"router" : { "router": {
"mode" : "history", "mode": "history",
"base" : "/mobile/" "base": "/"
}, },
"title" : "加载中" "title": "加载中"
}, },
"_spaceID" : "mp-62a38312-a6b8-4502-9a4c-9bb095d26ddd" "_spaceID": "mp-62a38312-a6b8-4502-9a4c-9bb095d26ddd"
} }

View File

@ -1,83 +1,41 @@
<template> <template>
<view <view class="register bg-white min-h-full flex flex-col items-center px-[40rpx] pt-[100rpx] box-border">
class="register bg-white min-h-full flex flex-col items-center px-[40rpx] pt-[100rpx] box-border"
>
<view class="w-full"> <view class="w-full">
<view class="text-2xl font-medium mb-[60rpx]">忘记登录密码</view> <view class="text-2xl font-medium mb-[60rpx]">忘记登录密码</view>
<u-tabs <u-tabs :list="forgetWayListsFilter" :is-scroll="false" v-model="currentTabs"
:list="forgetWayListsFilter" :active-color="$theme.primaryColor" @change="
:is-scroll="false"
v-model="currentTabs"
:active-color="$theme.primaryColor"
@change="
(index) => { (index) => {
currentTabs = index currentTabs = index
formData.scene = forgetWayLists[index].type formData.scene = forgetWayLists[index].type
} }
" "></u-tabs>
></u-tabs>
<u-form borderBottom :label-width="150"> <u-form borderBottom :label-width="150">
<u-form-item label="手机号" borderBottom v-show="isMobile"> <u-form-item label="手机号" borderBottom v-show="isMobile">
<u-input <u-input class="flex-1" v-model="formData.mobile" :border="false" placeholder="请输入手机号码" />
class="flex-1"
v-model="formData.mobile"
:border="false"
placeholder="请输入手机号码"
/>
</u-form-item> </u-form-item>
<u-form-item label="邮箱" borderBottom v-show="isMailbox"> <u-form-item label="邮箱" borderBottom>
<u-input <u-input class="flex-1" v-model="formData.email" :border="false" placeholder="请输入邮箱账号" />
class="flex-1"
v-model="formData.email"
:border="false"
placeholder="请输入邮箱账号"
/>
</u-form-item> </u-form-item>
<u-form-item label="验证码" borderBottom> <u-form-item label="验证码" borderBottom>
<u-input <u-input class="flex-1" v-model="formData.code" placeholder="请输入验证码" :border="false" />
class="flex-1" <view class="border-l border-solid border-0 border-light pl-3 text-muted leading-4 ml-3 w-[180rpx]"
v-model="formData.code" @click="sendCode">
placeholder="请输入验证码" <u-verification-code ref="uCodeRef" :seconds="60" @change="codeChange" change-text="x秒" />
:border="false" <text class="text-muted" :class="{
/>
<view
class="border-l border-solid border-0 border-light pl-3 text-muted leading-4 ml-3 w-[180rpx]"
@click="sendCode"
>
<u-verification-code
ref="uCodeRef"
:seconds="60"
@change="codeChange"
change-text="x秒"
/>
<text
class="text-muted"
:class="{
'text-primary': 'text-primary':
(isValidMobile && isMobile) || (isValidMailBox && isMailbox) (isValidMobile && isMobile) || (isValidMailBox && isMailbox)
}" }">
>
{{ codeTips }} {{ codeTips }}
</text> </text>
</view> </view>
</u-form-item> </u-form-item>
<u-form-item label="新密码" borderBottom> <u-form-item label="新密码" borderBottom>
<u-input <u-input class="flex-1" type="password" v-model="formData.password" placeholder="6-20位数字+字母或符号组合"
class="flex-1" :border="false" />
type="password"
v-model="formData.password"
placeholder="6-20位数字+字母或符号组合"
:border="false"
/>
</u-form-item> </u-form-item>
<u-form-item label="确认密码" borderBottom> <u-form-item label="确认密码" borderBottom>
<u-input <u-input class="flex-1" type="password" v-model="formData.password2" placeholder="再次输入新密码"
class="flex-1" :border="false" />
type="password"
v-model="formData.password2"
placeholder="再次输入新密码"
:border="false"
/>
</u-form-item> </u-form-item>
</u-form> </u-form>
<view class="mt-[100rpx]"> <view class="mt-[100rpx]">
@ -133,7 +91,7 @@ const formData = reactive({
mobile: '', mobile: '',
email: '', email: '',
code: '', code: '',
scene: 2, scene: 3,
password: '', password: '',
password2: '' password2: ''
}) })
@ -142,6 +100,7 @@ const isValidMobile = computed(() => uni.$u.test.mobile(formData.mobile))
const isValidMailBox = computed(() => uni.$u.test.email(formData.email)) const isValidMailBox = computed(() => uni.$u.test.email(formData.email))
const isMobile = computed(() => formData.scene == ForgotPwdSceneEnum.MOBILE) const isMobile = computed(() => formData.scene == ForgotPwdSceneEnum.MOBILE)
const isMailbox = computed(() => formData.scene == ForgotPwdSceneEnum.MAILBOX) const isMailbox = computed(() => formData.scene == ForgotPwdSceneEnum.MAILBOX)
console.log('isMailbox', isMailbox.value);
const codeChange = (text: string) => { const codeChange = (text: string) => {
codeTips.value = text codeTips.value = text

View File

@ -4,48 +4,21 @@
<view class="container"> <view class="container">
<view class="header flex flex-col"> <view class="header flex flex-col">
<!-- #ifndef H5 --> <!-- #ifndef H5 -->
<u-sticky <!-- <u-sticky h5-nav-height="0" bg-color="transparent" @fixed="isFixed = true" @unfixed="isFixed = false">
h5-nav-height="0" <u-navbar :is-fixed="false" title="开通会员" :back-icon-color="getNavColor" :title-color="getNavColor"
bg-color="transparent" :background="{ backgroundColor: getNavBg }" :border-bottom="false" :title-bold="true"
@fixed="isFixed = true" :customBack="goBack">
@unfixed="isFixed = false"
>
<u-navbar
:is-fixed="false"
title="开通会员"
:back-icon-color="getNavColor"
:title-color="getNavColor"
:background="{ backgroundColor: getNavBg }"
:border-bottom="false"
:title-bold="true"
:customBack="goBack"
>
</u-navbar> </u-navbar>
</u-sticky> </u-sticky> -->
<!-- #endif --> <!-- #endif -->
<view <view v-if="vipTop && vipTop?.content?.enabled && memberBuyLog.length" class="px-[30rpx] text-white"
v-if="vipTop && vipTop?.content?.enabled && memberBuyLog.length" style="background-color: rgba(255, 239, 230, 0.1)">
class="px-[30rpx] text-white" <swiper class="h-[70rpx]" circular :autoplay="true" :interval="3000" :vertical="true">
style="background-color: rgba(255, 239, 230, 0.1)"
>
<swiper
class="h-[70rpx]"
circular
:autoplay="true"
:interval="3000"
:vertical="true"
>
<swiper-item v-for="(item, index) in memberBuyLog" :key="index"> <swiper-item v-for="(item, index) in memberBuyLog" :key="index">
<view class="flex items-center h-full"> <view class="flex items-center h-full">
<view class="flex-none"> <view class="flex-none">
<u-image <u-image width="48" height="48" :src="item.avatar" alt="" border-radius="50%" />
width="48"
height="48"
:src="item.avatar"
alt=""
border-radius="50%"
/>
</view> </view>
<view class="ml-[20rpx] line-clamp-1 text-sm"> <view class="ml-[20rpx] line-clamp-1 text-sm">
@ -64,11 +37,7 @@
</view> </view>
</view> </view>
<view class="flex-none"> <view class="flex-none">
<image <image class="w-[120rpx] h-[120rpx]" src="@/static/images/user/user_vip.png" alt="" />
class="w-[120rpx] h-[120rpx]"
src="@/static/images/user/user_vip.png"
alt=""
/>
</view> </view>
</view> </view>
</view> </view>
@ -79,89 +48,56 @@
<view class="min-h-[300rpx]"> <view class="min-h-[300rpx]">
<scroll-view class="h-full" scroll-x="true" enable-flex> <scroll-view class="h-full" scroll-x="true" enable-flex>
<view class="p-[15rpx] inline-flex"> <view class="p-[15rpx] inline-flex">
<view <view class="w-[230rpx] bg-[white] m-[15rpx] rounded-lg package-item relative"
class="w-[230rpx] bg-[white] m-[15rpx] rounded-lg package-item relative" :class="{ active: currentPackage.id == item.id }" v-for="item in packageList"
:class="{ active: currentPackage.id == item.id }" :key="item.id" @click="selectPackage(item)">
v-for="item in packageList"
:key="item.id"
@click="selectPackage(item)"
>
<view <view
class="absolute container-charge text-[24rpx] text-white bg-[#FF4747] py-[4rpx] px-[8rpx] line-clamp-1" class="absolute container-charge text-[24rpx] text-white bg-[#FF4747] py-[4rpx] px-[8rpx] line-clamp-1"
v-if="item.tag" v-if="item.tag">
>
{{ item.tag }} {{ item.tag }}
</view> </view>
<view <view
class="flex flex-col justify-around items-center py-[20rpx] text-center px-[20rpx]" class="flex flex-col justify-around items-center py-[20rpx] text-center px-[20rpx]">
>
<view class="text-[28rpx]">{{ item.name }}</view> <view class="text-[28rpx]">{{ item.name }}</view>
<view> <view>
<price <price :content="item.sellPrice" mainSize="60rpx" minorSize="26rpx"
:content="item.sellPrice" fontWeight="500" color="#101010"></price>
mainSize="60rpx"
minorSize="26rpx"
fontWeight="500"
color="#101010"
></price>
</view> </view>
<view v-if="item.linePrice > 0"> <view v-if="item.linePrice > 0">
<price <price :content="item.linePrice" mainSize="24rpx" minorSize="24rpx" color="#999"
:content="item.linePrice" lineThrough></price>
mainSize="24rpx"
minorSize="24rpx"
color="#999"
lineThrough
></price>
</view> </view>
</view> </view>
</view> </view>
</view> </view>
</scroll-view> </scroll-view>
</view> </view>
<view <view class="mx-[20rpx] p-[30rpx] bg-white rounded-lg flex items-center mb-[20rpx]"
class="mx-[20rpx] p-[30rpx] bg-white rounded-lg flex items-center mb-[20rpx]" v-if="currentPackage.giveNumber > 0 || currentPackage.giveDrawNumber > 0">
v-if="currentPackage.giveNumber > 0 || currentPackage.giveDrawNumber > 0"
>
<view>额外赠送</view> <view>额外赠送</view>
<view class="flex ml-[20rpx]"> <view class="flex ml-[20rpx]">
<view <view v-if="currentPackage.giveNumber > 0"
v-if="currentPackage.giveNumber > 0" class="text-sm flex bg-[#FDF7E9] text-[#E4A71C] px-[10rpx] py-[2rpx] rounded-sm mr-[20rpx]">
class="text-sm flex bg-[#FDF7E9] text-[#E4A71C] px-[10rpx] py-[2rpx] rounded-sm mr-[20rpx]"
>
对话条数{{ currentPackage.giveNumber }} 对话条数{{ currentPackage.giveNumber }}
</view> </view>
<view <view v-if="currentPackage.giveDrawNumber > 0"
v-if="currentPackage.giveDrawNumber > 0" class="text-sm flex bg-[#FDF7E9] text-[#E4A71C] px-[10rpx] py-[2px] rounded-sm mr-[20rpx]">
class="text-sm flex bg-[#FDF7E9] text-[#E4A71C] px-[10rpx] py-[2px] rounded-sm mr-[20rpx]"
>
绘画条数{{ currentPackage.giveDrawNumber }} 绘画条数{{ currentPackage.giveDrawNumber }}
</view> </view>
</view> </view>
</view> </view>
<view <view v-if="priceState.discount > 0"
v-if="priceState.discount > 0" class="mx-[20rpx] p-[30rpx] bg-white rounded-lg flex justify-between mb-[20rpx]">
class="mx-[20rpx] p-[30rpx] bg-white rounded-lg flex justify-between mb-[20rpx]"
>
<view>优惠金额</view> <view>优惠金额</view>
<price <price prefix="-¥" :content="priceState.discount" mainSize="28rpx" minorSize="28rpx"
prefix="-¥" color="#FF2C3C"></price>
:content="priceState.discount"
mainSize="28rpx"
minorSize="28rpx"
color="#FF2C3C"
></price>
</view> </view>
<view class="mx-[20rpx] p-[30rpx] bg-white rounded-lg"> <view class="mx-[20rpx] p-[30rpx] bg-white rounded-lg">
<view class="text-[30rpx] font-medium">支付方式</view> <view class="text-[30rpx] font-medium">支付方式</view>
<view class="payway-lists pt-[10rpx]"> <view class="payway-lists pt-[10rpx]">
<u-radio-group v-model="payWay" class="w-full" active-color="#FF4747"> <u-radio-group v-model="payWay" class="w-full" active-color="#FF4747">
<view <view class="py-[20rpx] flex items-center w-full payway-item"
class="py-[20rpx] flex items-center w-full payway-item" v-for="(item, index) in payWayData" :key="index" @click="payWay = item.id">
v-for="(item, index) in payWayData"
:key="index"
@click="payWay = item.id"
>
<u-icon class="flex-none" :size="48" :name="item.icon"></u-icon> <u-icon class="flex-none" :size="48" :name="item.icon"></u-icon>
<view class="mx-[16rpx] flex-1"> <view class="mx-[16rpx] flex-1">
<view class="payway-item--name flex-1"> <view class="payway-item--name flex-1">
@ -175,38 +111,25 @@
</u-radio-group> </u-radio-group>
</view> </view>
</view> </view>
<view <view v-if="
v-if="
vipAdvantage && vipAdvantage &&
vipAdvantage?.content?.enabled == 1 && vipAdvantage?.content?.enabled == 1 &&
currentBenefits.length currentBenefits.length
" " class="mx-[20rpx] bg-white rounded-lg mt-[20rpx]">
class="mx-[20rpx] bg-white rounded-lg mt-[20rpx]"
>
<view class="text-[30rpx] font-medium p-[30rpx]"> <view class="text-[30rpx] font-medium p-[30rpx]">
{{ vipAdvantage?.content?.name }} {{ vipAdvantage?.content?.name }}
</view> </view>
<view class="flex flex-wrap mt-[10rpx]"> <view class="flex flex-wrap mt-[10rpx]">
<view <view class="w-1/3 flex flex-col items-center mb-[40rpx]"
class="w-1/3 flex flex-col items-center mb-[40rpx]" v-for="(item, index) in currentBenefits" :key="index">
v-for="(item, index) in currentBenefits" <u-image width="96" height="96" :src="appStore.getImageUrl(item.image)" alt="" />
:key="index"
>
<u-image
width="96"
height="96"
:src="appStore.getImageUrl(item.image)"
alt=""
/>
<view class="pt-[10rpx]">{{ item.name }}</view> <view class="pt-[10rpx]">{{ item.name }}</view>
<view class="text-sm text-muted">{{ item.describe }}</view> <view class="text-sm text-muted">{{ item.describe }}</view>
</view> </view>
</view> </view>
</view> </view>
<view <view v-if="vipNotice && vipNotice.content.enabled == 1"
v-if="vipNotice && vipNotice.content.enabled == 1" class="mx-[20rpx] p-[30rpx] bg-white rounded-lg mt-[20rpx]">
class="mx-[20rpx] p-[30rpx] bg-white rounded-lg mt-[20rpx]"
>
<text class="text-[30rpx] font-medium">{{ vipNotice.content.name }}</text> <text class="text-[30rpx] font-medium">{{ vipNotice.content.name }}</text>
<view class="py-[20rpx]"> <view class="py-[20rpx]">
请您仔细阅读以下说明内容用户购买会员权益即视为您已阅读并同意说明内容 请您仔细阅读以下说明内容用户购买会员权益即视为您已阅读并同意说明内容
@ -215,21 +138,13 @@
{{ vipNotice.content.data }} {{ vipNotice.content.data }}
</view> </view>
</view> </view>
<view <view v-if="vipEvaluate && vipEvaluate.content.enabled == 1"
v-if="vipEvaluate && vipEvaluate.content.enabled == 1" class="mx-[20rpx] p-[30rpx] bg-white rounded-lg mt-[20rpx]">
class="mx-[20rpx] p-[30rpx] bg-white rounded-lg mt-[20rpx]"
>
<text class="text-[30rpx] font-medium">用户评价</text> <text class="text-[30rpx] font-medium">用户评价</text>
<template v-for="item in commentLists" :key="item.id"> <template v-for="item in commentLists" :key="item.id">
<view class="flex mt-[40rpx]"> <view class="flex mt-[40rpx]">
<view class="flex flex-1"> <view class="flex flex-1">
<u-image <u-image width="64" height="64" :src="item.image" alt="" border-radius="50%" />
width="64"
height="64"
:src="item.image"
alt=""
border-radius="50%"
/>
<view class="ml-[20rpx]"> <view class="ml-[20rpx]">
<view class="font-medium line-clamp-1">{{ item.name }}</view> <view class="font-medium line-clamp-1">{{ item.name }}</view>
<view class="text-[24rpx] text-[#999999]"> <view class="text-[24rpx] text-[#999999]">
@ -238,12 +153,7 @@
</view> </view>
</view> </view>
<view class="flex-none"> <view class="flex-none">
<u-rate <u-rate v-model="item.commentLevel" disabled size="28" active-color="#FABB19"></u-rate>
v-model="item.commentLevel"
disabled
size="28"
active-color="#FABB19"
></u-rate>
</view> </view>
</view> </view>
<view class="mt-[20rpx]"> <view class="mt-[20rpx]">
@ -253,29 +163,15 @@
</view> </view>
<view class="container-bottom bg-white"> <view class="container-bottom bg-white">
<view class="mx-[30rpx] mt-[30rpx]"> <view class="mx-[30rpx] mt-[30rpx]">
<u-button <u-button type="error" hover-class="none" shape="circle" :custom-style="{
type="error"
hover-class="none"
shape="circle"
:custom-style="{
height: '82rpx', height: '82rpx',
fontSize: '32rpx', fontSize: '32rpx',
background: '#FFC94D', background: '#FFC94D',
color: '#000' color: '#000'
}" }" class="pay-btn" :disabled="!paySetup.ios_is_open" :loading="isLock" @click="buyNowLock">
class="pay-btn"
:disabled="!paySetup.ios_is_open"
:loading="isLock"
@click="buyNowLock"
>
{{ paySetup.ios_prompt }} {{ paySetup.ios_prompt }}
<price <price v-if="priceState.pay !== '' && paySetup.ios_is_open" :content="priceState.pay"
v-if="priceState.pay !== '' && paySetup.ios_is_open" mainSize="32rpx" minorSize="32rpx" color="#000"></price>
:content="priceState.pay"
mainSize="32rpx"
minorSize="32rpx"
color="#000"
></price>
</u-button> </u-button>
</view> </view>
<view class="flex text-[24rpx] text-[#999999] justify-center p-[20rpx]"> <view class="flex text-[24rpx] text-[#999999] justify-center p-[20rpx]">
@ -296,120 +192,65 @@
<page-status :status="status"> </page-status> <page-status :status="status"> </page-status>
<u-popup <u-popup v-model="showGiveUpPopup" mode="center" closeable :mask-close-able="false" border-radius="20">
v-model="showGiveUpPopup"
mode="center"
closeable
:mask-close-able="false"
border-radius="20"
>
<view class="give-up-popup px-[20rpx] py-[40rpx]"> <view class="give-up-popup px-[20rpx] py-[40rpx]">
<view class="text-center text-[#55300F] mb-[40rpx]"> <view class="text-center text-[#55300F] mb-[40rpx]">
<view class="text-[34rpx] font-medium"> 确定要放弃购买会员吗 </view> <view class="text-[34rpx] font-medium"> 确定要放弃购买会员吗 </view>
<view <view v-if="
v-if="
vipAdvantage && vipAdvantage.content.enabled == 1 && currentBenefits.length vipAdvantage && vipAdvantage.content.enabled == 1 && currentBenefits.length
" " class="text-sm mt-[20rpx]">
class="text-sm mt-[20rpx]"
>
- 你可能会错过以下权益 - - 你可能会错过以下权益 -
</view> </view>
</view> </view>
<view <view v-if="vipAdvantage && vipAdvantage.content.enabled == 1 && currentBenefits.length"
v-if="vipAdvantage && vipAdvantage.content.enabled == 1 && currentBenefits.length" class="py-[20rpx] rounded-lg">
class="py-[20rpx] rounded-lg"
>
<view class="flex flex-wrap"> <view class="flex flex-wrap">
<view <view class="w-1/3 flex flex-col items-center pb-[30rpx]" v-for="(item, index) in currentBenefits"
class="w-1/3 flex flex-col items-center pb-[30rpx]" :key="index">
v-for="(item, index) in currentBenefits" <u-image width="80" height="80" :src="appStore.getImageUrl(item.image)" alt="" />
:key="index"
>
<u-image
width="80"
height="80"
:src="appStore.getImageUrl(item.image)"
alt=""
/>
<view class="pt-[10rpx]">{{ item.name }}</view> <view class="pt-[10rpx]">{{ item.name }}</view>
</view> </view>
</view> </view>
</view> </view>
<view class="flex pt-[20rpx]"> <view class="flex pt-[20rpx]">
<view class="flex-1"> <view class="flex-1">
<u-button <u-button type="primary" shape="circle" hover-class="none" :custom-style="{
type="primary"
shape="circle"
hover-class="none"
:custom-style="{
width: '100%', width: '100%',
background: '#fff', background: '#fff',
color: '#000' color: '#000'
}" }" @click="openCoupon">
@click="openCoupon"
>
残忍放弃 残忍放弃
</u-button> </u-button>
</view> </view>
<view class="flex-1 ml-[20rpx]"> <view class="flex-1 ml-[20rpx]">
<u-button <u-button type="primary" shape="circle" hover-class="none" :custom-style="{
type="primary"
shape="circle"
hover-class="none"
:custom-style="{
width: '100%', width: '100%',
background: 'linear-gradient(180.00deg, #ffc94d 0%, #ffb814 100%)', background: 'linear-gradient(180.00deg, #ffc94d 0%, #ffb814 100%)',
color: '#000' color: '#000'
}" }" @click="showGiveUpPopup = false">
@click="showGiveUpPopup = false"
>
继续支付 继续支付
</u-button> </u-button>
</view> </view>
</view> </view>
</view> </view>
</u-popup> </u-popup>
<u-popup <u-popup v-model="showCouponPopup" mode="center" closeable :mask-close-able="false" border-radius="20"
v-model="showCouponPopup" close-icon="close-circle" close-icon-size="50" close-icon-color="#fff"
mode="center" :customStyle="{ background: 'transparent' }">
closeable
:mask-close-able="false"
border-radius="20"
close-icon="close-circle"
close-icon-size="50"
close-icon-color="#fff"
:customStyle="{ background: 'transparent' }"
>
<view class="coupon-popup flex flex-col items-center"> <view class="coupon-popup flex flex-col items-center">
<view class="text-center text-[#7B3E0E]"> <view class="text-center text-[#7B3E0E]">
<view class="text-[40rpx]" <view class="text-[40rpx]">您有<price prefix="" :content="currentPackage.retrieveAmount" mainSize="44rpx"
>您有<price minorSize="44rpx" color="#FF4B4B"></price>元优惠券未使用</view>
prefix=""
:content="currentPackage.retrieveAmount"
mainSize="44rpx"
minorSize="44rpx"
color="#FF4B4B"
></price
>元优惠券未使用</view
>
<view class="text-[34rpx] mt-[20rpx]">确定要放弃吗</view> <view class="text-[34rpx] mt-[20rpx]">确定要放弃吗</view>
</view> </view>
<view class="coupon-money flex flex-col items-center justify-center"> <view class="coupon-money flex flex-col items-center justify-center">
<view> <view>
<price <price :content="currentPackage.retrieveAmount" mainSize="80rpx" minorSize="40rpx" color="#8D5836">
:content="currentPackage.retrieveAmount" </price>
mainSize="80rpx"
minorSize="40rpx"
color="#8D5836"
></price>
</view> </view>
<view class="text-[32rpx] text-[#8D5836]">无门槛</view> <view class="text-[32rpx] text-[#8D5836]">无门槛</view>
</view> </view>
<u-button <u-button type="primary" shape="circle" hover-class="none" :custom-style="{
type="primary"
shape="circle"
hover-class="none"
:custom-style="{
width: '400rpx', width: '400rpx',
background: 'linear-gradient(180.00deg, #ffe8cf 0%, #e1ab7a 100%)', background: 'linear-gradient(180.00deg, #ffe8cf 0%, #e1ab7a 100%)',
color: '#6A3D15', color: '#6A3D15',
@ -417,29 +258,15 @@
fontWeight: 600, fontWeight: 600,
fontSize: '40rpx', fontSize: '40rpx',
boxShadow: '0 3px 10px #0000001a' boxShadow: '0 3px 10px #0000001a'
}" }" @click="useCoupon">
@click="useCoupon"
>
立即使用 立即使用
</u-button> </u-button>
</view> </view>
</u-popup> </u-popup>
<payment-check <payment-check v-model:show="payState.showCheck" :from="payState.from" :order-id="payState.orderId"
v-model:show="payState.showCheck" @success="paySuccess" />
:from="payState.from" <u-popup v-model="payState.showPaySuccess" :safe-area-inset-bottom="true" :mask-close-able="false"
:order-id="payState.orderId" border-radius="14" :z-index="899" round mode="center" width="600">
@success="paySuccess"
/>
<u-popup
v-model="payState.showPaySuccess"
:safe-area-inset-bottom="true"
:mask-close-able="false"
border-radius="14"
:z-index="899"
round
mode="center"
width="600"
>
<view class="pt-[20rpx]"> <view class="pt-[20rpx]">
<view class="px-[30rpx] py-[40rpx]"> <view class="px-[30rpx] py-[40rpx]">
<view class="text-success text-center"> <view class="text-success text-center">
@ -450,9 +277,7 @@
<view class="flex-1 ml-[20rpx]"> <view class="flex-1 ml-[20rpx]">
<router-navigate <router-navigate
class="h-[72rpx] leading-[72rpx] rounded-full bg-primary text-center text-btn-text" class="h-[72rpx] leading-[72rpx] rounded-full bg-primary text-center text-btn-text"
to="/pages/index/index" to="/pages/index/index" nav-type="reLaunch">
nav-type="reLaunch"
>
<text>返回首页</text> <text>返回首页</text>
</router-navigate> </router-navigate>
</view> </view>
@ -461,12 +286,7 @@
</view> </view>
</u-popup> </u-popup>
<!-- #ifdef MP-WEIXIN --> <!-- #ifdef MP-WEIXIN -->
<page-container <page-container v-if="showPageContainer" :show="true" :overlay="false" @beforeleave="beforeLeavePage" />
v-if="showPageContainer"
:show="true"
:overlay="false"
@beforeleave="beforeLeavePage"
/>
<!-- #endif --> <!-- #endif -->
<!-- #ifdef H5 --> <!-- #ifdef H5 -->
@ -799,6 +619,7 @@ onUnmounted(() => {
page { page {
height: 100%; height: 100%;
} }
.container { .container {
padding-bottom: calc(220rpx + env(safe-area-inset-bottom)); padding-bottom: calc(220rpx + env(safe-area-inset-bottom));
@ -806,25 +627,23 @@ page {
background: url('../../static/images/vip_bg.png') no-repeat; background: url('../../static/images/vip_bg.png') no-repeat;
background-size: cover; background-size: cover;
background-position: center center; background-position: center center;
.header-title { .header-title {
background-image: linear-gradient( background-image: linear-gradient(0.26deg,
0.26deg,
#e1ab7a 0%, #e1ab7a 0%,
#e1ab7a 21.17%, #e1ab7a 21.17%,
#ffe8cf 92.32%, #ffe8cf 92.32%,
#ffefe6 100% #ffefe6 100%);
);
-webkit-background-clip: text; -webkit-background-clip: text;
color: transparent; color: transparent;
} }
.header-desc { .header-desc {
background-image: linear-gradient( background-image: linear-gradient(0.26deg,
0.26deg,
#e1ab7a 0%, #e1ab7a 0%,
#e1ab7a 21.17%, #e1ab7a 21.17%,
#ffe8cf 92.32%, #ffe8cf 92.32%,
#ffefe6 100% #ffefe6 100%);
);
-webkit-background-clip: text; -webkit-background-clip: text;
color: transparent; color: transparent;
} }
@ -834,6 +653,7 @@ page {
border-radius: 16rpx 0 16rpx 0; border-radius: 16rpx 0 16rpx 0;
transform: translateY(-50%); transform: translateY(-50%);
} }
&-bottom { &-bottom {
position: fixed; position: fixed;
bottom: 0; bottom: 0;
@ -846,19 +666,23 @@ page {
background-color: #f2f2f2 !important; background-color: #f2f2f2 !important;
} }
} }
.package-item { .package-item {
border: 1px solid transparent; border: 1px solid transparent;
&.active { &.active {
background: #fffaf0; background: #fffaf0;
border-color: #ffc94d; border-color: #ffc94d;
} }
} }
} }
.give-up-popup { .give-up-popup {
border-radius: 20rpx; border-radius: 20rpx;
background: linear-gradient(180deg, #fff 0%, #fff2e3 100%); background: linear-gradient(180deg, #fff 0%, #fff2e3 100%);
width: 640rpx; width: 640rpx;
} }
.coupon-popup { .coupon-popup {
background: url('../../static/images/coupon_bg.png') no-repeat; background: url('../../static/images/coupon_bg.png') no-repeat;
width: 670rpx; width: 670rpx;
@ -866,6 +690,7 @@ page {
background-position: center 100rpx; background-position: center 100rpx;
padding: 140rpx 100rpx 0; padding: 140rpx 100rpx 0;
background-size: 580rpx 660rpx; background-size: 580rpx 660rpx;
.coupon-money { .coupon-money {
background: url('../../static/images/money_bg.png') no-repeat; background: url('../../static/images/money_bg.png') no-repeat;
width: 340rpx; width: 340rpx;

View File

@ -4,87 +4,45 @@
<navigation-bar :front-color="$theme.navColor" :background-color="$theme.navBgColor" /> <navigation-bar :front-color="$theme.navColor" :background-color="$theme.navBgColor" />
<!-- #endif --> <!-- #endif -->
</page-meta> </page-meta>
<view <view class="register bg-white min-h-full flex flex-col items-center px-[40rpx] pt-[40rpx] box-border">
class="register bg-white min-h-full flex flex-col items-center px-[40rpx] pt-[40rpx] box-border"
>
<view class="w-full"> <view class="w-full">
<view class="pb-[40rpx]"> <view class="pb-[40rpx]">
<u-tabs <u-tabs :list="registerWayListsFilter" :is-scroll="false" v-model="currentTabs"
:list="registerWayListsFilter" :active-color="$theme.primaryColor" @change="
:is-scroll="false"
v-model="currentTabs"
:active-color="$theme.primaryColor"
@change="
(index) => { (index) => {
currentTabs = index currentTabs = index
formData.scene = registerWayLists[index].type formData.scene = registerWayLists[index].type
} }
" "></u-tabs>
></u-tabs>
</view> </view>
<u-form borderBottom :label-width="150"> <u-form borderBottom :label-width="150">
<u-form-item label="手机号" borderBottom v-if="isMobile"> <u-form-item label="手机号" borderBottom v-if="isMobile">
<u-input <u-input class="flex-1" v-model="formData.mobile" :border="false" placeholder="请输入手机号码" />
class="flex-1"
v-model="formData.mobile"
:border="false"
placeholder="请输入手机号码"
/>
</u-form-item> </u-form-item>
<u-form-item label="邮箱" borderBottom v-if="isMailbox"> <u-form-item label="邮箱" borderBottom v-if="isMailbox">
<u-input <u-input class="flex-1" v-model="formData.email" :border="false" placeholder="请输入邮箱账号" />
class="flex-1"
v-model="formData.email"
:border="false"
placeholder="请输入邮箱账号"
/>
</u-form-item> </u-form-item>
<u-form-item label="验证码" v-if="isOpenSendSms"> <u-form-item label="验证码" v-if="isOpenSendSms">
<u-input <u-input class="flex-1" v-model="formData.code" placeholder="请输入验证码" :border="false" />
class="flex-1" <view class="border-l border-solid border-0 border-light pl-3 leading-4 ml-3 w-[180rpx]"
v-model="formData.code" @click="sendCode">
placeholder="请输入验证码" <u-verification-code ref="uCodeRef" :seconds="60" @change="codeChange" change-text="x秒" />
:border="false" <text class="text-muted" :class="{
/>
<view
class="border-l border-solid border-0 border-light pl-3 leading-4 ml-3 w-[180rpx]"
@click="sendCode"
>
<u-verification-code
ref="uCodeRef"
:seconds="60"
@change="codeChange"
change-text="x秒"
/>
<text
class="text-muted"
:class="{
'text-primary': 'text-primary':
(isValidMobile && isMobile) || (isValidMailBox && isMailbox) (isValidMobile && isMobile) || (isValidMailBox && isMailbox)
}" }">
>
{{ codeTips }} {{ codeTips }}
</text> </text>
</view> </view>
</u-form-item> </u-form-item>
<u-form-item label="设置密码" borderBottom> <u-form-item label="设置密码" borderBottom>
<u-input <u-input class="flex-1" type="password" v-model="formData.password" placeholder="6-20位数字+字母或符号组合"
class="flex-1" :border="false" />
type="password"
v-model="formData.password"
placeholder="6-20位数字+字母或符号组合"
:border="false"
/>
</u-form-item> </u-form-item>
<u-form-item label="确认密码" borderBottom> <u-form-item label="确认密码" borderBottom>
<u-input <u-input class="flex-1" type="password" v-model="formData.password2" placeholder="请确认密码"
class="flex-1" :border="false" />
type="password"
v-model="formData.password2"
placeholder="请确认密码"
:border="false"
/>
</u-form-item> </u-form-item>
</u-form> </u-form>
<view class="mt-[40rpx]"> <view class="mt-[40rpx]">
@ -215,7 +173,7 @@ const bindUsers = async (userSn: number) => {
}) })
cache.remove(USER_SN) cache.remove(USER_SN)
} }
} catch (error) {} } catch (error) { }
} }
const accountRegister = async () => { const accountRegister = async () => {

View File

@ -3,12 +3,7 @@
<!-- 头部修改头像 --> <!-- 头部修改头像 -->
<view class="header bg-white py-[30rpx]"> <view class="header bg-white py-[30rpx]">
<view class="flex justify-center"> <view class="flex justify-center">
<avatar-upload <avatar-upload v-model="userInfo.avatar" file-key="url" :round="true" @upload="uploadImg">
v-model="userInfo.avatar"
file-key="url"
:round="true"
@upload="uploadImg"
>
<template #footer> <template #footer>
<!-- #ifdef MP-WEIXIN --> <!-- #ifdef MP-WEIXIN -->
<view class="text-muted text-xs">同步微信头像</view> <view class="text-muted text-xs">同步微信头像</view>
@ -19,20 +14,14 @@
</view> </view>
<!-- 用户ID --> <!-- 用户ID -->
<view <view class="item text-nr flex justify-between" @click="; (showUserName = true), (newUsername = userInfo?.username)">
class="item text-nr flex justify-between"
@click=";(showUserName = true), (newUsername = userInfo?.username)"
>
<view class="label">账号</view> <view class="label">账号</view>
<view class="content">{{ userInfo?.username }}</view> <view class="content">{{ userInfo?.username }}</view>
<u-icon name="arrow-right" size="22" color="#666"></u-icon> <u-icon name="arrow-right" size="22" color="#666"></u-icon>
</view> </view>
<!-- 昵称 --> <!-- 昵称 -->
<view <view class="item text-nr flex justify-between" @click="; (showNickName = true), (newNickname = userInfo?.nickname)">
class="item text-nr flex justify-between"
@click=";(showNickName = true), (newNickname = userInfo?.nickname)"
>
<view class="label">昵称</view> <view class="label">昵称</view>
<view class="content">{{ userInfo?.nickname }}</view> <view class="content">{{ userInfo?.nickname }}</view>
<u-icon name="arrow-right" size="22" color="#666"></u-icon> <u-icon name="arrow-right" size="22" color="#666"></u-icon>
@ -46,13 +35,13 @@
</view> </view>
<!-- 手机号 --> <!-- 手机号 -->
<view class="item text-nr flex justify-between"> <!-- <view class="item text-nr flex justify-between">
<view class="label">手机号</view> <view class="label">手机号</view>
<view class="content">{{ <view class="content">{{
userInfo?.mobile == '' ? '未绑定手机号' : userInfo?.mobile userInfo?.mobile == '' ? '未绑定手机号' : userInfo?.mobile
}}</view> }}</view>
<!-- #ifdef MP-WEIXIN -->
<u-button <u-button
open-type="getPhoneNumber" open-type="getPhoneNumber"
@getphonenumber="getPhoneNumber" @getphonenumber="getPhoneNumber"
@ -63,8 +52,7 @@
> >
{{ userInfo?.mobile == '' ? '绑定手机号' : '更换手机号' }} {{ userInfo?.mobile == '' ? '绑定手机号' : '更换手机号' }}
</u-button> </u-button>
<!-- #endif -->
<!-- #ifndef MP-WEIXIN -->
<u-button <u-button
@click="showMobilePop = true" @click="showMobilePop = true"
size="mini" size="mini"
@ -74,8 +62,9 @@
> >
{{ userInfo?.mobile == '' ? '绑定手机号' : '更换手机号' }} {{ userInfo?.mobile == '' ? '绑定手机号' : '更换手机号' }}
</u-button> </u-button>
<!-- #endif -->
</view> </view> -->
<!-- 邮箱 --> <!-- 邮箱 -->
<view class="item text-nr flex justify-between"> <view class="item text-nr flex justify-between">
<view class="label">邮箱</view> <view class="label">邮箱</view>
@ -91,32 +80,17 @@
</view> </view>
<!-- 昵称修改组件 --> <!-- 昵称修改组件 -->
<u-popup <u-popup v-model="showNickName" :closeable="true" mode="center" :maskCloseAble="false" border-radius="20">
v-model="showNickName"
:closeable="true"
mode="center"
:maskCloseAble="false"
border-radius="20"
>
<view class="px-[50rpx] py-[40rpx] bg-white" style="width: 85vw"> <view class="px-[50rpx] py-[40rpx] bg-white" style="width: 85vw">
<form @submit="changeNameConfirm"> <form @submit="changeNameConfirm">
<view class="mb-[70rpx] text-xl text-center">修改昵称</view> <view class="mb-[70rpx] text-xl text-center">修改昵称</view>
<u-form-item borderBottom> <u-form-item borderBottom>
<input <input class="nr h-[60rpx] w-full" :value="userInfo.nickname" name="nickname" type="nickname"
class="nr h-[60rpx] w-full" placeholder="请输入昵称" />
:value="userInfo.nickname"
name="nickname"
type="nickname"
placeholder="请输入昵称"
/>
</u-form-item> </u-form-item>
<view class="mt-[80rpx]"> <view class="mt-[80rpx]">
<button <button class="bg-primary text-white w-full h-[80rpx] !text-lg !leading-[80rpx] rounded-full"
class="bg-primary text-white w-full h-[80rpx] !text-lg !leading-[80rpx] rounded-full" form-type="submit" hover-class="none" size="mini">
form-type="submit"
hover-class="none"
size="mini"
>
确定 确定
</button> </button>
</view> </view>
@ -129,12 +103,7 @@
<view class="px-[50rpx] py-[40rpx] bg-white" style="width: 85vw"> <view class="px-[50rpx] py-[40rpx] bg-white" style="width: 85vw">
<view class="mb-[70rpx] text-xl text-center">修改账号</view> <view class="mb-[70rpx] text-xl text-center">修改账号</view>
<u-form-item borderBottom> <u-form-item borderBottom>
<u-input <u-input class="flex-1" v-model="newUsername" placeholder="请输入账号" :border="false" />
class="flex-1"
v-model="newUsername"
placeholder="请输入账号"
:border="false"
/>
</u-form-item> </u-form-item>
<view class="mt-[80rpx]"> <view class="mt-[80rpx]">
<u-button @click="changeUserNameConfirm" type="primary" shape="circle"> <u-button @click="changeUserNameConfirm" type="primary" shape="circle">
@ -145,44 +114,21 @@
</u-popup> </u-popup>
<!-- 性别修改组件 --> <!-- 性别修改组件 -->
<u-picker <u-picker mode="selector" v-model="showPicker" confirm-color="#4173FF" :default-selector="[0]" :range="sexList"
mode="selector" @confirm="changeSexConfirm" />
v-model="showPicker"
confirm-color="#4173FF"
:default-selector="[0]"
:range="sexList"
@confirm="changeSexConfirm"
/>
<!-- 账号修改组件 --> <!-- 账号修改组件 -->
<u-popup v-model="showMobilePop" :closeable="true" mode="center" border-radius="20"> <u-popup v-model="showMobilePop" :closeable="true" mode="center" border-radius="20">
<view class="px-[50rpx] py-[40rpx] bg-white" style="width: 85vw"> <view class="px-[50rpx] py-[40rpx] bg-white" style="width: 85vw">
<view class="mb-[70rpx] text-xl text-center">修改手机号码</view> <view class="mb-[70rpx] text-xl text-center">修改手机号码</view>
<u-form-item borderBottom> <u-form-item borderBottom>
<u-input <u-input class="flex-1" v-model="newMobile" placeholder="请输入新的手机号码" :border="false" />
class="flex-1"
v-model="newMobile"
placeholder="请输入新的手机号码"
:border="false"
/>
</u-form-item> </u-form-item>
<u-form-item borderBottom> <u-form-item borderBottom>
<u-input <u-input class="flex-1" v-model="mobileCode" placeholder="请输入验证码" :border="false" />
class="flex-1" <view class="border-l border-solid border-0 border-light pl-3 text-muted leading-4 ml-3 w-[180rpx]"
v-model="mobileCode" @click="sendSms">
placeholder="请输入验证码" <u-verification-code ref="uCodeRef" :seconds="60" @change="codeChange" change-text="x秒" />
:border="false"
/>
<view
class="border-l border-solid border-0 border-light pl-3 text-muted leading-4 ml-3 w-[180rpx]"
@click="sendSms"
>
<u-verification-code
ref="uCodeRef"
:seconds="60"
@change="codeChange"
change-text="x秒"
/>
{{ codeTips }} {{ codeTips }}
</view> </view>
</u-form-item> </u-form-item>

View File

@ -1,10 +1,7 @@
<template> <template>
<page-meta :page-style="$theme.pageStyle"> <page-meta :page-style="$theme.pageStyle">
<!-- #ifndef H5 --> <!-- #ifndef H5 -->
<navigation-bar <navigation-bar :front-color="$theme.navColor" :background-color="$theme.navBgColor" />
:front-color="$theme.navColor"
:background-color="$theme.navBgColor"
/>
<!-- #endif --> <!-- #endif -->
</page-meta> </page-meta>
<view class="user-set"> <view class="user-set">
@ -20,19 +17,12 @@
</view> </view>
</view> </view>
</navigator> </navigator>
<view <view class="item bg-white mt-[20rpx] btn-border flex flex-1 justify-between" @click="handlePwd">
class="item bg-white mt-[20rpx] btn-border flex flex-1 justify-between"
@click="handlePwd"
>
<view class="">登录密码</view> <view class="">登录密码</view>
<u-icon name="arrow-right" color="#666"></u-icon> <u-icon name="arrow-right" color="#666"></u-icon>
</view> </view>
<!-- #ifdef MP-WEIXIN || H5 --> <!-- #ifdef MP-WEIXIN || H5 -->
<view <view v-if="isWeixin" class="item bg-white flex flex-1 justify-between" @click="bindWechatLock">
v-if="isWeixin"
class="item bg-white flex flex-1 justify-between"
@click="bindWechatLock"
>
<view class="">绑定微信</view> <view class="">绑定微信</view>
<view class="flex justify-between"> <view class="flex justify-between">
<view class="text-muted mr-[20rpx]"> <view class="text-muted mr-[20rpx]">
@ -42,7 +32,7 @@
</view> </view>
</view> </view>
<!-- #endif --> <!-- #endif -->
<navigator :url="`/packages/pages/agreement/agreement?type=${AgreementEnum.PRIVACY}`"> <!-- <navigator :url="`/packages/pages/agreement/agreement?type=${AgreementEnum.PRIVACY}`">
<view class="item bg-white mt-[20rpx] btn-border flex flex-1 justify-between"> <view class="item bg-white mt-[20rpx] btn-border flex flex-1 justify-between">
<view class="">隐私政策</view> <view class="">隐私政策</view>
<u-icon name="arrow-right" color="#666"></u-icon> <u-icon name="arrow-right" color="#666"></u-icon>
@ -64,14 +54,12 @@
<u-icon name="arrow-right" color="#666"></u-icon> <u-icon name="arrow-right" color="#666"></u-icon>
</view> </view>
</view> </view>
</navigator> </navigator> -->
<!-- 注销账号 --> <!-- 注销账号 -->
<view <view v-if="userInfo?.isCancelled == 1"
v-if="userInfo?.isCancelled == 1"
class="text-nr flex justify-between mt-[10rpx] px-[30rpx] bg-white h-[100rpx] items-center" class="text-nr flex justify-between mt-[10rpx] px-[30rpx] bg-white h-[100rpx] items-center"
@click="handlecancel" @click="handlecancel">
>
<view class="label">注销账号</view> <view class="label">注销账号</view>
<u-icon name="arrow-right" size="22" color="#666"></u-icon> <u-icon name="arrow-right" size="22" color="#666"></u-icon>
</view> </view>
@ -80,12 +68,8 @@
</view> </view>
<u-action-sheet <u-action-sheet :list="list" v-model="show" @click="handleClick"
:list="list" :safe-area-inset-bottom="true"></u-action-sheet>
v-model="show"
@click="handleClick"
:safe-area-inset-bottom="true"
></u-action-sheet>
<!-- #ifdef H5 --> <!-- #ifdef H5 -->
<!-- 悬浮菜单 --> <!-- 悬浮菜单 -->
<floating-menu></floating-menu> <floating-menu></floating-menu>

View File

@ -1,19 +1,10 @@
{ {
"pages": [ "pages": [
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "首页",
"enablePullDownRefresh": false
},
"meta": {
"share": true
}
},
{ {
"path": "pages/ai_creation/ai_creation", "path": "pages/ai_creation/ai_creation",
"style": { "style": {
"navigationBarTitleText": "AI创作" "navigationBarTitleText": "AI创作",
"enablePullDownRefresh": false
}, },
"meta": { "meta": {
"share": true "share": true
@ -85,7 +76,6 @@
} }
} }
], ],
"subPackages": [ "subPackages": [
{ {
"root": "packages", "root": "packages",

View File

@ -3,61 +3,22 @@
<view class="mb-[60rpx]"> <view class="mb-[60rpx]">
<u-form> <u-form>
<u-form-item> <u-form-item>
<u-icon <u-icon class="mr-2" :size="36" name="/static/images/icon/icon_mobile.png" />
class="mr-2" <u-input class="flex-1" v-model="formData.email" :border="false" placeholder="请输入邮箱账号" />
:size="36"
name="/static/images/icon/icon_mobile.png"
/>
<u-input
class="flex-1"
v-model="formData.email"
:border="false"
placeholder="请输入邮箱账号"
/>
</u-form-item> </u-form-item>
<u-form-item v-if="appStore.getLoginConfig.is_captcha"> <u-form-item v-if="appStore.getLoginConfig.is_captcha">
<u-icon <u-icon class="mr-2" :size="36" name="/static/images/icon/icon_code.png" />
class="mr-2" <u-input class="flex-1" v-model="formData.code" placeholder="图形验证码" :border="false" />
:size="36" <view class="pl-3 leading-4 ml-3 w-[180rpx]" @click="getCaptchaFn">
name="/static/images/icon/icon_code.png" <image :src="captchaImage" title="点击刷新" alt="验证码" class='w-full h-[50rpx]' />
/>
<u-input
class="flex-1"
v-model="formData.code"
placeholder="图形验证码"
:border="false"
/>
<view
class="pl-3 leading-4 ml-3 w-[180rpx]"
@click="getCaptchaFn"
>
<image
:src="captchaImage"
title="点击刷新"
alt="验证码"
class='w-full h-[50rpx]'
/>
</view> </view>
</u-form-item> </u-form-item>
<u-form-item> <u-form-item>
<u-icon <u-icon class="mr-2" :size="36" name="/static/images/icon/icon_password.png" />
class="mr-2" <u-input class="flex-1" v-model="formData.password" type="password" placeholder="请输入密码"
:size="36" :border="false" />
name="/static/images/icon/icon_password.png" <router-navigate to="/packages/pages/forget_pwd/forget_pwd?type=3">
/> <view class="border-l border-solid border-0 border-light pl-3 text-muted leading-4 ml-3">
<u-input
class="flex-1"
v-model="formData.password"
type="password"
placeholder="请输入密码"
:border="false"
/>
<router-navigate
to="/packages/pages/forget_pwd/forget_pwd?type=3"
>
<view
class="border-l border-solid border-0 border-light pl-3 text-muted leading-4 ml-3"
>
忘记密码 忘记密码
</view> </view>
</router-navigate> </router-navigate>
@ -68,19 +29,14 @@
<view class="mb-[40rpx]"> <view class="mb-[40rpx]">
<agreement ref="agreementRef" /> <agreement ref="agreementRef" />
</view> </view>
<u-button <u-button type="primary" shape="circle" hover-class="none" @click="handleLogin">
type="primary"
shape="circle"
hover-class="none"
@click="handleLogin"
>
</u-button> </u-button>
<view class="text-content flex justify-end mt-[40rpx]"> <view class="text-content flex justify-end mt-[40rpx]">
<router-navigate to="/packages/pages/register/register?type=3"> <!-- <router-navigate to="/packages/pages/register/register?type=3">
注册账号 注册账号
</router-navigate> </router-navigate> -->
</view> </view>
</view> </view>
</template> </template>

File diff suppressed because one or more lines are too long

View File

@ -7,14 +7,9 @@
<view class="user"> <view class="user">
<view v-for="(item, index) in state.pages" :key="index"> <view v-for="(item, index) in state.pages" :key="index">
<template v-if="item.name == 'user-info'"> <template v-if="item.name == 'user-info'">
<w-user-info <w-user-info :content="item.content" :styles="item.styles" :user="userInfo" :is-login="isLogin" />
:content="item.content"
:styles="item.styles"
:user="userInfo"
:is-login="isLogin"
/>
</template> </template>
<template v-if="item.name == 'open-vip'"> <!-- <template v-if="item.name == 'open-vip'">
<w-user-vip <w-user-vip
:content="item.content" :content="item.content"
:styles="item.styles" :styles="item.styles"
@ -30,7 +25,7 @@
</template> </template>
<template v-if="item.name == 'user-bottom'"> <template v-if="item.name == 'user-bottom'">
<w-user-bottom :content="item.content" :styles="item.styles" /> <w-user-bottom :content="item.content" :styles="item.styles" />
</template> </template> -->
</view> </view>
<tabbar /> <tabbar />
</view> </view>

View File

@ -1,14 +1,16 @@
// #ifdef H5 // #ifdef H5
// 提交前需要注释 本地调试使用 // 提交前需要注释 本地调试使用
import Vconsole from 'vconsole' import Vconsole from "vconsole";
import { isDevMode } from '@/utils/env' import { isDevMode } from "@/utils/env";
// #endif // #endif
export default () => { export default () => {
// #ifdef H5 // #ifdef H5
if (isDevMode()) { // if (isDevMode()) {
const vConsole = new Vconsole() // const vConsole = new Vconsole()
return vConsole // return vConsole
} // }
// #endif // #endif
} const vConsole = new Vconsole();
return vConsole;
};

View File

@ -1,13 +1,13 @@
import { defineStore } from 'pinia' import { defineStore } from "pinia";
import { getConfig } from '@/api/app' import { getConfig } from "@/api/app";
interface AppSate { interface AppSate {
config: Record<string, any> config: Record<string, any>;
} }
export const useAppStore = defineStore({ export const useAppStore = defineStore({
id: 'appStore', id: "appStore",
state: (): AppSate => ({ state: (): AppSate => ({
config: {} config: {},
}), }),
getters: { getters: {
getWebsiteConfig: (state) => state.config.website || {}, getWebsiteConfig: (state) => state.config.website || {},
@ -29,15 +29,16 @@ export const useAppStore = defineStore({
getIsVoiceTransfer: (state) => getIsVoiceTransfer: (state) =>
!!state.config.voice?.voice_input?.is_open || false, !!state.config.voice?.voice_input?.is_open || false,
getIsVoiceChat: (state) => getIsVoiceChat: (state) =>
!!state.config.voice?.voice_chat?.is_open || false !!state.config.voice?.voice_chat?.is_open || false,
}, },
actions: { actions: {
getImageUrl(url: string) { getImageUrl(url: string) {
return url.indexOf('http') ? `${this.config.domain}${url}` : url const imgUrl = url.indexOf("http") ? `${this.config.domain}${url}` : url;
return imgUrl;
}, },
async getConfig() { async getConfig() {
const data = await getConfig({ type: 1 }) const data = await getConfig({ type: 1 });
this.config = data this.config = data;
} },
} },
}) });

2178
yarn.lock

File diff suppressed because it is too large Load Diff