Commit 0e03ee3703f6659d671ecdcc87067b6dc95ea28a

Authored by xwenliang
1 parent 91161957

ffeat: 接入激励广告能力

... ... @@ -161,6 +161,14 @@ App({
161 161 success: (resp) => {
162 162 if (resp.data.code === 2000000) {
163 163 resolve(resp.data.data.url);
  164 + } else if (resp.data.code === 5000014) {
  165 + // 次数用完,显示广告弹窗
  166 + const pages = getCurrentPages();
  167 + const currentPage = pages[pages.length - 1];
  168 + if (currentPage && currentPage.showLimitDialog) {
  169 + currentPage.showLimitDialog();
  170 + }
  171 + reject(new Error(resp.data.msg || '次数已用完'));
164 172 } else {
165 173 wx.showToast({
166 174 title: resp.data.msg || '生成失败',
... ...
pages/index/index.js
... ... @@ -5,6 +5,7 @@ const typeList = app.globalData.getTypeList();
5 5 const selectedIndex = typeList.length > 1 ? app.globalData.getSelectedTypeIndex() : 0;
6 6  
7 7 let audio = null;
  8 +let videoAd = null;
8 9  
9 10 Page({
10 11 data: {
... ... @@ -15,6 +16,118 @@ Page({
15 16 },
16 17 onLoad(){
17 18 wx.showShareMenu();
  19 + this.initVideoAd();
  20 + },
  21 +
  22 + // 初始化激励视频广告
  23 + initVideoAd() {
  24 + // 若在开发者工具中无法预览广告,请切换开发者工具中的基础库版本
  25 + if (wx.createRewardedVideoAd) {
  26 + videoAd = wx.createRewardedVideoAd({
  27 + adUnitId: 'adunit-aedf0933f69de926'
  28 + });
  29 +
  30 + videoAd.onLoad(() => {
  31 + console.log('激励视频广告加载成功');
  32 + });
  33 +
  34 + videoAd.onError((err) => {
  35 + console.error('激励视频广告加载失败', err);
  36 + });
  37 +
  38 + videoAd.onClose((res) => {
  39 + if (res && res.isEnded) {
  40 + // 用户看完广告,重置使用次数
  41 + this.resetTtsCount();
  42 + } else {
  43 + // 用户中途退出
  44 + wx.showToast({
  45 + title: '请看完广告获取次数',
  46 + icon: 'none'
  47 + });
  48 + }
  49 + });
  50 + }
  51 + },
  52 +
  53 + // 显示激励视频广告
  54 + showVideoAd() {
  55 + if (videoAd) {
  56 + videoAd.show().catch(() => {
  57 + // 失败重试
  58 + videoAd.load()
  59 + .then(() => videoAd.show())
  60 + .catch(err => {
  61 + console.error('激励视频广告显示失败', err);
  62 + wx.showToast({
  63 + title: '广告加载失败,请稍后重试',
  64 + icon: 'none'
  65 + });
  66 + });
  67 + });
  68 + } else {
  69 + wx.showToast({
  70 + title: '广告功能暂不可用',
  71 + icon: 'none'
  72 + });
  73 + }
  74 + },
  75 +
  76 + // 重置TTS使用次数
  77 + async resetTtsCount() {
  78 + wx.showLoading({
  79 + title: '正在重置次数...',
  80 + mask: true
  81 + });
  82 +
  83 + try {
  84 + const result = await new Promise((resolve, reject) => {
  85 + app.request({
  86 + url: `${app.globalData.domain}/open-api/wx330e54aa6000516d/tts-count-reset`,
  87 + success(res) {
  88 + resolve(res.data);
  89 + },
  90 + fail(err) {
  91 + reject(err);
  92 + }
  93 + });
  94 + });
  95 +
  96 + wx.hideLoading();
  97 +
  98 + if (result.code === 2000000) {
  99 + wx.showToast({
  100 + title: '获得10次使用机会!',
  101 + icon: 'success'
  102 + });
  103 + } else {
  104 + wx.showToast({
  105 + title: result.msg || '重置失败',
  106 + icon: 'none'
  107 + });
  108 + }
  109 + } catch (error) {
  110 + wx.hideLoading();
  111 + wx.showToast({
  112 + title: '网络错误',
  113 + icon: 'none'
  114 + });
  115 + }
  116 + },
  117 +
  118 + // 显示次数用完弹窗
  119 + showLimitDialog() {
  120 + wx.showModal({
  121 + title: '使用次数已用完',
  122 + content: '今日免费次数已用完,观看广告可获得额外10次使用机会',
  123 + confirmText: '观看广告',
  124 + cancelText: '明日再试',
  125 + success: (res) => {
  126 + if (res.confirm) {
  127 + this.showVideoAd();
  128 + }
  129 + }
  130 + });
18 131 },
19 132 inputText(e){
20 133 this.data.text = e.detail.value;
... ...
pages/index/index.wxml
... ... @@ -28,5 +28,5 @@
28 28 > {{item.desc}} </button>
29 29 </view>
30 30 </view>
31   -<ad class="ad-1" unit-id="adunit-34f63a98428c1660"></ad>
32   -<ad class="ad-2" unit-id="adunit-80a27ecf9a35c553"></ad>
33 31 \ No newline at end of file
  32 +<!--ad class="ad-1" unit-id="adunit-34f63a98428c1660"></ad>
  33 +<ad class="ad-2" unit-id="adunit-80a27ecf9a35c553"></ad-->
34 34 \ No newline at end of file
... ...
pages/index/index.wxss
1 1 /**index.wxss**/
2 2  
  3 +/* 防止横向滚动 */
  4 +page {
  5 + width: 100%;
  6 + overflow-x: hidden;
  7 + box-sizing: border-box;
  8 +}
  9 +
  10 +/* 全局移除按钮边框 */
  11 +button {
  12 + border: none !important;
  13 + outline: none !important;
  14 +}
  15 +
  16 +button::after {
  17 + border: none !important;
  18 +}
  19 +
  20 +button::before {
  21 + border: none !important;
  22 +}
  23 +
  24 +.container {
  25 + width: 100%;
  26 + max-width: 100vw;
  27 + overflow-x: hidden;
  28 + box-sizing: border-box;
  29 + padding: 20rpx;
  30 +}
  31 +
3 32 .text-view{
4 33 width: 100%;
5 34 margin-bottom: 20rpx;
6 35 text-align: center;
  36 + box-sizing: border-box;
7 37 }
8 38 .text-area{
9   - width: 95%;
10   - padding: 5rpx 10rpx;
  39 + width: 100%;
  40 + max-width: 100%;
  41 + padding: 20rpx;
11 42 text-align: left;
12 43 box-sizing: border-box;
13   - display: inline-block;
14   - border: 1px dashed #afafaf;
  44 + display: block;
  45 + border: none;
  46 + border-radius: 16rpx;
  47 + background-color: #fafafa;
  48 + font-size: 32rpx;
  49 + line-height: 1.5;
  50 + transition: all 0.3s ease;
  51 + box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.08);
  52 +}
  53 +.text-area:focus {
  54 + background-color: #ffffff;
  55 + box-shadow: 0 4rpx 20rpx rgba(0, 122, 255, 0.15);
15 56 }
16 57  
17 58 .button-view{
18 59 width: 100%;
19 60 margin-bottom: 40rpx;
20 61 text-align: center;
  62 + box-sizing: border-box;
21 63 }
  64 +
  65 +/* 主要按钮样式 */
22 66 .button-view button{
23   - width: 95%;
24   - display: inline-block;
25   - vertical-align: top;
  67 + width: 100%;
  68 + max-width: 100%;
  69 + display: block;
26 70 margin-bottom: 20rpx;
27   - height: 92rpx;
28   - line-height: 92rpx;
29   - font-size: 36rpx;
  71 + height: 88rpx;
  72 + line-height: 88rpx;
  73 + font-size: 32rpx;
30 74 text-align: center;
  75 + border-radius: 44rpx;
  76 + border: none !important;
  77 + font-weight: 600;
  78 + letter-spacing: 2rpx;
  79 + transition: all 0.3s ease;
  80 + position: relative;
  81 + overflow: hidden;
  82 + box-sizing: border-box;
  83 +}
  84 +
  85 +.button-view button::after {
  86 + border: none !important;
  87 +}
  88 +
  89 +.button-view button::before {
  90 + border: none !important;
  91 +}
  92 +
  93 +/* 播放按钮 - 主要操作 */
  94 +.button-view button[bindtap="play"] {
  95 + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  96 + color: white;
  97 + box-shadow: 0 8rpx 24rpx rgba(102, 126, 234, 0.4), inset 0 2rpx 0 rgba(255, 255, 255, 0.2);
  98 +}
  99 +
  100 +.button-view button[bindtap="play"]:active {
  101 + transform: translateY(2rpx);
  102 + box-shadow: 0 4rpx 12rpx rgba(102, 126, 234, 0.4);
  103 +}
  104 +
  105 +/* 下载按钮 - 次要操作 */
  106 +.goto-audio-list {
  107 + background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
  108 + color: white;
  109 + box-shadow: 0 8rpx 24rpx rgba(240, 147, 251, 0.4), inset 0 2rpx 0 rgba(255, 255, 255, 0.2);
  110 +}
  111 +
  112 +.goto-audio-list:active {
  113 + transform: translateY(2rpx);
  114 + box-shadow: 0 4rpx 12rpx rgba(240, 147, 251, 0.4);
31 115 }
32 116  
  117 +/* 清空按钮 - 辅助操作 */
  118 +.button-view button[bindtap="clear"] {
  119 + background: linear-gradient(135deg, #ffecd2 0%, #fcb69f 100%);
  120 + color: #8b4513;
  121 + box-shadow: 0 8rpx 24rpx rgba(252, 182, 159, 0.4), inset 0 2rpx 0 rgba(255, 255, 255, 0.3);
  122 +}
  123 +
  124 +.button-view button[bindtap="clear"]:active {
  125 + transform: translateY(2rpx);
  126 + box-shadow: 0 4rpx 12rpx rgba(252, 182, 159, 0.4);
  127 +}
  128 +
  129 +/* 语音类型选择区域 */
33 130 .type-view{
34   - width: 95%;
35   - margin-bottom: 40rpx;
36   - display: flex;
37   - justify-content: space-between;
  131 + width: 100%;
  132 + max-width: 100%;
  133 + margin: 0 0 40rpx 0;
  134 + padding: 20rpx;
  135 + background: linear-gradient(135deg, rgba(255, 255, 255, 0.95) 0%, rgba(248, 250, 252, 0.95) 100%);
  136 + border-radius: 20rpx;
  137 + box-shadow: 0 6rpx 24rpx rgba(0, 0, 0, 0.08);
  138 + backdrop-filter: blur(10rpx);
  139 + box-sizing: border-box;
38 140 }
  141 +
39 142 .type-view button{
40   - padding: 20rpx 10rpx;
41   - writing-mode: vertical-lr;
  143 + width: 100%;
  144 + max-width: 100%;
  145 + height: 60rpx;
  146 + margin-bottom: 16rpx;
  147 + padding: 0 20rpx;
  148 + writing-mode: horizontal-tb;
42 149 text-align: center;
43   - letter-spacing: 15rpx;
  150 + letter-spacing: 1rpx;
  151 + font-size: 28rpx;
  152 + font-weight: 500;
  153 + border-radius: 30rpx;
  154 + border: none !important;
  155 + transition: all 0.3s ease;
  156 + position: relative;
  157 + overflow: hidden;
  158 + display: flex;
  159 + align-items: center;
  160 + justify-content: center;
  161 + white-space: nowrap;
  162 + box-sizing: border-box;
  163 +}
  164 +
  165 +.type-view button::after {
  166 + border: none !important;
  167 +}
  168 +
  169 +.type-view button::before {
  170 + border: none !important;
44 171 }
  172 +
  173 +.type-view button:last-child {
  174 + margin-bottom: 0;
  175 +}
  176 +
  177 +/* 未选中的语音类型按钮 */
  178 +.type-view button[type="default"] {
  179 + background: linear-gradient(135deg, #ffffff 0%, #f8f9fa 100%);
  180 + color: #495057;
  181 + box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1), inset 0 1rpx 0 rgba(255, 255, 255, 0.8);
  182 +}
  183 +
  184 +.type-view button[type="default"]:active {
  185 + background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
  186 + transform: translateY(2rpx);
  187 + box-shadow: 0 2rpx 6rpx rgba(0, 0, 0, 0.15), inset 0 1rpx 0 rgba(255, 255, 255, 0.6);
  188 +}
  189 +
  190 +/* 选中的语音类型按钮 */
  191 +.type-view button[type="primary"] {
  192 + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  193 + color: white;
  194 + box-shadow: 0 6rpx 20rpx rgba(102, 126, 234, 0.4), inset 0 1rpx 0 rgba(255, 255, 255, 0.2);
  195 + transform: scale(1.02);
  196 +}
  197 +
  198 +.type-view button[type="primary"]:active {
  199 + transform: scale(1.02) translateY(2rpx);
  200 + box-shadow: 0 4rpx 16rpx rgba(102, 126, 234, 0.5), inset 0 1rpx 0 rgba(255, 255, 255, 0.1);
  201 +}
  202 +
  203 +/* 按钮悬浮效果动画 */
  204 +.button-view button::before,
  205 +.type-view button::before {
  206 + content: '';
  207 + position: absolute;
  208 + top: 0;
  209 + left: -100%;
  210 + width: 100%;
  211 + height: 100%;
  212 + background: linear-gradient(90deg, transparent, rgba(255,255,255,0.2), transparent);
  213 + transition: left 0.5s;
  214 +}
  215 +
  216 +.button-view button:active::before,
  217 +.type-view button:active::before {
  218 + left: 100%;
  219 +}
  220 +
45 221 .ad-1{
46 222 margin-bottom: 20rpx;
47 223 }
48 224 \ No newline at end of file
... ...
pages/result/result.wxml
1   -<view class="ad-placeholder">
  1 +<!--view class="ad-placeholder">
2 2 <ad unit-id="adunit-0a991618c53a4445" class="ad-3"></ad>
3   -</view>
  3 +</view-->
4 4 <view
5 5 class="text-view"
6 6 wx:for="{{audioList}}"
... ...