This commit is contained in:
2026-07-10 16:14:31 +08:00
commit 637b0bd144
158 changed files with 33269 additions and 0 deletions
@@ -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;
}