ea
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"usingComponents": {
|
||||
"custom-nav": "/components/custom-nav/custom-nav"
|
||||
},
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
import { backgroundTemplates, updateTaskBackground } from "../../../utils/request"
|
||||
|
||||
type Category = {
|
||||
id: string
|
||||
name: string
|
||||
}
|
||||
|
||||
type BgTemplate = {
|
||||
id: number
|
||||
name: string
|
||||
scene: string
|
||||
category: string
|
||||
coverUrl?: string
|
||||
imageUrl?: string
|
||||
videoUrl?: string
|
||||
isRecommend?: number
|
||||
}
|
||||
|
||||
function filterTemplates(category: string, templates: BgTemplate[]) {
|
||||
if (category === 'all') return templates
|
||||
return templates.filter((item) => item.category === category)
|
||||
}
|
||||
|
||||
Page({
|
||||
data: {
|
||||
taskId: '',
|
||||
categories: [] as Category[],
|
||||
activeCategory: 'all',
|
||||
selectedTemplate: 0,
|
||||
allTemplates: [] as BgTemplate[],
|
||||
templates: [] as BgTemplate[],
|
||||
loading: false,
|
||||
},
|
||||
|
||||
onLoad(options: any) {
|
||||
this.setData({ taskId: options.taskId || options.taskid || '' })
|
||||
this.loadBackgroundTemplates()
|
||||
},
|
||||
|
||||
loadBackgroundTemplates() {
|
||||
this.setData({ loading: true })
|
||||
backgroundTemplates().then((res: any) => {
|
||||
const categories = res && !res.code && res.data ? (res.data.categories || []) : []
|
||||
const templates = res && !res.code && res.data ? (res.data.templates || []) : []
|
||||
const selectedTemplate = templates.length ? Number(templates[0].id) : 0
|
||||
this.setData({
|
||||
categories,
|
||||
allTemplates: templates,
|
||||
templates: filterTemplates(this.data.activeCategory, templates),
|
||||
selectedTemplate,
|
||||
loading: false,
|
||||
})
|
||||
}).catch(() => {
|
||||
this.setData({ loading: false })
|
||||
wx.showModal({ title: '温馨提示', content: '背景模板加载失败,请稍后再试', showCancel: false })
|
||||
})
|
||||
},
|
||||
|
||||
handleBack() {
|
||||
wx.navigateBack({
|
||||
fail: () => wx.navigateTo({ url: '/pages/aiPackage/record/index' }),
|
||||
})
|
||||
},
|
||||
|
||||
handleCategorySelect(e: WechatMiniprogram.TouchEvent) {
|
||||
const activeCategory = e.currentTarget.dataset.id
|
||||
if (!activeCategory) return
|
||||
|
||||
const templates = filterTemplates(activeCategory, this.data.allTemplates)
|
||||
this.setData({ activeCategory, templates })
|
||||
},
|
||||
|
||||
handleTemplateSelect(e: WechatMiniprogram.TouchEvent) {
|
||||
const selectedTemplate = Number(e.currentTarget.dataset.id || 0)
|
||||
if (selectedTemplate <= 0) return
|
||||
|
||||
this.setData({ selectedTemplate })
|
||||
},
|
||||
|
||||
handleConfirm() {
|
||||
if (!this.data.taskId) {
|
||||
wx.showModal({ title: '温馨提示', content: '创作记录不存在', showCancel: false })
|
||||
return
|
||||
}
|
||||
if (this.data.selectedTemplate <= 0) {
|
||||
wx.showModal({ title: '温馨提示', content: '请选择背景模板', showCancel: false })
|
||||
return
|
||||
}
|
||||
|
||||
wx.showLoading({ mask: true, title: '保存背景中' })
|
||||
updateTaskBackground(this.data.taskId, this.data.selectedTemplate).then((res: any) => {
|
||||
wx.hideLoading()
|
||||
if (!res.code) {
|
||||
wx.redirectTo({ url: '/pages/aiPackage/gen/index?taskId=' + encodeURIComponent(this.data.taskId) })
|
||||
} else {
|
||||
wx.showModal({ title: '温馨提示', content: res.message || '背景保存失败', showCancel: false })
|
||||
}
|
||||
}).catch(() => {
|
||||
wx.hideLoading()
|
||||
wx.showModal({ title: '温馨提示', content: '网络异常,请稍后再试', showCancel: false })
|
||||
})
|
||||
},
|
||||
})
|
||||
@@ -0,0 +1,44 @@
|
||||
<view class="bg-page">
|
||||
<custom-nav padding-x="34">
|
||||
<view class="bg-nav">
|
||||
<view class="nav-back" bindtap="handleBack"><text></text></view>
|
||||
<view class="nav-title-wrap">
|
||||
<text class="nav-title">选择背景模板</text>
|
||||
<text class="nav-subtitle">选择适合你视频内容的场景背景</text>
|
||||
</view>
|
||||
<view class="nav-space"></view>
|
||||
</view>
|
||||
</custom-nav>
|
||||
|
||||
<view class="bg-content">
|
||||
<scroll-view class="category-scroll" scroll-x="true" enhanced="true" show-scrollbar="false">
|
||||
<view class="category-list">
|
||||
<view wx:for="{{categories}}" wx:key="id"
|
||||
class="category-item {{activeCategory === item.id ? 'category-active' : ''}}" data-id="{{item.id}}"
|
||||
bindtap="handleCategorySelect">{{item.name}}</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
|
||||
<view class="template-grid">
|
||||
<scroll-view class="auto-flex" enable-flex="true" scroll-y="true">
|
||||
<view wx:for="{{templates}}" wx:key="id"
|
||||
class="template-card {{selectedTemplate === item.id ? 'template-active' : ''}}" data-id="{{item.id}}"
|
||||
bindtap="handleTemplateSelect">
|
||||
<view class="scene-preview scene-{{item.scene}}">
|
||||
<image class="scene-placeholder icon-placeholder" src="/static/images/my/image.png" mode="aspectFit">
|
||||
</image>
|
||||
<view class="select-circle top-circle {{selectedTemplate === item.id ? 'circle-active' : ''}}"><text></text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="template-foot">
|
||||
<text>{{item.name}}</text>
|
||||
<!-- <view class="select-circle foot-circle {{selectedTemplate === item.id ? 'circle-active' : ''}}">
|
||||
<text></text></view> -->
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
|
||||
<view class="confirm-action" bindtap="handleConfirm">确认背景,去生成</view>
|
||||
</view>
|
||||
</view>
|
||||
@@ -0,0 +1,367 @@
|
||||
page {
|
||||
min-height: 100vh;
|
||||
background: #f8faff;
|
||||
color: #111827;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
}
|
||||
|
||||
.bg-page {
|
||||
width: 750rpx;
|
||||
height: 100vh;
|
||||
margin: 0 auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
box-sizing: border-box;
|
||||
background:
|
||||
radial-gradient(circle at 12% 0%, rgba(104, 126, 255, 0.08), transparent 34%),
|
||||
radial-gradient(circle at 88% 10%, rgba(130, 86, 255, 0.08), transparent 30%),
|
||||
linear-gradient(180deg, #fbfcff 0%, #f6f8ff 44%, #ffffff 100%);
|
||||
}
|
||||
|
||||
.bg-nav {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.nav-back,
|
||||
.nav-space {
|
||||
width: 60rpx;
|
||||
height: 60rpx;
|
||||
flex: 0 0 60rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.nav-back text {
|
||||
width: 26rpx;
|
||||
height: 26rpx;
|
||||
display: block;
|
||||
border-left: 5rpx solid #111827;
|
||||
border-bottom: 5rpx solid #111827;
|
||||
transform: rotate(45deg);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.nav-title-wrap {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 10rpx;
|
||||
}
|
||||
|
||||
.nav-title {
|
||||
color: #111827;
|
||||
font-size: 34rpx;
|
||||
line-height: 40rpx;
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
.nav-subtitle {
|
||||
max-width: 560rpx;
|
||||
color: #6c7284;
|
||||
font-size: 22rpx;
|
||||
line-height: 28rpx;
|
||||
font-weight: 600;
|
||||
text-align: center;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.bg-content {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
overflow-y: hidden;
|
||||
flex-direction: column;
|
||||
padding: 20rpx 18rpx 34rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.category-scroll {
|
||||
width: 100%;
|
||||
flex: 0 0 auto;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.auto-flex {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.category-list {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10rpx;
|
||||
padding: 2rpx 0 26rpx;
|
||||
}
|
||||
|
||||
.category-item {
|
||||
height: 46rpx;
|
||||
padding: 0 18rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border: 2rpx solid #e0e4f2;
|
||||
border-radius: 24rpx;
|
||||
background: #ffffff;
|
||||
color: #656d80;
|
||||
font-size: 21rpx;
|
||||
line-height: 28rpx;
|
||||
font-weight: 800;
|
||||
box-sizing: border-box;
|
||||
white-space: nowrap;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.category-active {
|
||||
border-color: #7462ff;
|
||||
color: #ffffff;
|
||||
background: linear-gradient(100deg, #6b83ff 0%, #754df3 100%);
|
||||
box-shadow: 0 8rpx 18rpx rgba(101, 85, 246, 0.2);
|
||||
}
|
||||
|
||||
.template-grid {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
justify-content: space-between;
|
||||
row-gap: 30rpx;
|
||||
padding: 0 0 34rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.template-card {
|
||||
width: 326rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
border: 2rpx solid transparent;
|
||||
border-radius: 14rpx;
|
||||
margin-bottom: 20rpx;
|
||||
background: #ffffff;
|
||||
box-shadow: 0 12rpx 30rpx rgba(83, 92, 151, 0.12);
|
||||
box-sizing: border-box;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.template-active {
|
||||
border-color: #765eff;
|
||||
box-shadow: 0 12rpx 30rpx rgba(101, 85, 246, 0.22);
|
||||
}
|
||||
|
||||
.scene-preview {
|
||||
height: 166rpx;
|
||||
padding: 12rpx 14rpx;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-content: space-between;
|
||||
justify-content: space-between;
|
||||
box-sizing: border-box;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.scene-window,
|
||||
.scene-light,
|
||||
.scene-plant,
|
||||
.scene-main {
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.scene-window {
|
||||
width: 96rpx;
|
||||
height: 56rpx;
|
||||
border-radius: 4rpx;
|
||||
background: linear-gradient(135deg, rgba(255, 255, 255, 0.88) 0%, rgba(225, 238, 250, 0.72) 100%);
|
||||
box-shadow: inset 0 0 0 2rpx rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
|
||||
.scene-light {
|
||||
width: 54rpx;
|
||||
height: 66rpx;
|
||||
border-radius: 28rpx 28rpx 10rpx 10rpx;
|
||||
background: linear-gradient(180deg, rgba(255, 246, 210, 0.9), rgba(226, 170, 92, 0.35));
|
||||
}
|
||||
|
||||
.scene-plant {
|
||||
width: 44rpx;
|
||||
height: 62rpx;
|
||||
border-radius: 28rpx 28rpx 8rpx 8rpx;
|
||||
background:
|
||||
radial-gradient(circle at 30% 28%, #7db66d 0 10rpx, transparent 11rpx),
|
||||
radial-gradient(circle at 68% 36%, #679f5d 0 12rpx, transparent 13rpx),
|
||||
linear-gradient(180deg, transparent 0 42rpx, #b48354 43rpx 100%);
|
||||
}
|
||||
|
||||
.plant-right {
|
||||
transform: scale(0.82);
|
||||
}
|
||||
|
||||
.scene-main {
|
||||
width: 160rpx;
|
||||
height: 54rpx;
|
||||
border-radius: 10rpx 10rpx 4rpx 4rpx;
|
||||
background: rgba(255, 255, 255, 0.72);
|
||||
box-shadow: inset 0 -8rpx 0 rgba(188, 158, 120, 0.18);
|
||||
}
|
||||
|
||||
.scene-live {
|
||||
background:
|
||||
linear-gradient(90deg, rgba(255, 255, 255, 0.28) 0 2rpx, transparent 2rpx 100%),
|
||||
linear-gradient(180deg, #fff4df 0%, #f9ead4 48%, #dfc09a 100%);
|
||||
}
|
||||
|
||||
.scene-office {
|
||||
background:
|
||||
linear-gradient(90deg, rgba(150, 168, 184, 0.16) 0 2rpx, transparent 2rpx 64rpx),
|
||||
linear-gradient(180deg, #eff6fb 0%, #dfe7ec 52%, #c8d2d9 100%);
|
||||
}
|
||||
|
||||
.scene-office .scene-main {
|
||||
width: 178rpx;
|
||||
background: linear-gradient(180deg, #f8fbfd 0%, #cbd7df 100%);
|
||||
}
|
||||
|
||||
.scene-classroom {
|
||||
background: linear-gradient(180deg, #fff4df 0%, #f4dfbf 52%, #d6b98c 100%);
|
||||
}
|
||||
|
||||
.scene-classroom .scene-main {
|
||||
width: 184rpx;
|
||||
height: 58rpx;
|
||||
background:
|
||||
linear-gradient(180deg, #4d7555 0%, #315b3b 100%);
|
||||
box-shadow: 0 18rpx 0 rgba(140, 98, 56, 0.32);
|
||||
}
|
||||
|
||||
.scene-emotion {
|
||||
background: linear-gradient(180deg, #ffe2be 0%, #e5b379 52%, #b57945 100%);
|
||||
}
|
||||
|
||||
.scene-emotion .scene-main,
|
||||
.scene-life .scene-main {
|
||||
width: 178rpx;
|
||||
height: 52rpx;
|
||||
border-radius: 30rpx 30rpx 12rpx 12rpx;
|
||||
background: linear-gradient(180deg, #f5dfc9 0%, #d1a78a 100%);
|
||||
}
|
||||
|
||||
.scene-product {
|
||||
background: linear-gradient(180deg, #f8dbb5 0%, #dfb076 55%, #b9844f 100%);
|
||||
}
|
||||
|
||||
.scene-product .scene-main {
|
||||
width: 174rpx;
|
||||
height: 58rpx;
|
||||
border-radius: 50%;
|
||||
background: radial-gradient(circle at 50% 34%, #fff1d7 0%, #c8965e 66%, #9e6e3c 100%);
|
||||
}
|
||||
|
||||
.scene-life {
|
||||
background: linear-gradient(180deg, #fff6e9 0%, #ead8bd 54%, #c9ab81 100%);
|
||||
}
|
||||
|
||||
.template-foot {
|
||||
height: 62rpx;
|
||||
padding: 0 18rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 12rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.template-foot text {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
color: #222633;
|
||||
font-size: 25rpx;
|
||||
line-height: 32rpx;
|
||||
font-weight: 900;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.template-active .template-foot text {
|
||||
color: #6559ff;
|
||||
}
|
||||
|
||||
.select-circle {
|
||||
width: 34rpx;
|
||||
height: 34rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border: 3rpx solid #d4d8e8;
|
||||
border-radius: 50%;
|
||||
background: rgba(255, 255, 255, 0.9);
|
||||
box-sizing: border-box;
|
||||
flex: 0 0 34rpx;
|
||||
}
|
||||
|
||||
.top-circle {
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.foot-circle {
|
||||
width: 32rpx;
|
||||
height: 32rpx;
|
||||
}
|
||||
|
||||
.circle-active {
|
||||
border-color: #7363ff;
|
||||
background: linear-gradient(135deg, #7089ff 0%, #7a4df4 100%);
|
||||
}
|
||||
|
||||
.circle-active text {
|
||||
width: 14rpx;
|
||||
height: 8rpx;
|
||||
display: block;
|
||||
border-left: 4rpx solid #ffffff;
|
||||
border-bottom: 4rpx solid #ffffff;
|
||||
transform: rotate(-45deg);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.confirm-action {
|
||||
height: 86rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 16rpx;
|
||||
color: #ffffff;
|
||||
background: linear-gradient(100deg, #4e84ff 0%, #7d3ff3 100%);
|
||||
box-shadow: 0 14rpx 28rpx rgba(91, 86, 245, 0.24);
|
||||
font-size: 29rpx;
|
||||
line-height: 36rpx;
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
.scene-placeholder {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.icon-placeholder {
|
||||
display: block;
|
||||
flex-shrink: 0;
|
||||
background: none;
|
||||
border: 0;
|
||||
box-shadow: none;
|
||||
transform: none;
|
||||
}
|
||||
|
||||
.scene-preview {
|
||||
position: relative;
|
||||
padding: 0;
|
||||
background: #ffffff;
|
||||
}
|
||||
|
||||
.top-circle {
|
||||
position: absolute;
|
||||
top: 12rpx;
|
||||
right: 14rpx;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"usingComponents": {
|
||||
"custom-nav": "/components/custom-nav/custom-nav"
|
||||
},
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
import { taskinfo } from "../../../utils/request"
|
||||
|
||||
function createTaskId() {
|
||||
return `task_${Date.now()}`
|
||||
}
|
||||
|
||||
Page({
|
||||
|
||||
data: {
|
||||
taskinfo: null as any,
|
||||
userinfo: null,
|
||||
price: 40,
|
||||
start: false
|
||||
},
|
||||
|
||||
onLoad(ops: { taskId: string }) {
|
||||
this.setData({ userinfo: wx.getStorageSync('userInfo') })
|
||||
taskinfo(ops.taskId).then((res: any) => {
|
||||
console.log(res);
|
||||
if (!res.code) {
|
||||
this.setData({ taskinfo: res.data });
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
handleBack() {
|
||||
wx.navigateBack({
|
||||
fail: () => wx.navigateTo({ url: '/pages/aiPackage/bg/index' }),
|
||||
})
|
||||
},
|
||||
|
||||
handleViewScript() {
|
||||
wx.showToast({ title: '展示完整文案', icon: 'none' })
|
||||
},
|
||||
|
||||
handleGenerate() {
|
||||
if (!this.data.taskinfo) {
|
||||
return;
|
||||
}
|
||||
let task_no = this.data.taskinfo.task_no || '';
|
||||
const detailUrl = `/pages/historyPackage/historyDetail/index?status=processing&taskId=${encodeURIComponent(task_no)}`
|
||||
|
||||
let userinfo = wx.getStorageSync('userinfo');
|
||||
if (userinfo.diamond < this.data.price) {
|
||||
wx.showModal({ title: '温馨提示', content: '余额不足' })
|
||||
return;
|
||||
}
|
||||
|
||||
this.setData({ start: true })
|
||||
|
||||
// wx.redirectTo({ url: detailUrl })
|
||||
},
|
||||
|
||||
handleDownload() {
|
||||
// wx.showToast({ title: '开始下载', icon: 'none' })
|
||||
wx.downloadFile({
|
||||
url: '',
|
||||
success(res) {
|
||||
wx.showModal({ title: '温馨提示', content: '下载成功' })
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
handleRegenerate() {
|
||||
// wx.showToast({ title: '重新生成', icon: 'none' })
|
||||
},
|
||||
|
||||
handleHome() {
|
||||
wx.switchTab({
|
||||
url: '/pages/index/index',
|
||||
})
|
||||
},
|
||||
})
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
<view class="gen-page">
|
||||
<custom-nav content-height="62" padding-x="34">
|
||||
<view class="gen-nav">
|
||||
<view class="nav-back" bindtap="handleBack"><text></text></view>
|
||||
<text class="nav-title">生成视频</text>
|
||||
<view class="coin-pill">
|
||||
<!-- <image class="coin-icon icon-placeholder" src="/static/images/my/image.png" mode="aspectFit"></image>
|
||||
<text>金币</text>
|
||||
<text class="coin-count">128</text> -->
|
||||
</view>
|
||||
</view>
|
||||
</custom-nav>
|
||||
|
||||
<view class="gen-content">
|
||||
<view class="confirm-card">
|
||||
<text class="card-title">生成确认</text>
|
||||
<view class="info-list">
|
||||
<view class="info-row avatar-row">
|
||||
<text class="info-label">数字人形象</text>
|
||||
<image class="small-avatar icon-placeholder" src="{{ taskinfo.avatar.image_url }}" mode="aspectFit"></image>
|
||||
</view>
|
||||
<view class="info-row">
|
||||
<text class="info-label">背景模板</text>
|
||||
<text class="info-value">清新直播间</text>
|
||||
</view>
|
||||
<view class="info-row">
|
||||
<text class="info-label">音色</text>
|
||||
<view class="voice-value">
|
||||
<image class="voice-icon icon-placeholder" src="/static/images/yinse.png" mode="aspectFit"></image>
|
||||
<text>已上传专属音色</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="info-row script-row">
|
||||
<text class="info-label">文案摘要</text>
|
||||
<view class="script-summary">
|
||||
<text>{{ taskinfo.script_text }}</text>
|
||||
<view class="view-script" bindtap="handleViewScript">
|
||||
<text>查看完整文案</text>
|
||||
<text class="right-arrow"></text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="cost-card" wx:if="{{!start}}">
|
||||
<view class="cost-row">
|
||||
<text>本次生成消耗</text>
|
||||
<view class="amount"><text>{{price}}</text><text>金币</text></view>
|
||||
</view>
|
||||
<view class="cost-row">
|
||||
<text>当前余额</text>
|
||||
<view class="balance-line">
|
||||
<view class="amount"><text>{{userinfo.diamond}}</text><text>金币</text></view>
|
||||
<view class="{{ userinfo.diamond < price ?'enough-waring': 'enough'}}">
|
||||
<text></text><text>{{userinfo.diamond < price? '余额不足' : '余额充足'}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="generate-action" bindtap="handleGenerate">
|
||||
<image class="sparkle icon-placeholder" src="/static/images/filter-3-filled.png" mode="aspectFit"></image>
|
||||
<text>一键生成数字人视频</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view wx:if="{{start}}" style="display:flex;flex-direction: column;gap: 30rpx;">
|
||||
<view class="result-title">
|
||||
<image class="result-icon icon-placeholder" src="/static/images/my/image.png" mode="aspectFit"></image>
|
||||
<text>生成结果</text>
|
||||
</view>
|
||||
|
||||
<view class="video-preview">
|
||||
<view class="preview-bg">
|
||||
<image class="preview-plant plant-left icon-placeholder" src="/static/images/my/image.png" mode="aspectFit">
|
||||
</image>
|
||||
<image class="preview-plant plant-right icon-placeholder" src="/static/images/my/image.png" mode="aspectFit">
|
||||
</image>
|
||||
<image class="preview-avatar icon-placeholder" src="/static/images/my/image.png" mode="aspectFit"></image>
|
||||
<image class="play-btn icon-placeholder" src="/static/images/my/image.png" mode="aspectFit"></image>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="bottom-actions">
|
||||
<view class="action-primary" bindtap="handleDownload">
|
||||
<image class="download-icon icon-placeholder" src="/static/images/download.png" mode="aspectFit"></image>
|
||||
<text>下载视频</text>
|
||||
</view>
|
||||
<view class="action-outline" bindtap="handleRegenerate">
|
||||
<image class="refresh-icon icon-placeholder" src="/static/images/currency-exchange.png" mode="aspectFit">
|
||||
</image>
|
||||
<text>重新生成</text>
|
||||
</view>
|
||||
<view class="action-outline" bindtap="handleHome">
|
||||
<image class="home-icon icon-placeholder" src="/static/images/to_index.png" mode="aspectFit"></image>
|
||||
<text>返回首页</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="save-tip">
|
||||
<image class="tip-icon icon-placeholder" src="/static/images/info-circle.png" mode="aspectFit"></image>
|
||||
<text>视频已为你自动保存到【创作记录】</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@@ -0,0 +1,590 @@
|
||||
page {
|
||||
min-height: 100vh;
|
||||
background: #f8faff;
|
||||
color: #111827;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
}
|
||||
|
||||
.gen-page {
|
||||
width: 750rpx;
|
||||
min-height: 100vh;
|
||||
margin: 0 auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
box-sizing: border-box;
|
||||
background:
|
||||
radial-gradient(circle at 12% 0%, rgba(104, 126, 255, 0.08), transparent 34%),
|
||||
radial-gradient(circle at 88% 8%, rgba(130, 86, 255, 0.08), transparent 30%),
|
||||
linear-gradient(180deg, #fbfcff 0%, #f6f8ff 46%, #ffffff 100%);
|
||||
}
|
||||
|
||||
.gen-nav {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 16rpx;
|
||||
}
|
||||
|
||||
.nav-back {
|
||||
width: 60rpx;
|
||||
height: 60rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex: 0 0 60rpx;
|
||||
}
|
||||
|
||||
.nav-back text {
|
||||
width: 26rpx;
|
||||
height: 26rpx;
|
||||
display: block;
|
||||
border-left: 5rpx solid #111827;
|
||||
border-bottom: 5rpx solid #111827;
|
||||
transform: rotate(45deg);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.nav-title {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
color: #111827;
|
||||
font-size: 34rpx;
|
||||
line-height: 42rpx;
|
||||
font-weight: 900;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.coin-pill {
|
||||
height: 50rpx;
|
||||
padding: 0 16rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 8rpx;
|
||||
/* border: 2rpx solid #eef0fb; */
|
||||
border-radius: 28rpx;
|
||||
/* background: rgba(255, 255, 255, 0.88); */
|
||||
/* box-shadow: 0 8rpx 18rpx rgba(93, 102, 158, 0.12); */
|
||||
color: #111827;
|
||||
font-size: 22rpx;
|
||||
line-height: 28rpx;
|
||||
font-weight: 800;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.coin-icon {
|
||||
width: 30rpx;
|
||||
height: 30rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 50%;
|
||||
color: #ffffff;
|
||||
background: linear-gradient(135deg, #ffd45d 0%, #ffa51f 100%);
|
||||
font-size: 17rpx;
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
.coin-count {
|
||||
color: #6657ff;
|
||||
}
|
||||
|
||||
.gen-content {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 18rpx;
|
||||
padding: 30rpx;
|
||||
box-sizing: border-box;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.confirm-card,
|
||||
.cost-card {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
border: 2rpx solid #e6e9ff;
|
||||
border-radius: 16rpx;
|
||||
background: rgba(255, 255, 255, 0.96);
|
||||
box-shadow: 0 14rpx 34rpx rgba(80, 92, 170, 0.08);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.confirm-card {
|
||||
padding: 22rpx 28rpx 10rpx;
|
||||
}
|
||||
|
||||
.card-title {
|
||||
color: #111827;
|
||||
font-size: 27rpx;
|
||||
line-height: 34rpx;
|
||||
font-weight: 900;
|
||||
padding-bottom: 18rpx;
|
||||
border-bottom: 2rpx solid #edf0f8;
|
||||
}
|
||||
|
||||
.info-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.info-row {
|
||||
min-height: 62rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 20rpx;
|
||||
border-bottom: 2rpx solid #edf0f8;
|
||||
}
|
||||
|
||||
.info-row:last-child {
|
||||
border-bottom: 0;
|
||||
}
|
||||
|
||||
.avatar-row {
|
||||
min-height: 72rpx;
|
||||
}
|
||||
|
||||
.info-label {
|
||||
flex: 0 0 160rpx;
|
||||
color: #303748;
|
||||
font-size: 24rpx;
|
||||
line-height: 32rpx;
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
.info-value,
|
||||
.voice-value,
|
||||
.script-summary {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
color: #41495b;
|
||||
font-size: 24rpx;
|
||||
line-height: 32rpx;
|
||||
font-weight: 700;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.small-avatar {
|
||||
width: 58rpx;
|
||||
height: 58rpx;
|
||||
border-radius: 10rpx;
|
||||
background:
|
||||
radial-gradient(circle at 50% 33%, #ffe1d2 0 17rpx, transparent 18rpx),
|
||||
radial-gradient(circle at 50% 34%, #33201b 0 24rpx, transparent 25rpx),
|
||||
linear-gradient(180deg, #eef4ff 0%, #ffffff 100%);
|
||||
flex: 0 0 58rpx;
|
||||
}
|
||||
|
||||
.voice-value {
|
||||
gap: 10rpx;
|
||||
}
|
||||
|
||||
.voice-icon {
|
||||
width: 28rpx;
|
||||
height: 28rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: #6d58ff;
|
||||
flex: 0 0 28rpx;
|
||||
}
|
||||
|
||||
.voice-icon::before,
|
||||
.voice-icon::after,
|
||||
.voice-icon text {
|
||||
content: '';
|
||||
width: 5rpx;
|
||||
border-radius: 5rpx;
|
||||
background: #6d58ff;
|
||||
}
|
||||
|
||||
.voice-icon::before { height: 18rpx; }
|
||||
.voice-icon text { height: 28rpx; margin: 0 4rpx; display: block; }
|
||||
.voice-icon::after { height: 20rpx; }
|
||||
|
||||
.script-row {
|
||||
align-items: flex-start;
|
||||
padding: 16rpx 0;
|
||||
}
|
||||
|
||||
.script-summary {
|
||||
flex-direction: column;
|
||||
align-items: flex-end;
|
||||
gap: 10rpx;
|
||||
line-height: 34rpx;
|
||||
}
|
||||
|
||||
.view-script {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10rpx;
|
||||
color: #7062ff;
|
||||
font-size: 23rpx;
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
.right-arrow {
|
||||
width: 14rpx;
|
||||
height: 14rpx;
|
||||
border-right: 4rpx solid #7062ff;
|
||||
border-top: 4rpx solid #7062ff;
|
||||
transform: rotate(45deg);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.cost-card {
|
||||
padding: 12rpx 24rpx 22rpx;
|
||||
background: linear-gradient(100deg, rgba(255, 255, 255, 0.98) 0%, rgba(239, 255, 248, 0.92) 100%);
|
||||
margin-bottom: calc(10rpx + env(safe-area-inset-bottom));
|
||||
}
|
||||
|
||||
.cost-row {
|
||||
min-height: 52rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
border-bottom: 2rpx solid rgba(224, 229, 242, 0.75);
|
||||
color: #303748;
|
||||
font-size: 24rpx;
|
||||
line-height: 32rpx;
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
.amount,
|
||||
.balance-line,
|
||||
.enough {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.amount {
|
||||
gap: 10rpx;
|
||||
color: #111827;
|
||||
}
|
||||
|
||||
.amount text:first-child {
|
||||
font-size: 32rpx;
|
||||
line-height: 38rpx;
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
.amount text:last-child {
|
||||
font-size: 23rpx;
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
.balance-line {
|
||||
gap: 22rpx;
|
||||
}
|
||||
|
||||
.enough {
|
||||
gap: 8rpx;
|
||||
color: #40bf83;
|
||||
font-size: 21rpx;
|
||||
line-height: 28rpx;
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
.enough-waring {
|
||||
gap: 8rpx;
|
||||
color: red;
|
||||
font-size: 21rpx;
|
||||
line-height: 28rpx;
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
.enough text:first-child {
|
||||
width: 26rpx;
|
||||
height: 26rpx;
|
||||
border-radius: 50%;
|
||||
background: #42c982;
|
||||
}
|
||||
|
||||
.enough text:first-child::after {
|
||||
content: '';
|
||||
width: 11rpx;
|
||||
height: 7rpx;
|
||||
margin: 7rpx auto 0;
|
||||
display: block;
|
||||
border-left: 3rpx solid #ffffff;
|
||||
border-bottom: 3rpx solid #ffffff;
|
||||
transform: rotate(-45deg);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.generate-action {
|
||||
height: 66rpx;
|
||||
margin-top: 14rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 12rpx;
|
||||
border-radius: 12rpx;
|
||||
color: #ffffff;
|
||||
background: linear-gradient(100deg, #4e84ff 0%, #7d3ff3 100%);
|
||||
box-shadow: 0 12rpx 24rpx rgba(91, 86, 245, 0.22);
|
||||
font-size: 27rpx;
|
||||
line-height: 34rpx;
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
.sparkle {
|
||||
width: 28rpx;
|
||||
height: 28rpx;
|
||||
background:
|
||||
linear-gradient(90deg, transparent 42%, #ffffff 43% 57%, transparent 58%),
|
||||
linear-gradient(0deg, transparent 42%, #ffffff 43% 57%, transparent 58%);
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
|
||||
.result-title {
|
||||
margin-top: 14rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10rpx;
|
||||
color: #3f4dff;
|
||||
font-size: 25rpx;
|
||||
line-height: 32rpx;
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
.result-icon {
|
||||
width: 25rpx;
|
||||
height: 25rpx;
|
||||
border: 4rpx solid #625aff;
|
||||
border-radius: 8rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.video-preview {
|
||||
width: 100%;
|
||||
height: 274rpx;
|
||||
border-radius: 14rpx;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 12rpx 30rpx rgba(83, 92, 151, 0.13);
|
||||
}
|
||||
|
||||
.preview-bg {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
justify-content: center;
|
||||
background:
|
||||
linear-gradient(90deg, rgba(255,255,255,0.36) 0 3rpx, transparent 3rpx 64rpx),
|
||||
linear-gradient(180deg, #fff4e3 0%, #f1dcc3 58%, #d9b98f 100%);
|
||||
}
|
||||
|
||||
.preview-plant {
|
||||
width: 86rpx;
|
||||
height: 126rpx;
|
||||
margin-bottom: 18rpx;
|
||||
border-radius: 50rpx 50rpx 12rpx 12rpx;
|
||||
background:
|
||||
radial-gradient(circle at 30% 24%, #79ad65 0 22rpx, transparent 23rpx),
|
||||
radial-gradient(circle at 66% 32%, #6aa05f 0 24rpx, transparent 25rpx),
|
||||
radial-gradient(circle at 50% 50%, #7eb86a 0 25rpx, transparent 26rpx),
|
||||
linear-gradient(180deg, transparent 0 82rpx, #a9794d 83rpx 100%);
|
||||
}
|
||||
|
||||
.plant-left {
|
||||
margin-right: 76rpx;
|
||||
}
|
||||
|
||||
.plant-right {
|
||||
margin-left: 76rpx;
|
||||
}
|
||||
|
||||
.preview-avatar {
|
||||
width: 176rpx;
|
||||
height: 236rpx;
|
||||
margin-bottom: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.avatar-head {
|
||||
width: 116rpx;
|
||||
height: 130rpx;
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
justify-content: center;
|
||||
border-radius: 60rpx 60rpx 42rpx 42rpx;
|
||||
background: linear-gradient(160deg, #241a18 0%, #604038 60%, #8a6258 100%);
|
||||
}
|
||||
|
||||
.avatar-face {
|
||||
width: 78rpx;
|
||||
height: 92rpx;
|
||||
margin-bottom: 10rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 12rpx;
|
||||
border-radius: 42rpx 42rpx 34rpx 34rpx;
|
||||
background: linear-gradient(180deg, #ffe6d9 0%, #ffd0c2 100%);
|
||||
}
|
||||
|
||||
.avatar-eyes {
|
||||
width: 48rpx;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.avatar-eyes text {
|
||||
width: 8rpx;
|
||||
height: 8rpx;
|
||||
border-radius: 50%;
|
||||
background: #241a18;
|
||||
}
|
||||
|
||||
.avatar-mouth {
|
||||
width: 26rpx;
|
||||
height: 8rpx;
|
||||
border-radius: 0 0 16rpx 16rpx;
|
||||
background: #ca6975;
|
||||
}
|
||||
|
||||
.avatar-body {
|
||||
width: 160rpx;
|
||||
height: 106rpx;
|
||||
border-radius: 46rpx 46rpx 0 0;
|
||||
background: linear-gradient(120deg, #ffffff 0%, #f5f4f1 48%, #ffffff 100%);
|
||||
}
|
||||
|
||||
.play-btn {
|
||||
width: 74rpx;
|
||||
height: 74rpx;
|
||||
margin-left: -126rpx;
|
||||
margin-bottom: 54rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border: 4rpx solid rgba(255, 255, 255, 0.82);
|
||||
border-radius: 50%;
|
||||
background: rgba(49, 43, 38, 0.48);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.play-btn text {
|
||||
width: 0;
|
||||
height: 0;
|
||||
margin-left: 6rpx;
|
||||
border-top: 16rpx solid transparent;
|
||||
border-bottom: 16rpx solid transparent;
|
||||
border-left: 24rpx solid #ffffff;
|
||||
}
|
||||
|
||||
.bottom-actions {
|
||||
display: flex;
|
||||
gap: 18rpx;
|
||||
}
|
||||
|
||||
.action-primary,
|
||||
.action-outline {
|
||||
height: 82rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 12rpx;
|
||||
border-radius: 14rpx;
|
||||
font-size: 24rpx;
|
||||
line-height: 31rpx;
|
||||
font-weight: 900;
|
||||
box-sizing: border-box;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.action-primary {
|
||||
color: #ffffff;
|
||||
background: linear-gradient(100deg, #5a80ff 0%, #764df3 100%);
|
||||
box-shadow: 0 12rpx 24rpx rgba(91, 86, 245, 0.18);
|
||||
}
|
||||
|
||||
.action-outline {
|
||||
color: #625aff;
|
||||
border: 2rpx solid #dce0f5;
|
||||
background: #ffffff;
|
||||
}
|
||||
|
||||
.download-icon {
|
||||
width: 24rpx;
|
||||
height: 24rpx;
|
||||
border-left: 4rpx solid #ffffff;
|
||||
border-bottom: 4rpx solid #ffffff;
|
||||
transform: rotate(-45deg);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.refresh-icon {
|
||||
width: 24rpx;
|
||||
height: 24rpx;
|
||||
border: 4rpx solid #625aff;
|
||||
border-right-color: transparent;
|
||||
border-radius: 50%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.home-icon {
|
||||
width: 25rpx;
|
||||
height: 22rpx;
|
||||
border: 4rpx solid #625aff;
|
||||
border-top: 0;
|
||||
border-radius: 4rpx;
|
||||
box-sizing: border-box;
|
||||
transform: translateY(4rpx);
|
||||
}
|
||||
|
||||
.home-icon::before {
|
||||
content: '';
|
||||
width: 18rpx;
|
||||
height: 18rpx;
|
||||
display: block;
|
||||
border-left: 4rpx solid #625aff;
|
||||
border-top: 4rpx solid #625aff;
|
||||
transform: rotate(45deg) translate(-4rpx, -13rpx);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.save-tip {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 10rpx;
|
||||
color: #8d94a5;
|
||||
font-size: 23rpx;
|
||||
line-height: 30rpx;
|
||||
font-weight: 600;
|
||||
margin-bottom: calc(10rpx + env(safe-area-inset-bottom));
|
||||
}
|
||||
|
||||
.tip-icon {
|
||||
width: 24rpx;
|
||||
height: 24rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border: 3rpx solid #9aa1b2;
|
||||
border-radius: 50%;
|
||||
font-size: 16rpx;
|
||||
line-height: 18rpx;
|
||||
font-weight: 900;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.icon-placeholder {
|
||||
display: block;
|
||||
flex-shrink: 0;
|
||||
background: none;
|
||||
border: 0;
|
||||
box-shadow: none;
|
||||
transform: none;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"usingComponents": {
|
||||
"custom-nav": "/components/custom-nav/custom-nav"
|
||||
},
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
import { polishScript, saveScript, taskinfo } from "../../../utils/request"
|
||||
|
||||
type PolishStyle = {
|
||||
id: string
|
||||
name: string
|
||||
icon: string
|
||||
activeIcon: string
|
||||
}
|
||||
|
||||
const styles: PolishStyle[] = [
|
||||
{ id: 'natural', name: '自然口播', icon: '/static/images/Frame-15355646363.png', activeIcon: '/static/images/Frame-1561268387.png' },
|
||||
{ id: 'goods', name: '带货风格', icon: '/static/images/Frame-1561268385.png', activeIcon: '/static/images/Frame-1561268389.png' },
|
||||
{ id: 'emotion', name: '情感风格', icon: '/static/images/Frame-1561268384.png', activeIcon: '/static/images/Frame-1561268388.png' },
|
||||
{ id: 'teach', name: '专业讲解', icon: '/static/images/Frame-1561268383.png', activeIcon: '/static/images/Frame-1561268390.png' },
|
||||
{ id: 'viral', name: '爆款短视频', icon: '/static/images/Frame-1561268382.png', activeIcon: '/static/images/Frame-1561268386.png' },
|
||||
]
|
||||
|
||||
const styleMap: Record<string, string> = {
|
||||
natural: 'friendly',
|
||||
goods: 'product',
|
||||
emotion: 'rewrite',
|
||||
teach: 'professional',
|
||||
viral: 'rewrite',
|
||||
}
|
||||
|
||||
Page({
|
||||
data: {
|
||||
styles,
|
||||
selectedStyle: 'natural',
|
||||
taskinfo: null as any,
|
||||
inEdit: false,
|
||||
},
|
||||
|
||||
onLoad(ops: any) {
|
||||
taskinfo(ops.taskId).then((res: any) => {
|
||||
if (!res.code) {
|
||||
this.setData({ taskinfo: res.data })
|
||||
} else {
|
||||
wx.showModal({ title: '温馨提示', content: res.message || '获取文案失败', showCancel: false })
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
handleBack() {
|
||||
wx.navigateBack({
|
||||
fail: () => wx.switchTab({ url: '/pages/index/index' }),
|
||||
})
|
||||
},
|
||||
|
||||
handleStyleSelect(e: WechatMiniprogram.TouchEvent) {
|
||||
const selectedStyle = e.currentTarget.dataset.id
|
||||
if (!selectedStyle) return
|
||||
|
||||
this.setData({ selectedStyle })
|
||||
},
|
||||
|
||||
handleEdit() {
|
||||
if (!this.data.taskinfo) return
|
||||
|
||||
this.setData({ inEdit: !this.data.inEdit })
|
||||
},
|
||||
|
||||
changeContent(e: any) {
|
||||
const taskinfo = this.data.taskinfo
|
||||
if (!taskinfo) return
|
||||
|
||||
taskinfo.script_text = e.detail.value
|
||||
this.setData({ taskinfo })
|
||||
},
|
||||
|
||||
handleRegenerate() {
|
||||
const taskinfo = this.data.taskinfo
|
||||
if (!taskinfo) return
|
||||
|
||||
const content = taskinfo.script_text || taskinfo.original_script || ''
|
||||
if (!content) {
|
||||
wx.showToast({ title: '暂无可润色文案', icon: 'none' })
|
||||
return
|
||||
}
|
||||
|
||||
wx.showLoading({ title: '润色中' })
|
||||
polishScript(taskinfo.task_no, content, styleMap[this.data.selectedStyle] || 'optimize').then((res: any) => {
|
||||
wx.hideLoading()
|
||||
if (res.code) {
|
||||
wx.showModal({ title: '温馨提示', content: res.message || '润色失败', showCancel: false })
|
||||
return
|
||||
}
|
||||
|
||||
taskinfo.script_text = res.data.scriptText
|
||||
this.setData({ taskinfo, inEdit: false })
|
||||
wx.showToast({ title: '已重新润色', icon: 'success' })
|
||||
}).catch(() => {
|
||||
wx.hideLoading()
|
||||
wx.showModal({ title: '温馨提示', content: '网络异常,请稍后再试', showCancel: false })
|
||||
})
|
||||
},
|
||||
|
||||
handleConfirm() {
|
||||
this.saveCurrentScript(true)
|
||||
},
|
||||
|
||||
saveCurrentScript(next: boolean) {
|
||||
const taskinfo = this.data.taskinfo
|
||||
if (!taskinfo) return
|
||||
|
||||
const content = (taskinfo.script_text || '').trim()
|
||||
if (!content) {
|
||||
wx.showToast({ title: '文案不能为空', icon: 'none' })
|
||||
return
|
||||
}
|
||||
|
||||
wx.showLoading({ title: '保存中' })
|
||||
saveScript(taskinfo.task_no, content).then((res: any) => {
|
||||
wx.hideLoading()
|
||||
if (res.code) {
|
||||
wx.showModal({ title: '温馨提示', content: res.message || '保存失败', showCancel: false })
|
||||
return
|
||||
}
|
||||
|
||||
taskinfo.script_text = res.data.scriptText
|
||||
this.setData({ taskinfo, inEdit: false })
|
||||
if (next) {
|
||||
wx.redirectTo({
|
||||
url: '/pages/aiPackage/record/index?taskid=' + taskinfo.task_no,
|
||||
})
|
||||
} else {
|
||||
wx.showToast({ title: '已保存', icon: 'success' })
|
||||
}
|
||||
}).catch(() => {
|
||||
wx.hideLoading()
|
||||
wx.showModal({ title: '温馨提示', content: '网络异常,请稍后再试', showCancel: false })
|
||||
})
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
<view class="preview-page">
|
||||
<custom-nav content-height="86" padding-x="34">
|
||||
<view class="preview-nav">
|
||||
<view class="nav-back" bindtap="handleBack"><text></text></view>
|
||||
<view class="nav-title-wrap">
|
||||
<text class="nav-title">文案优化</text>
|
||||
<text class="nav-subtitle">让口播更自然,更适合短视频传播</text>
|
||||
</view>
|
||||
<view class="nav-space"></view>
|
||||
</view>
|
||||
</custom-nav>
|
||||
|
||||
<view class="preview-content">
|
||||
<view class="panel original-panel">
|
||||
<text class="panel-title">原文案</text>
|
||||
<view class="script-text original-text">
|
||||
<text>{{taskinfo.original_script}}</text>
|
||||
</view>
|
||||
<text class="count-text">共 {{taskinfo.original_script.length}} 字</text>
|
||||
</view>
|
||||
|
||||
<view class="panel ai-panel">
|
||||
<view class="panel-head">
|
||||
<view class="title-line">
|
||||
<text class="panel-title">AI 优化后文案</text>
|
||||
<text class="status-pill">已优化</text>
|
||||
</view>
|
||||
<view class="edit-btn" bindtap="handleEdit">
|
||||
<image class="edit-icon icon-placeholder" src="/static/images/edit.png" mode="aspectFit"></image>
|
||||
<text>{{inEdit?'保存':'编辑'}}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="optimized-box">
|
||||
<text wx:if="{{inEdit == false}}">{{taskinfo.script_text}}</text>
|
||||
<textarea bindinput="changeContent" wx:else value="{{taskinfo.script_text}}"></textarea>
|
||||
<text class="optimized-count">共 {{taskinfo.script_text.length}} 字</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="panel style-panel">
|
||||
<text class="panel-title">选择润色风格</text>
|
||||
<view class="style-list">
|
||||
<view
|
||||
wx:for="{{styles}}"
|
||||
wx:key="id"
|
||||
class="style-item {{selectedStyle === item.id ? 'style-item-active' : ''}}"
|
||||
data-id="{{item.id}}"
|
||||
bindtap="handleStyleSelect"
|
||||
>
|
||||
<image class="style-icon style-icon-{{item.id}} icon-placeholder" src="{{selectedStyle == item.id ? item.activeIcon :item.icon}}" mode="aspectFit"></image>
|
||||
<text>{{item.name}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="action-row">
|
||||
<view class="outline-action" bindtap="handleRegenerate">重新润色</view>
|
||||
<view class="confirm-action" bindtap="handleConfirm">确认使用此文案</view>
|
||||
</view>
|
||||
|
||||
<view class="bottom-tip">
|
||||
<image class="tip-dot icon-placeholder" src="/static/images/info-circle.png" mode="aspectFit"></image>
|
||||
<text>新生成的视频将使用优化后的文案进行口播</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
@@ -0,0 +1,335 @@
|
||||
page {
|
||||
min-height: 100vh;
|
||||
background: #f8faff;
|
||||
color: #111827;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
}
|
||||
|
||||
.preview-page {
|
||||
width: 750rpx;
|
||||
min-height: 100vh;
|
||||
margin: 0 auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
box-sizing: border-box;
|
||||
background:
|
||||
radial-gradient(circle at 10% 0%, rgba(117, 93, 255, 0.08), transparent 32%),
|
||||
radial-gradient(circle at 92% 8%, rgba(74, 132, 255, 0.08), transparent 30%),
|
||||
linear-gradient(180deg, #fbfcff 0%, #f5f7ff 48%, #ffffff 100%);
|
||||
}
|
||||
|
||||
.preview-nav {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.nav-back,
|
||||
.nav-space {
|
||||
width: 60rpx;
|
||||
height: 60rpx;
|
||||
flex: 0 0 60rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.nav-back text {
|
||||
width: 26rpx;
|
||||
height: 26rpx;
|
||||
display: block;
|
||||
border-left: 5rpx solid #111827;
|
||||
border-bottom: 5rpx solid #111827;
|
||||
transform: rotate(45deg);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.nav-title-wrap {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 10rpx;
|
||||
}
|
||||
|
||||
.nav-title {
|
||||
font-size: 34rpx;
|
||||
line-height: 40rpx;
|
||||
font-weight: 900;
|
||||
color: #111827;
|
||||
}
|
||||
|
||||
.nav-subtitle {
|
||||
max-width: 520rpx;
|
||||
font-size: 22rpx;
|
||||
line-height: 28rpx;
|
||||
font-weight: 600;
|
||||
color: #6d7484;
|
||||
text-align: center;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.preview-content {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 26rpx;
|
||||
padding: 22rpx 34rpx 30rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.panel {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
box-sizing: border-box;
|
||||
border: 2rpx solid #e8eaff;
|
||||
border-radius: 16rpx;
|
||||
background: rgba(255, 255, 255, 0.94);
|
||||
box-shadow: 0 12rpx 34rpx rgba(80, 92, 170, 0.08);
|
||||
}
|
||||
|
||||
.original-panel {
|
||||
min-height: 326rpx;
|
||||
padding: 25rpx 32rpx 22rpx;
|
||||
}
|
||||
|
||||
.panel-title {
|
||||
font-size: 28rpx;
|
||||
line-height: 36rpx;
|
||||
font-weight: 900;
|
||||
color: #111827;
|
||||
}
|
||||
|
||||
.script-text {
|
||||
margin-top: 22rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
color: #252a35;
|
||||
font-size: 24rpx;
|
||||
line-height: 42rpx;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.original-text {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.count-text,
|
||||
.optimized-count {
|
||||
align-self: flex-end;
|
||||
font-size: 21rpx;
|
||||
line-height: 28rpx;
|
||||
font-weight: 600;
|
||||
color: #9ba1af;
|
||||
}
|
||||
|
||||
.ai-panel {
|
||||
padding: 20rpx 18rpx 18rpx;
|
||||
}
|
||||
|
||||
.panel-head {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 20rpx;
|
||||
padding: 0 16rpx 16rpx;
|
||||
}
|
||||
|
||||
.title-line {
|
||||
min-width: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 18rpx;
|
||||
}
|
||||
|
||||
.status-pill {
|
||||
padding: 4rpx 18rpx;
|
||||
border-radius: 20rpx;
|
||||
background: #ece9ff;
|
||||
color: #7860ff;
|
||||
font-size: 20rpx;
|
||||
line-height: 28rpx;
|
||||
font-weight: 800;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.edit-btn {
|
||||
height: 48rpx;
|
||||
padding: 0 20rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 10rpx;
|
||||
border: 2rpx solid #d8d1ff;
|
||||
border-radius: 14rpx;
|
||||
color: #7254f4;
|
||||
font-size: 23rpx;
|
||||
line-height: 28rpx;
|
||||
font-weight: 800;
|
||||
box-sizing: border-box;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.edit-icon {
|
||||
width: 21rpx;
|
||||
height: 21rpx;
|
||||
border: 4rpx solid #7254f4;
|
||||
border-left: 0;
|
||||
border-top: 0;
|
||||
transform: skew(-12deg) rotate(-45deg);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.optimized-box {
|
||||
min-height: 286rpx;
|
||||
padding: 20rpx 20rpx 18rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
border: 2rpx solid #dcd9ff;
|
||||
border-radius: 14rpx;
|
||||
box-sizing: border-box;
|
||||
color: #252a35;
|
||||
font-size: 24rpx;
|
||||
line-height: 40rpx;
|
||||
font-weight: 700;
|
||||
background: #ffffff;
|
||||
}
|
||||
|
||||
.style-panel {
|
||||
padding: 25rpx 18rpx 22rpx;
|
||||
gap: 22rpx;
|
||||
}
|
||||
|
||||
.style-list {
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
justify-content: space-between;
|
||||
gap: 16rpx;
|
||||
}
|
||||
|
||||
.style-item {
|
||||
width: 112rpx;
|
||||
height: 112rpx;
|
||||
padding: 12rpx 8rpx 10rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 8rpx;
|
||||
border: 2rpx solid #e1e4f4;
|
||||
border-radius: 12rpx;
|
||||
background: #ffffff;
|
||||
box-sizing: border-box;
|
||||
color: #555d6f;
|
||||
font-size: 19rpx;
|
||||
line-height: 24rpx;
|
||||
font-weight: 800;
|
||||
text-align: center;
|
||||
flex: 0 0 112rpx;
|
||||
}
|
||||
|
||||
.style-item-active {
|
||||
border-color: #7461ff;
|
||||
background: linear-gradient(180deg, #806bff 0%, #5f55f5 100%);
|
||||
color: #ffffff;
|
||||
box-shadow: 0 10rpx 22rpx rgba(98, 85, 245, 0.26);
|
||||
}
|
||||
|
||||
.style-icon {
|
||||
width: 44rpx;
|
||||
height: 44rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 16rpx;
|
||||
font-size: 18rpx;
|
||||
line-height: 20rpx;
|
||||
font-weight: 900;
|
||||
color: #ffffff;
|
||||
background: #83cfff;
|
||||
}
|
||||
|
||||
.style-icon-natural { background: linear-gradient(135deg, #8c82ff 0%, #6b58ff 100%); }
|
||||
.style-icon-goods { background: linear-gradient(135deg, #a7e8ff 0%, #69bde8 100%); }
|
||||
.style-icon-emotion { background: linear-gradient(135deg, #ffd888 0%, #ffb750 100%); }
|
||||
.style-icon-teach { background: linear-gradient(135deg, #dca8ff 0%, #9f66ef 100%); }
|
||||
.style-icon-viral { background: linear-gradient(135deg, #ffbccd 0%, #ff7696 100%); }
|
||||
|
||||
.style-item-active .style-icon {
|
||||
background: rgba(255, 255, 255, 0.16);
|
||||
border: 1rpx solid rgba(255, 255, 255, 0.24);
|
||||
}
|
||||
|
||||
.action-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 20rpx;
|
||||
margin-top: 2rpx;
|
||||
}
|
||||
|
||||
.outline-action,
|
||||
.confirm-action {
|
||||
height: 76rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 16rpx;
|
||||
font-size: 27rpx;
|
||||
line-height: 34rpx;
|
||||
font-weight: 900;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.outline-action {
|
||||
flex: 0 0 278rpx;
|
||||
border: 2rpx solid #d9d4ff;
|
||||
background: rgba(255, 255, 255, 0.86);
|
||||
color: #7254f4;
|
||||
}
|
||||
|
||||
.confirm-action {
|
||||
flex: 1;
|
||||
color: #ffffff;
|
||||
background: linear-gradient(100deg, #4e84ff 0%, #7d3ff3 100%);
|
||||
box-shadow: 0 12rpx 24rpx rgba(91, 86, 245, 0.24);
|
||||
}
|
||||
|
||||
.bottom-tip {
|
||||
margin-top: 4rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 12rpx;
|
||||
color: #8d94a5;
|
||||
font-size: 23rpx;
|
||||
line-height: 30rpx;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.tip-dot {
|
||||
width: 24rpx;
|
||||
height: 24rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border: 3rpx solid #8d94a5;
|
||||
border-radius: 50%;
|
||||
font-size: 16rpx;
|
||||
line-height: 18rpx;
|
||||
font-weight: 900;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.icon-placeholder {
|
||||
display: block;
|
||||
flex-shrink: 0;
|
||||
background: none;
|
||||
border: 0;
|
||||
box-shadow: none;
|
||||
transform: none;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"usingComponents": {
|
||||
"custom-nav": "/components/custom-nav/custom-nav"
|
||||
},
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
@@ -0,0 +1,301 @@
|
||||
import { taskinfo, uploadavatar, uploadrecord, checkavatar, checkvoice, saveHumanAssets } from "../../../utils/request"
|
||||
|
||||
const waveBars = [
|
||||
{ id: 'b1', cls: 'bar-22' },
|
||||
{ id: 'b2', cls: 'bar-34' },
|
||||
{ id: 'b3', cls: 'bar-48' },
|
||||
{ id: 'b4', cls: 'bar-34' },
|
||||
{ id: 'b5', cls: 'bar-62' },
|
||||
{ id: 'b6', cls: 'bar-42' },
|
||||
{ id: 'b7', cls: 'bar-70' },
|
||||
{ id: 'b8', cls: 'bar-52' },
|
||||
{ id: 'b9', cls: 'bar-38' },
|
||||
{ id: 'b10', cls: 'bar-58' },
|
||||
{ id: 'b11', cls: 'bar-46' },
|
||||
{ id: 'b12', cls: 'bar-30' },
|
||||
]
|
||||
const miniBars = [
|
||||
{ id: 'm1', cls: 'mini-bar-18' },
|
||||
{ id: 'm2', cls: 'mini-bar-30' },
|
||||
{ id: 'm3', cls: 'mini-bar-46' },
|
||||
{ id: 'm4', cls: 'mini-bar-28' },
|
||||
{ id: 'm5', cls: 'mini-bar-56' },
|
||||
{ id: 'm6', cls: 'mini-bar-36' },
|
||||
]
|
||||
|
||||
function formatRecordTime(totalSeconds: number) {
|
||||
const minutes = Math.floor(totalSeconds / 60)
|
||||
const seconds = totalSeconds % 60
|
||||
return `${String(minutes).padStart(2, '0')}:${String(seconds).padStart(2, '0')}`
|
||||
}
|
||||
|
||||
Page({
|
||||
recordTimer: 0,
|
||||
voiceCheckTimer: 0,
|
||||
|
||||
data: {
|
||||
isRecording: false,
|
||||
recordingClass: 'recording-active',
|
||||
elapsedSeconds: 0,
|
||||
recordTime: '00:00',
|
||||
waveBars,
|
||||
miniBars,
|
||||
taskinfo: null as any,
|
||||
avatar: '/static/images/my/image.png',
|
||||
avatarUrl: '',
|
||||
avatarChecked: false,
|
||||
recordUrl: '',
|
||||
recordDurationMs: 0,
|
||||
voiceAsrTaskId: '',
|
||||
voiceChecked: false,
|
||||
voiceText: '',
|
||||
voiceStatusText: ''
|
||||
},
|
||||
|
||||
|
||||
onLoad(ops: any) {
|
||||
taskinfo(ops.taskid).then((res: any) => {
|
||||
if (!res.code) {
|
||||
this.setData({ taskinfo: res.data });
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
onShow() {
|
||||
if (this.data.isRecording) {
|
||||
this.startRecordTimer()
|
||||
}
|
||||
},
|
||||
|
||||
onHide() {
|
||||
this.clearRecordTimer()
|
||||
this.clearVoiceCheckTimer()
|
||||
},
|
||||
|
||||
onUnload() {
|
||||
this.clearRecordTimer()
|
||||
this.clearVoiceCheckTimer()
|
||||
},
|
||||
|
||||
handleBack() {
|
||||
wx.navigateBack({
|
||||
fail: () => wx.navigateTo({ url: '/pages/aiPackage/preview/index' }),
|
||||
})
|
||||
},
|
||||
|
||||
handleUploadPhoto() {
|
||||
const that = this;
|
||||
wx.chooseImage({
|
||||
count: 1,
|
||||
success(res: any) {
|
||||
const file = res.tempFilePaths[0];
|
||||
wx.showLoading({ mask: true, title: '上传照片中' });
|
||||
uploadavatar(file, {}, '/api/upload/avatar').then((uploadRes: any) => {
|
||||
if (uploadRes.code) {
|
||||
wx.hideLoading();
|
||||
wx.showModal({ title: '温馨提示', content: uploadRes.message || '照片上传失败', showCancel: false })
|
||||
return;
|
||||
}
|
||||
|
||||
wx.showLoading({ mask: true, title: '人脸检测中' });
|
||||
checkavatar(uploadRes.data.url).then((checkRes: any) => {
|
||||
wx.hideLoading();
|
||||
if (!checkRes.code) {
|
||||
that.setData({ avatar: uploadRes.data.url, avatarUrl: uploadRes.data.url, avatarChecked: true })
|
||||
wx.showToast({ title: '照片检测通过', icon: 'success' })
|
||||
} else {
|
||||
that.setData({ avatarUrl: '', avatarChecked: false })
|
||||
wx.showModal({ title: '温馨提示', content: checkRes.message || '未检测到人脸', showCancel: false })
|
||||
}
|
||||
}).catch(() => {
|
||||
wx.hideLoading();
|
||||
that.setData({ avatarUrl: '', avatarChecked: false })
|
||||
wx.showModal({ title: '温馨提示', content: '人脸检测失败,请稍后再试', showCancel: false })
|
||||
})
|
||||
}).catch(() => {
|
||||
wx.hideLoading();
|
||||
wx.showModal({ title: '温馨提示', content: '网络异常,请稍后再试', showCancel: false })
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
handleUseDefaultAvatar() {
|
||||
wx.showToast({ title: '暂未配置默认形象', icon: 'none' })
|
||||
},
|
||||
|
||||
handleRecord() {
|
||||
if (this.data.isRecording) return
|
||||
|
||||
if (this.recordTimer) {
|
||||
clearTimeout(this.recordTimer);
|
||||
clearInterval(this.recordTimer);
|
||||
}
|
||||
|
||||
this.clearVoiceCheckTimer()
|
||||
this.recordTimer = 0;
|
||||
|
||||
this.setData({
|
||||
isRecording: true,
|
||||
recordTime: '00:00',
|
||||
elapsedSeconds: 0,
|
||||
recordingClass: 'recording-active',
|
||||
recordUrl: '',
|
||||
recordDurationMs: 0,
|
||||
voiceAsrTaskId: '',
|
||||
voiceChecked: false,
|
||||
voiceText: '',
|
||||
voiceStatusText: ''
|
||||
})
|
||||
this.startRecordTimer()
|
||||
},
|
||||
|
||||
handleUseDefaultVoice() {
|
||||
this.clearRecordTimer()
|
||||
this.clearVoiceCheckTimer()
|
||||
this.setData({ isRecording: false, recordingClass: '' })
|
||||
wx.showToast({ title: '暂未配置默认音色', icon: 'none' })
|
||||
},
|
||||
|
||||
handleStopRecord() {
|
||||
this.clearRecordTimer()
|
||||
this.recordTimer = 0;
|
||||
this.setData({ isRecording: false, recordingClass: '' })
|
||||
wx.getRecorderManager().stop()
|
||||
},
|
||||
|
||||
handleNext() {
|
||||
if (!this.data.taskinfo || !this.data.taskinfo.task_no) {
|
||||
wx.showModal({ title: '温馨提示', content: '创作记录不存在', showCancel: false })
|
||||
return
|
||||
}
|
||||
if (!this.data.avatarChecked || !this.data.avatarUrl) {
|
||||
wx.showModal({ title: '温馨提示', content: '请先上传并通过数字人照片检测', showCancel: false })
|
||||
return
|
||||
}
|
||||
if (!this.data.voiceChecked || !this.data.recordUrl || !this.data.voiceText) {
|
||||
wx.showModal({ title: '温馨提示', content: '请先录制并通过音色检测', showCancel: false })
|
||||
return
|
||||
}
|
||||
|
||||
wx.showLoading({ mask: true, title: '保存中' })
|
||||
saveHumanAssets({
|
||||
taskId: this.data.taskinfo.task_no,
|
||||
avatarUrl: this.data.avatarUrl,
|
||||
voiceUrl: this.data.recordUrl,
|
||||
voiceText: this.data.voiceText,
|
||||
durationMs: this.data.recordDurationMs,
|
||||
asrTaskId: this.data.voiceAsrTaskId
|
||||
}).then((res: any) => {
|
||||
wx.hideLoading()
|
||||
if (!res.code) {
|
||||
wx.redirectTo({ url: '/pages/aiPackage/bg/index?taskId=' + encodeURIComponent(this.data.taskinfo.task_no) })
|
||||
} else {
|
||||
wx.showModal({ title: '温馨提示', content: res.message || '保存失败', showCancel: false })
|
||||
}
|
||||
}).catch(() => {
|
||||
wx.hideLoading()
|
||||
wx.showModal({ title: '温馨提示', content: '网络异常,请稍后再试', showCancel: false })
|
||||
})
|
||||
},
|
||||
|
||||
startRecordTimer() {
|
||||
let that = this;
|
||||
that.clearRecordTimer()
|
||||
that.recordTimer = setInterval(() => {
|
||||
const elapsedSeconds = that.data.elapsedSeconds + 1
|
||||
that.setData({ elapsedSeconds, recordTime: formatRecordTime(elapsedSeconds) })
|
||||
}, 1000) as unknown as number
|
||||
|
||||
let recorder = wx.getRecorderManager();
|
||||
recorder.onError(that.onRecordError.bind(that));
|
||||
recorder.onStop(that.onRecordStop.bind(that))
|
||||
recorder.start({ duration: 10000, format: 'mp3' });
|
||||
},
|
||||
|
||||
onRecordError(err: any) {
|
||||
console.log(err)
|
||||
this.clearRecordTimer()
|
||||
this.setData({ isRecording: false, recordingClass: '' })
|
||||
wx.showModal({ title: '温馨提示', content: '录音失败,请重新录制', showCancel: false })
|
||||
},
|
||||
|
||||
onRecordStop(resource: { duration: number, fileSize: number, tempFilePath: string }) {
|
||||
this.clearRecordTimer()
|
||||
this.recordTimer = 0;
|
||||
this.setData({ isRecording: false, recordingClass: '', voiceStatusText: '录音上传中' })
|
||||
|
||||
wx.showLoading({ mask: true, title: '上传录音中' })
|
||||
uploadrecord(resource.tempFilePath).then((res: any) => {
|
||||
if (res.code) {
|
||||
wx.hideLoading()
|
||||
this.setData({ voiceStatusText: '', voiceChecked: false })
|
||||
wx.showModal({ title: '温馨提示', content: res.message || '录音上传失败', showCancel: false })
|
||||
return
|
||||
}
|
||||
|
||||
this.setData({
|
||||
recordUrl: res.data.url,
|
||||
recordDurationMs: res.data.durationMs || resource.duration || 0,
|
||||
voiceAsrTaskId: '',
|
||||
voiceChecked: false,
|
||||
voiceText: '',
|
||||
voiceStatusText: '录音识别中'
|
||||
})
|
||||
this.pollVoiceCheck('')
|
||||
}).catch(() => {
|
||||
wx.hideLoading()
|
||||
this.setData({ voiceStatusText: '', voiceChecked: false })
|
||||
wx.showModal({ title: '温馨提示', content: '网络异常,请稍后再试', showCancel: false })
|
||||
})
|
||||
},
|
||||
|
||||
pollVoiceCheck(asrTaskId: string) {
|
||||
checkvoice(this.data.recordUrl, asrTaskId).then((res: any) => {
|
||||
if (res.code === 200) {
|
||||
wx.hideLoading()
|
||||
const nextTaskId = res.data && res.data.asrTaskId ? res.data.asrTaskId : asrTaskId
|
||||
this.setData({ voiceAsrTaskId: nextTaskId, voiceStatusText: '录音识别中' })
|
||||
this.clearVoiceCheckTimer()
|
||||
this.voiceCheckTimer = setTimeout(() => {
|
||||
this.pollVoiceCheck(nextTaskId)
|
||||
}, 1500) as unknown as number
|
||||
return
|
||||
}
|
||||
|
||||
wx.hideLoading()
|
||||
if (!res.code) {
|
||||
this.clearVoiceCheckTimer()
|
||||
this.setData({
|
||||
voiceAsrTaskId: res.data.asrTaskId,
|
||||
voiceText: res.data.recognizedText,
|
||||
voiceChecked: true,
|
||||
voiceStatusText: '录音检测通过'
|
||||
})
|
||||
wx.showToast({ title: '音色检测通过', icon: 'success' })
|
||||
} else {
|
||||
this.clearVoiceCheckTimer()
|
||||
this.setData({ voiceChecked: false, voiceStatusText: '' })
|
||||
wx.showModal({ title: '温馨提示', content: res.message || '录音识别失败,请重新录制', showCancel: false })
|
||||
}
|
||||
}).catch(() => {
|
||||
wx.hideLoading()
|
||||
this.clearVoiceCheckTimer()
|
||||
this.setData({ voiceChecked: false, voiceStatusText: '' })
|
||||
wx.showModal({ title: '温馨提示', content: '录音识别失败,请稍后再试', showCancel: false })
|
||||
})
|
||||
},
|
||||
|
||||
clearRecordTimer() {
|
||||
if (!this.recordTimer) return
|
||||
clearInterval(this.recordTimer)
|
||||
this.recordTimer = 0
|
||||
},
|
||||
|
||||
clearVoiceCheckTimer() {
|
||||
if (!this.voiceCheckTimer) return
|
||||
clearTimeout(this.voiceCheckTimer)
|
||||
this.voiceCheckTimer = 0
|
||||
},
|
||||
})
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
<view class="record-page">
|
||||
<custom-nav content-height="86" padding-x="34">
|
||||
<view class="record-nav">
|
||||
<view class="nav-back" bindtap="handleBack"><text></text></view>
|
||||
<view class="nav-title-wrap">
|
||||
<text class="nav-title">设置数字人</text>
|
||||
<text class="nav-subtitle">上传照片和录音,生成你的专属数字人</text>
|
||||
</view>
|
||||
<view class="nav-space"></view>
|
||||
</view>
|
||||
</custom-nav>
|
||||
|
||||
<view class="record-content">
|
||||
<view class="panel photo-panel">
|
||||
<text class="panel-title">上传数字人照片</text>
|
||||
<view class="photo-body">
|
||||
<view class="photo-preview">
|
||||
<image class="portrait-bg icon-placeholder" src="{{ avatar }}" mode="aspectFit"></image>
|
||||
<view class="camera-badge"><image class="camera-icon icon-placeholder" style="width: 60%;height: 60%;" src="/static/images/carram_white.png" mode="aspectFit"></image></view>
|
||||
</view>
|
||||
|
||||
<view class="photo-actions">
|
||||
<view class="primary-small" bindtap="handleUploadPhoto">上传照片</view>
|
||||
<view class="ghost-small" bindtap="handleUseDefaultAvatar">使用默认形象</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="hint-row">
|
||||
<image class="hint-dot icon-placeholder" src="/static/images/zhuyi1.png" mode="aspectFit"></image>
|
||||
<text>建议上传清晰正脸照片,生成效果更自然</text>
|
||||
</view>
|
||||
<!-- <view wx:if="{{avatarChecked}}" class="asset-status success-status">照片检测通过</view> -->
|
||||
</view>
|
||||
|
||||
<view class="panel voice-panel">
|
||||
<text class="panel-title">录取专属音色</text>
|
||||
<view class="voice-body">
|
||||
<view class="voice-visual {{recordingClass}}">
|
||||
<view wx:if="{{isRecording}}" class="recording-pill"><text></text><text>录制中</text></view>
|
||||
<view class="wave-row wave-left">
|
||||
<text wx:for="{{waveBars}}" wx:key="id" class="{{item.cls}}"></text>
|
||||
</view>
|
||||
<view class="mic-wrap">
|
||||
<view class="pulse-ring ring-one"></view>
|
||||
<view class="pulse-ring ring-two"></view>
|
||||
<view class="pulse-ring ring-three"></view>
|
||||
<view class="mic-core">
|
||||
<image class="mic-icon icon-placeholder" style="width: 60%;height: 60%;" src="/static/images/mic.png" mode="aspectFit"></image>
|
||||
</view>
|
||||
</view>
|
||||
<view class="wave-row wave-right">
|
||||
<text wx:for="{{waveBars}}" wx:key="id" class="{{item.cls}}"></text>
|
||||
</view>
|
||||
<text class="record-time">{{recordTime}}</text>
|
||||
</view>
|
||||
|
||||
<view class="voice-actions">
|
||||
<view class="primary-small" wx:if="{{!isRecording}}" bindtap="handleRecord">录取音色</view>
|
||||
<view class="stop-small" wx:if="{{isRecording}}" bindtap="handleStopRecord">
|
||||
<image class="stop-dot icon-placeholder" style="width: 40rpx;height: 40rpx;" src="/static/images/stop.png" mode="aspectFit"></image>
|
||||
<text>停止录制</text>
|
||||
</view>
|
||||
<view class="ghost-small" bindtap="handleUseDefaultVoice">使用默认音色</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="hint-row voice-hint">
|
||||
<image class="hint-dot icon-placeholder" src="/static/images/zhuyi1.png" mode="aspectFit"></image>
|
||||
<text>建议录制 10 秒以上,环境安静效果更佳</text>
|
||||
</view>
|
||||
<!-- <view wx:if="{{voiceStatusText}}" class="asset-status {{voiceChecked ? 'success-status' : 'pending-status'}}">{{voiceStatusText}}</view> -->
|
||||
|
||||
<view class="script-section">
|
||||
<text class="script-title">朗读以下文案(约10秒)</text>
|
||||
<view class="script-card">
|
||||
<text>大家好,我是你的数字人口播助手。今天为大家带来一段精彩的内容介绍。</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="default-section">
|
||||
<text class="default-title">默认选项(可直接体验)</text>
|
||||
<view class="default-row">
|
||||
<view class="default-card">
|
||||
<image class="mini-avatar icon-placeholder" src="https://cdn.zhuangb123.com/chat-square/EB3D71A23725-6CD76-956EFD1DB-0C25B0.jpg" mode="aspectFit"></image>
|
||||
<text class="default-name">默认数字人</text>
|
||||
<text class="trial-pill">可直接体验</text>
|
||||
</view>
|
||||
<view class="default-card">
|
||||
<image class="mini-voice icon-placeholder" src="/static/images/ys.png" mode="aspectFit"></image>
|
||||
<text class="default-name">默认音色</text>
|
||||
<text class="trial-pill blue-pill">可直接体验</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="next-action" bindtap="handleNext">下一步:选择视频背景</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
|
||||
@@ -0,0 +1,668 @@
|
||||
page {
|
||||
min-height: 100vh;
|
||||
background: #f8faff;
|
||||
color: #111827;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
}
|
||||
|
||||
.record-page {
|
||||
width: 750rpx;
|
||||
min-height: 100vh;
|
||||
margin: 0 auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
box-sizing: border-box;
|
||||
background:
|
||||
radial-gradient(circle at 10% 0%, rgba(116, 98, 255, 0.08), transparent 34%),
|
||||
radial-gradient(circle at 88% 10%, rgba(73, 132, 255, 0.08), transparent 30%),
|
||||
linear-gradient(180deg, #fbfcff 0%, #f7f9ff 46%, #ffffff 100%);
|
||||
}
|
||||
|
||||
.record-nav {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.nav-back,
|
||||
.nav-space {
|
||||
width: 60rpx;
|
||||
height: 60rpx;
|
||||
flex: 0 0 60rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.nav-back text {
|
||||
width: 26rpx;
|
||||
height: 26rpx;
|
||||
display: block;
|
||||
border-left: 5rpx solid #111827;
|
||||
border-bottom: 5rpx solid #111827;
|
||||
transform: rotate(45deg);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.nav-title-wrap {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 10rpx;
|
||||
}
|
||||
|
||||
.nav-title {
|
||||
font-size: 34rpx;
|
||||
line-height: 40rpx;
|
||||
font-weight: 900;
|
||||
color: #111827;
|
||||
}
|
||||
|
||||
.nav-subtitle {
|
||||
max-width: 560rpx;
|
||||
color: #687086;
|
||||
font-size: 22rpx;
|
||||
line-height: 28rpx;
|
||||
font-weight: 600;
|
||||
text-align: center;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.record-content {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 22rpx;
|
||||
padding: 20rpx 32rpx 30rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.panel {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
border: 2rpx solid #e6e9ff;
|
||||
border-radius: 18rpx;
|
||||
background: rgba(255, 255, 255, 0.96);
|
||||
box-shadow: 0 14rpx 34rpx rgba(80, 92, 170, 0.08);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.photo-panel {
|
||||
padding: 24rpx 26rpx 24rpx;
|
||||
}
|
||||
|
||||
.panel-title {
|
||||
color: #111827;
|
||||
font-size: 28rpx;
|
||||
line-height: 36rpx;
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
.photo-body {
|
||||
margin-top: 14rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 56rpx;
|
||||
}
|
||||
|
||||
.photo-preview {
|
||||
width: 306rpx;
|
||||
height: 224rpx;
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
justify-content: center;
|
||||
border: 2rpx solid #dce1ff;
|
||||
border-radius: 14rpx;
|
||||
background: linear-gradient(180deg, #f8fbff 0%, #eef3ff 100%);
|
||||
overflow: hidden;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.portrait-bg {
|
||||
width: 190rpx;
|
||||
height: 218rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.portrait-head {
|
||||
width: 120rpx;
|
||||
height: 138rpx;
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
justify-content: center;
|
||||
border-radius: 60rpx 60rpx 44rpx 44rpx;
|
||||
background: linear-gradient(160deg, #2e1e19 0%, #684235 56%, #9c6a58 100%);
|
||||
box-shadow: 0 4rpx 12rpx rgba(85, 50, 44, 0.18);
|
||||
}
|
||||
|
||||
.face {
|
||||
width: 78rpx;
|
||||
height: 98rpx;
|
||||
margin-bottom: 10rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 8rpx;
|
||||
border-radius: 42rpx 42rpx 36rpx 36rpx;
|
||||
background: linear-gradient(180deg, #ffe8dc 0%, #ffd0c2 100%);
|
||||
}
|
||||
|
||||
.eye-row {
|
||||
width: 48rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.eye-row text {
|
||||
width: 8rpx;
|
||||
height: 8rpx;
|
||||
border-radius: 50%;
|
||||
background: #251918;
|
||||
}
|
||||
|
||||
.nose {
|
||||
width: 8rpx;
|
||||
height: 12rpx;
|
||||
border-radius: 8rpx;
|
||||
background: rgba(196, 116, 101, 0.46);
|
||||
}
|
||||
|
||||
.mouth {
|
||||
width: 24rpx;
|
||||
height: 7rpx;
|
||||
border-radius: 0 0 16rpx 16rpx;
|
||||
background: #ca6975;
|
||||
}
|
||||
|
||||
.hair,
|
||||
.hair-main {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.portrait-neck {
|
||||
width: 32rpx;
|
||||
height: 22rpx;
|
||||
background: #ffd3c4;
|
||||
}
|
||||
|
||||
.portrait-cloth {
|
||||
width: 178rpx;
|
||||
height: 68rpx;
|
||||
border-radius: 40rpx 40rpx 0 0;
|
||||
background: linear-gradient(120deg, #ffffff 0%, #f7f6f2 50%, #ffffff 100%);
|
||||
}
|
||||
|
||||
.camera-badge {
|
||||
width: 60rpx;
|
||||
height: 60rpx;
|
||||
/* margin-bottom: 20rpx; */
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border: 4rpx solid rgba(255, 255, 255, 0.88);
|
||||
border-radius: 50%;
|
||||
background: rgba(66, 56, 49, 0.72);
|
||||
box-sizing: border-box;
|
||||
flex: 0 0 60rpx;
|
||||
position: absolute;
|
||||
bottom: 20rpx;
|
||||
}
|
||||
|
||||
.camera-icon {
|
||||
width: 28rpx;
|
||||
height: 21rpx;
|
||||
border: 4rpx solid #ffffff;
|
||||
border-radius: 5rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.camera-icon::after {
|
||||
content: '';
|
||||
width: 8rpx;
|
||||
height: 8rpx;
|
||||
margin: 2rpx auto 0;
|
||||
display: block;
|
||||
border: 3rpx solid #ffffff;
|
||||
border-radius: 50%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.photo-actions,
|
||||
.voice-actions {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 24rpx;
|
||||
}
|
||||
|
||||
.primary-small,
|
||||
.ghost-small,
|
||||
.stop-small {
|
||||
height: 70rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 16rpx;
|
||||
font-size: 26rpx;
|
||||
line-height: 32rpx;
|
||||
font-weight: 900;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.primary-small {
|
||||
color: #ffffff;
|
||||
background: linear-gradient(100deg, #4e84ff 0%, #7d3ff3 100%);
|
||||
box-shadow: 0 12rpx 24rpx rgba(91, 86, 245, 0.22);
|
||||
}
|
||||
|
||||
.ghost-small,
|
||||
.stop-small {
|
||||
border: 2rpx solid #d9dcf2;
|
||||
background: #fafbff;
|
||||
color: #596083;
|
||||
}
|
||||
|
||||
.hint-row {
|
||||
margin-top: 18rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8rpx;
|
||||
color: #7a8196;
|
||||
font-size: 21rpx;
|
||||
line-height: 28rpx;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.hint-dot {
|
||||
width: 18rpx;
|
||||
height: 18rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 50%;
|
||||
background: #b9bfd2;
|
||||
color: #ffffff;
|
||||
font-size: 12rpx;
|
||||
line-height: 16rpx;
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
.voice-panel {
|
||||
padding: 24rpx 26rpx 24rpx;
|
||||
}
|
||||
|
||||
.voice-body {
|
||||
margin-top: 12rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 32rpx;
|
||||
}
|
||||
|
||||
.voice-visual {
|
||||
width: 340rpx;
|
||||
min-height: 240rpx;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.recording-pill {
|
||||
width: 116rpx;
|
||||
height: 44rpx;
|
||||
margin-right: 224rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 10rpx;
|
||||
border-radius: 22rpx;
|
||||
color: #ffffff;
|
||||
background: linear-gradient(90deg, #7380ff 0%, #8a55ed 100%);
|
||||
box-shadow: 0 8rpx 18rpx rgba(117, 94, 239, 0.3);
|
||||
font-size: 21rpx;
|
||||
line-height: 26rpx;
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
.recording-pill text:first-child {
|
||||
width: 12rpx;
|
||||
height: 12rpx;
|
||||
border-radius: 50%;
|
||||
background: #ffffff;
|
||||
}
|
||||
|
||||
.recording-active .recording-pill text:first-child {
|
||||
animation: blinkDot 1s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.wave-row {
|
||||
width: 118rpx;
|
||||
height: 82rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 7rpx;
|
||||
}
|
||||
|
||||
.wave-row text {
|
||||
width: 5rpx;
|
||||
border-radius: 6rpx;
|
||||
background: linear-gradient(180deg, #5f86ff 0%, #bd67f2 100%);
|
||||
transform-origin: center;
|
||||
}
|
||||
|
||||
.recording-active .wave-row text:nth-child(2n) {
|
||||
animation: waveScaleA 0.78s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.recording-active .wave-row text:nth-child(2n + 1) {
|
||||
animation: waveScaleB 0.92s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.recording-active .wave-row text:nth-child(3n) {
|
||||
animation-delay: 0.18s;
|
||||
}
|
||||
|
||||
.mic-wrap {
|
||||
width: 98rpx;
|
||||
height: 98rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 50%;
|
||||
background: radial-gradient(circle, rgba(139, 102, 255, 0.13) 0%, rgba(139, 102, 255, 0.05) 68%, transparent 70%);
|
||||
}
|
||||
|
||||
.pulse-ring {
|
||||
width: 90rpx;
|
||||
height: 90rpx;
|
||||
margin-right: -90rpx;
|
||||
border: 3rpx solid rgba(135, 98, 247, 0.28);
|
||||
border-radius: 50%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.recording-active .ring-one { animation: pulseRing 1.5s ease-out infinite; }
|
||||
.recording-active .ring-two { animation: pulseRing 1.5s ease-out 0.3s infinite; }
|
||||
.recording-active .ring-three { animation: pulseRing 1.5s ease-out 0.6s infinite; }
|
||||
|
||||
.mic-core {
|
||||
width: 90rpx;
|
||||
height: 90rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 50%;
|
||||
background: linear-gradient(160deg, #77a0ff 0%, #8346f5 100%);
|
||||
box-shadow: 0 10rpx 24rpx rgba(117, 86, 243, 0.32);
|
||||
}
|
||||
|
||||
.mic-icon {
|
||||
width: 32rpx;
|
||||
height: 45rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.mic-icon::before {
|
||||
content: '';
|
||||
width: 24rpx;
|
||||
height: 34rpx;
|
||||
border-radius: 14rpx;
|
||||
background: #ffffff;
|
||||
}
|
||||
|
||||
.mic-icon text {
|
||||
width: 34rpx;
|
||||
height: 14rpx;
|
||||
display: block;
|
||||
border-bottom: 5rpx solid #ffffff;
|
||||
border-left: 5rpx solid #ffffff;
|
||||
border-right: 5rpx solid #ffffff;
|
||||
border-radius: 0 0 18rpx 18rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.record-time {
|
||||
width: 100%;
|
||||
margin-top: 2rpx;
|
||||
color: #586085;
|
||||
font-size: 31rpx;
|
||||
line-height: 38rpx;
|
||||
font-weight: 600;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.stop-small {
|
||||
gap: 16rpx;
|
||||
}
|
||||
|
||||
.stop-dot {
|
||||
width: 16rpx;
|
||||
height: 16rpx;
|
||||
border-radius: 3rpx;
|
||||
background: #ff6b6b;
|
||||
}
|
||||
|
||||
.voice-hint {
|
||||
margin-top: 8rpx;
|
||||
}
|
||||
|
||||
.script-section {
|
||||
margin-top: 24rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12rpx;
|
||||
}
|
||||
|
||||
.script-title {
|
||||
color: #111827;
|
||||
font-size: 24rpx;
|
||||
line-height: 32rpx;
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
.script-card {
|
||||
min-height: 92rpx;
|
||||
padding: 18rpx 22rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border: 2rpx solid #dfe3ff;
|
||||
border-radius: 10rpx;
|
||||
background: linear-gradient(180deg, #fbfbff 0%, #f6f7ff 100%);
|
||||
box-sizing: border-box;
|
||||
color: #4d557d;
|
||||
font-size: 24rpx;
|
||||
line-height: 36rpx;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.default-section {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12rpx;
|
||||
}
|
||||
|
||||
.default-title {
|
||||
color: #4f47ff;
|
||||
font-size: 23rpx;
|
||||
line-height: 30rpx;
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
.default-row {
|
||||
display: flex;
|
||||
gap: 10rpx;
|
||||
}
|
||||
|
||||
.default-card {
|
||||
flex: 1;
|
||||
height: 88rpx;
|
||||
min-width: 0;
|
||||
padding: 10rpx 12rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12rpx;
|
||||
border: 2rpx solid #e4e7f6;
|
||||
border-radius: 14rpx;
|
||||
background: rgba(255, 255, 255, 0.94);
|
||||
box-shadow: 0 10rpx 24rpx rgba(80, 92, 170, 0.08);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.mini-avatar {
|
||||
width: 58rpx;
|
||||
height: 58rpx;
|
||||
border-radius: 12rpx;
|
||||
background:
|
||||
radial-gradient(circle at 50% 32%, #ffe0d2 0 16rpx, transparent 17rpx),
|
||||
radial-gradient(circle at 50% 35%, #4b2d25 0 24rpx, transparent 25rpx),
|
||||
linear-gradient(180deg, #eef4ff 0%, #ffffff 100%);
|
||||
flex: 0 0 58rpx;
|
||||
}
|
||||
|
||||
.mini-voice {
|
||||
width: 58rpx;
|
||||
height: 58rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 5rpx;
|
||||
border-radius: 12rpx;
|
||||
background: #eef2ff;
|
||||
flex: 0 0 58rpx;
|
||||
}
|
||||
|
||||
.mini-voice text {
|
||||
width: 5rpx;
|
||||
border-radius: 5rpx;
|
||||
background: linear-gradient(180deg, #5f86ff 0%, #8550f2 100%);
|
||||
}
|
||||
|
||||
.default-name {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
color: #111827;
|
||||
font-size: 23rpx;
|
||||
line-height: 30rpx;
|
||||
font-weight: 900;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.trial-pill {
|
||||
padding: 6rpx 12rpx;
|
||||
border-radius: 18rpx;
|
||||
background: #fff3db;
|
||||
color: #f4a326;
|
||||
font-size: 18rpx;
|
||||
line-height: 22rpx;
|
||||
font-weight: 800;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.blue-pill {
|
||||
background: #e9f3ff;
|
||||
color: #5a96f0;
|
||||
}
|
||||
|
||||
.next-action {
|
||||
height: 78rpx;
|
||||
margin-top: -2rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 16rpx;
|
||||
color: #ffffff;
|
||||
background: linear-gradient(100deg, #4e84ff 0%, #7d3ff3 100%);
|
||||
box-shadow: 0 12rpx 24rpx rgba(91, 86, 245, 0.24);
|
||||
font-size: 31rpx;
|
||||
line-height: 38rpx;
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
@keyframes waveScaleA {
|
||||
0%, 100% { transform: scaleY(0.62); opacity: 0.62; }
|
||||
50% { transform: scaleY(1.18); opacity: 1; }
|
||||
}
|
||||
|
||||
@keyframes waveScaleB {
|
||||
0%, 100% { transform: scaleY(1); opacity: 0.88; }
|
||||
50% { transform: scaleY(0.55); opacity: 0.55; }
|
||||
}
|
||||
|
||||
@keyframes pulseRing {
|
||||
0% { transform: scale(0.72); opacity: 0.7; }
|
||||
100% { transform: scale(1.72); opacity: 0; }
|
||||
}
|
||||
|
||||
@keyframes blinkDot {
|
||||
0%, 100% { opacity: 1; transform: scale(1); }
|
||||
50% { opacity: 0.38; transform: scale(0.72); }
|
||||
}
|
||||
|
||||
.bar-22 { height: 22rpx; }
|
||||
.bar-30 { height: 30rpx; }
|
||||
.bar-34 { height: 34rpx; }
|
||||
.bar-38 { height: 38rpx; }
|
||||
.bar-42 { height: 42rpx; }
|
||||
.bar-46 { height: 46rpx; }
|
||||
.bar-48 { height: 48rpx; }
|
||||
.bar-52 { height: 52rpx; }
|
||||
.bar-58 { height: 58rpx; }
|
||||
.bar-62 { height: 62rpx; }
|
||||
.bar-70 { height: 70rpx; }
|
||||
|
||||
.mini-bar-18 { height: 18rpx; }
|
||||
.mini-bar-28 { height: 28rpx; }
|
||||
.mini-bar-30 { height: 30rpx; }
|
||||
.mini-bar-36 { height: 36rpx; }
|
||||
.mini-bar-46 { height: 46rpx; }
|
||||
.mini-bar-56 { height: 56rpx; }
|
||||
|
||||
.icon-placeholder {
|
||||
display: block;
|
||||
flex-shrink: 0;
|
||||
background: none;
|
||||
border: 0;
|
||||
box-shadow: none;
|
||||
transform: none;
|
||||
}
|
||||
|
||||
.asset-status {
|
||||
margin-top: 14rpx;
|
||||
height: 44rpx;
|
||||
padding: 0 18rpx;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
align-self: flex-start;
|
||||
border-radius: 22rpx;
|
||||
font-size: 21rpx;
|
||||
line-height: 28rpx;
|
||||
font-weight: 800;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.success-status {
|
||||
color: #16854f;
|
||||
background: #e9f8f0;
|
||||
border: 2rpx solid #bdebd3;
|
||||
}
|
||||
|
||||
.pending-status {
|
||||
color: #5a5f89;
|
||||
background: #f1f3ff;
|
||||
border: 2rpx solid #dfe3ff;
|
||||
}
|
||||
Reference in New Issue
Block a user