feat: add virtual resource payments and optimize images

This commit is contained in:
王鹏
2026-07-28 13:35:23 +08:00
parent ab281be02a
commit d14f005d34
35 changed files with 462 additions and 2125 deletions

View File

@@ -1,7 +1,7 @@
## 简介
目前实现个人博客资源收集下载网盘短剧视频链接分享手机壁纸下载电脑壁纸下载头像下载,支持 100+ 热门平台的图片视频水印去除,这些内容展示均已实现小程序流量主功能,可根据自己需要进行配置,
目前实现个人博客资源收集下载网盘短剧视频链接分享手机壁纸下载电脑壁纸下载头像下载,这些内容展示均已实现小程序流量主功能,可根据自己需要进行配置,
另外还加入了积分系统以及积分任务和积分商店,可让用户完成相应的任务获得积分换取奖励,源码无保留可二次开发,话不多说看图最重要。

159
README.md
View File

@@ -1,140 +1,37 @@
<p align="center">
<img alt="logo" src="https://img.eplusskin.com/uploads/20240730/log.png">
</p>
<h1 align="center" style="margin: 30px 0 30px; font-weight: bold;">依沫博客资源</h1>
<h4 align="center">基于UniApp开发</h4>
<p align="center">
<img src="https://img.shields.io/github/license/mashape/apistatus.svg">
</p>
# 南音博客 (依沫博客)
## 平台简介
这是一个基于 **uni-app (Vue 2)****uView UI** 框架开发的微信小程序/多端应用项目。
本项目是一个功能丰富的资源分享类博客系统,包含完善的用户体系和商业化/积分玩法,集成了“文章阅读 + 资源/壁纸下载 + 短剧观看 + 积分商城 + 抽奖活动 + 支付充值”的综合性内容变现功能。
依沫博客资源变现专为内容资源下载场景设计,一站式解决内容带货、流量、资源变现,资源博客文章分享难题,目前以实现个人博客,文章发表,资源收集下载,网盘短剧视频链接分享,手机壁纸下载,电脑壁纸下载,头像下载,支持抖音,快手,小红书等 100+ 平台的图片视频水印去除,这些内容展示均已实现微信小程序流量主广告变现功能,可根据自己需要进行配置,
另外还加入了积分系统以及积分任务和积分商店,可让用户完成相应的任务获得积分换取奖励,源码无保留可二次开发。
## 核心功能模块
* 应用框架基于[uniapp](https://uniapp.dcloud.net.cn/)支持小程序、H5、Android和IOS。流量主流量变现广告目前只支持微信小程序
* 前端组件采用[uni-ui](https://github.com/dcloudio/uni-ui)全端兼容的高性能UI框架
* 阿里云服务器免费试用3个月新老用户同享 99/年:[点我进入](https://www.aliyun.com/daily-act/ecs/activity_selection?userCode=ua4mkdxk)
* 需要后端代码请打开微信搜索公众号关注 "依沫资源网" 或微信扫面下方二维码关注微信公众号发送 "依沫博客后端源码" 即可获取
### 1. 文章与博客系统
- **文章流与详情**:支持文章列表查询与详情展示。
- **富文本与代码高亮**:内置 `mp-html` 组件,集成 `marked``prismjs`,完美支持 Markdown 渲染和代码高亮展示。
- **互动功能**:支持文章点赞和阅读量统计。
<img src="https://img.yidaima.cn/%E5%B0%8F%E7%A8%8B%E5%BA%8F/gongzhonghao.jpg" alt="公众号"/>
### 2. 资源与壁纸分享
- **资源系统**:提供虚拟资源的展示与详情查看,支持消耗积分兑换并下载资源。
- **壁纸系统**:提供壁纸列表浏览及高清图片下载功能。
## 技术文档
### 3. 短剧模块
- 提供当前热门短剧资源的列表浏览及观看体验。
[//]: # (<img src="https://img.eplusskin.com/uploads/20240730/1715928722339.png"> QQ 1149297946 或 微信yimoziyuan666)
- 运行之前请安装uview-ui组件依赖可打开项目根目录运行 cmd 输入 npm install uview-ui
- 如需微信小程序运行或实现微信流量主小程序流量变现请修改 manifest.json 微信小程序的AppID以及在后台管理端的App配置项配置自己的广告id
- 打开微信扫描下面的小程序码即可体验小程序
### 4. 积分与商城经济系统
- **积分获取**:包含每日签到、积分新增记录、积分明细查看。
- **充值与支付**:支持创建充值订单,并更新用户积分余额。
- **积分商城**:用户可使用积分兑换实物商品或虚拟资源,并支持查看兑换记录。
<img src="https://img.eplusskin.com/uploads/20240730/miniapp.jpg" alt="小程序演示"/>
### 5. 抽奖系统
- 内置抽奖玩法,包含抽奖次数校验、概率生成、奖品配置查看、奖励发放以及抽奖记录展示。
## 故障排除
### uni-search-bar 组件路径错误
如果在编译时遇到以下错误:
```
pages/search/index.json: ["usingComponents"]["uni-search-bar"]: "/node-modules/uni_modules/uni-search-bar/components/uni-search-bar/uni-search-bar",在 D:/codes/git/yimo-resource-blog-master/unpackage/dist/dev/mp-weixin/node-modules/uni_modules/uni-search-bar/components/uni-search-bar/uni-search-bar 路径下未找到组件
```
**解决方案:**
1. **清理编译缓存**
```bash
# Windows 命令行
rmdir /s /q unpackage
# 或者直接删除 unpackage 目录
```
2. **检查 pages.json 配置**
确保 `pages.json` 中的 `easycom` 配置包含了 uni_modules 组件的正确匹配规则:
```json
"easycom": {
"^u-(.*)": "uview-ui/components/u-$1/u-$1.vue",
"^uni-(.*)": "@/uni_modules/uni-$1/components/uni-$1/uni-$1.vue"
}
```
3. **确认组件存在**
检查 `uni_modules/uni-search-bar/components/uni-search-bar/uni-search-bar.vue` 文件是否存在。
4. **重新编译项目**
- 在 HBuilderX 中:运行 → 运行到小程序模拟器 → 微信开发者工具
- 或使用命令行工具重新编译
**说明:**
- uni-app 的 easycom 机制会自动注册符合命名规范的组件
- 项目中的 uni-search-bar 组件位于 `uni_modules` 目录下,是标准的 uni_modules 组件
- 错误中的 `node-modules` 路径是编译过程中的临时路径,实际组件路径应该是 `uni_modules`
- 清理缓存可以解决大部分编译路径缓存问题
### 其他常见问题
- **组件不显示**:确保已正确配置 easycom 或手动引入组件
- **编译错误**:检查 pages.json 语法,确保 JSON 格式正确
- **路径错误**:使用相对路径时注意 `@/` 表示项目根目录
## 技术支持
- 如有问题欢迎联系作者
<table>
<tr>
<td align="center" bgcolor=#F6F8FA>微信</td>
<td align="center" bgcolor=#F6F8FA>QQ</td>
</tr>
<tr>
<td bgcolor=#FFFFFF><img src="https://img.eplusskin.com/uploads/20240730/wx3.png"/></td>
<td bgcolor=#FFFFFF><img src="https://img.eplusskin.com/uploads/20240730/qiuqiu3.png"/></td>
</tr>
<tr>
<td align="center">YiMoZiYuan666</td>
<td align="center">1149297946</td>
</tr>
</table>
## 小程序部分演示图
<table>
<tr>
<td><img src="https://img.eplusskin.com/uploads/20240730/show-1.png"/></td>
<td><img src="https://img.eplusskin.com/uploads/20240730/show-2.png"/></td>
<td><img src="https://img.eplusskin.com/uploads/20240730/show-4.png"/></td>
</tr>
<tr>
<td><img src="https://img.eplusskin.com/uploads/20240730/show-3.png"/></td>
<td><img src="https://img.eplusskin.com/uploads/20240730/show-5.png"/></td>
<td><img src="https://img.eplusskin.com/uploads/20240730/%E6%B0%B4%E5%8D%B01.png"/></td>
</tr>
<tr>
<td><img src="https://img.eplusskin.com/uploads/20240730/%E6%96%87%E7%AB%A0%E8%AF%A6%E6%83%85.png"/></td>
<td><img src="https://img.eplusskin.com/uploads/20240730/%E6%96%87%E7%AB%A0%E8%AF%A6%E6%83%852.png"/></td>
<td><img src="https://img.eplusskin.com/uploads/20240730/%E4%B8%8B%E8%BD%BD.png"/></td>
</tr>
<tr>
<td><img src="https://img.eplusskin.com/uploads/20240730/%E7%A7%AF%E5%88%86.png"/></td>
<td><img src="https://img.eplusskin.com/uploads/20240730/%E7%A7%AF%E5%88%86%E7%89%A9%E5%93%81.png"/></td>
<td><img src="https://img.eplusskin.com/uploads/20240730/choujiang.jpg"/></td>
</tr>
<tr>
<td><img src="https://img.eplusskin.com/uploads/20240730/%E6%89%8B%E6%9C%BA%E5%A3%81%E7%BA%B8.png"/></td>
<td><img src="https://img.eplusskin.com/uploads/20240730/%E7%94%B5%E8%84%91%E5%A3%81%E7%BA%B8.png"/></td>
<td><img src="https://img.eplusskin.com/uploads/20240730/%E5%A3%81%E7%BA%B8%E8%AF%A6%E6%83%85.png"/></td>
</tr>
</table>
## PC端部分演示图 在线演示[www.emoboy.vip](https://www.emoboy.vip)
<img src="https://img.eplusskin.com/uploads/20240730/%E5%90%8E%E5%8F%B0-new-1.png"/>
<img src="https://img.eplusskin.com/uploads/20240730/%E5%90%8E%E5%8F%B0-new-2.png"/>
## 管理后台部分演示图
<img src="https://img.eplusskin.com/uploads/20240730/%E5%90%8E%E5%8F%B01.png"/>
<img src="https://img.eplusskin.com/uploads/20240730/%E5%90%8E%E5%8F%B02.png"/>
<img src="https://img.eplusskin.com/uploads/20240730/%E5%90%8E%E5%8F%B03.png"/>
<img src="https://img.eplusskin.com/uploads/20240730/%E5%90%8E%E5%8F%B04.png"/>
* 若您喜欢对您有帮助的话,麻烦客官动动发财的手给小二一个 Star ,您的支持是我们不断进步的源泉!!!
### 6. 用户与权限中心
- **登录注册**:支持账号密码登录、注册,以及微信授权自动/快捷登录。
- **状态管理**:基于 `Vuex` 集中管理用户 Token、基础信息头像、昵称等。
- **权限控制**:基于 JWT 的权限认证体系,封装了 `$auth` 插件,支持基于角色和权限的细粒度鉴权。
- **网络拦截**:封装统一的 `request.js`,支持 Token 自动携带、响应拦截、过期自动弹窗跳转等。
## 技术栈
- 前端框架uni-app (Vue 2)
- UI 框架uView UI
- 状态管理Vuex

View File

@@ -53,9 +53,9 @@ export function getResource(id) {
}
// 查询资源详细
export function getResourceByUserId(id, userId) {
export function getResourceByUserId(id) {
return request({
url: '/app/resource/app/user/' + id + '/' + userId,
url: '/app/resource/app/user/' + id,
method: 'get'
})
}
@@ -95,16 +95,7 @@ export function listGoods(query) {
})
}
// 微信登录获取openid
export function autoLoginWx(code) {
return request({
url: '/app/public/autoLoginWx/' + code,
method: 'get'
})
}
// 新增文章
// 微信临时 code 登录OpenID 和 session_key 仅由后端获取
export function wxLogin(data) {
return request({
url: '/wxLogin',
@@ -192,23 +183,6 @@ export function exchangeResource(data) {
}
// 去水印
export function delShuiYin(data) {
return request({
url: '/app/public/delSHuiYin',
method: 'post',
data: data
})
}
// 新增安全域名配置
export function addNewDownloadUrl(url) {
return request({
url: '/app/public/addNewDownloadUrl/' + url,
method: 'get'
})
}
// 获取系统配置数据
export function getSysSet() {
return request({
@@ -280,20 +254,22 @@ export function listLotteryLog(query) {
})
}
// 创建充值订单
export function createRechargeOrder(data) {
// 创建资源虚拟支付订单
export function createVirtualResourceOrder(data) {
return request({
url: '/app/pay/createOrder',
url: '/app/virtual-pay/resource-orders',
method: 'post',
data: data
})
}
// 更新用户积分
export function updateUserPoints(data) {
// 查询资源虚拟支付订单
export function getVirtualResourceOrder(orderNo, sync) {
return request({
url: '/app/pay/updatePoints',
method: 'post',
data: data
url: '/app/virtual-pay/resource-orders/' + orderNo,
method: 'get',
params: {
sync: !!sync
}
})
}

View File

@@ -1,8 +1,10 @@
<template>
<view class="shape">
<swiper class="image-container example-body-item uni-swiper-wrapper" previous-margin="43rpx" next-margin="43rpx" circular @change="swiperChange" :indicator-dots="false" interval="2500" autoplay>
<swiper-item :class="currentIndex == index ? 'swiper-item' : 'swiper-item-side'" v-for="(item, index) in imgList" :key="item[urlKey]">
<image @click="clickImg(item)" :class="currentIndex == index ? 'item-img' : 'item-img-side'" :src="item.image" lazy-load :style="dontFirstAnimation ? 'animation: none;' : ''" mode="aspectFill"></image>
<swiper-item :class="currentIndex == index ? 'swiper-item' : 'swiper-item-side'" v-for="(item, index) in imgList" :key="index">
<navigator class="carousel-link" :url="item.url" open-type="navigate" hover-class="none">
<image :class="currentIndex == index ? 'item-img' : 'item-img-side'" :src="imageSource(item, index)" lazy-load :draggable="false" :style="dontFirstAnimation ? 'animation: none;' : ''" mode="aspectFill" @error="imageError(item, index)"></image>
</navigator>
</swiper-item>
</swiper>
</view>
@@ -16,27 +18,35 @@
default() {
return []
}
},
urlKey: {
type: String,
default() {
return ''
}
}
},
data() {
return {
currentIndex: 0,
dontFirstAnimation: true,
failedImages: {},
}
},
watch: {
imgList() {
this.failedImages = {}
}
},
methods: {
imageSource(item, index) {
if (this.failedImages[index] && item.fallbackImage) {
return item.fallbackImage
}
return item.image
},
imageError(item, index) {
if (!this.failedImages[index] && item.fallbackImage && item.fallbackImage !== item.image) {
this.$set(this.failedImages, index, true)
}
},
swiperChange(e) {
this.dontFirstAnimation = false
this.currentIndex = e.detail.current
},
clickImg(item) {
this.$emit('selected', item, this.currentIndex)
}
}
}
@@ -78,6 +88,13 @@
.image-container {
height: 360rpx;
}
.carousel-link {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.item-img {
width: 650rpx;

View File

@@ -74,14 +74,6 @@
"enablePullDownRefresh" : true
}
},
{
"path" : "pages/tool/video",
"style" :
{
"navigationBarTitleText" : "演示视频",
"enablePullDownRefresh" : false
}
},
{
"path" : "pages/tool/software",
"style" :
@@ -127,7 +119,7 @@
"path" : "pages/mine/integral_record",
"style" :
{
"navigationBarTitleText" : "积分记录",
"navigationBarTitleText" : "消费记录",
"enablePullDownRefresh" : false
}
},
@@ -139,14 +131,6 @@
"enablePullDownRefresh" : false
}
},
{
"path": "pages/mine/recharge",
"style": {
"navigationBarTitleText": "充值积分",
"navigationBarBackgroundColor": "#ffffff",
"navigationBarTextStyle": "black"
}
},
{
"path" : "pages/tool/avatar",
"style" :
@@ -164,38 +148,6 @@
"navigationStyle": "custom"
}
},
{
"path" : "pages/tool/shuiyin",
"style" :
{
"navigationBarTitleText" : "水印去除",
"enablePullDownRefresh" : false
}
},
{
"path" : "pages/tool/shuiyin/problem",
"style" :
{
"navigationBarTitleText" : "教程和问题",
"enablePullDownRefresh" : false
}
},
{
"path" : "pages/tool/shuiyin/image",
"style" :
{
"navigationBarTitleText" : "解析结果",
"enablePullDownRefresh" : false
}
},
{
"path" : "pages/tool/shuiyin/video",
"style" :
{
"navigationBarTitleText" : "解析结果",
"enablePullDownRefresh" : false
}
},
{
"path" : "pages/tool/phone",
"style" :

View File

@@ -11,7 +11,7 @@
</cover-view>
<!-- 顶部图片 -->
<view class="top-img">
<image class="ui-img" :src="blogInfo.showImg" mode="aspectFill"></image>
<image class="ui-img" :src="$image.original(blogInfo.showImg)" mode="aspectFill"></image>
<text v-if="share == 0" @click="back()" class="cuIcon-back backbut"></text>
<text v-else @click="home()" class="cuIcon-home backbut"></text>
</view>
@@ -53,7 +53,7 @@
<view v-if="blogInfo.picList && blogInfo.picList.length > 0" class="screenshot-view">
<view class="screenshot-list">
<view v-for="(item, index) in blogInfo.picList" :key="index" class="screenshot-item" @click="previewImage(index)">
<image class="screenshot-img" :src="item" mode="aspectFill"></image>
<image class="screenshot-img" :src="$image.original(item)" lazy-load mode="aspectFill"></image>
</view>
</view>
</view>
@@ -69,7 +69,7 @@
<block>
<view class="list-li" v-for="(item ,index) in blogList" :key="index" @click="to(item.id)">
<view class="list-img">
<image class="ui-img" :src="item.showImg"></image>
<image class="ui-img" :src="$image.articleThumbnail(item)" lazy-load mode="aspectFill"></image>
</view>
<view class="list-li-left">
<view class="list-li-left-h">
@@ -85,7 +85,7 @@
</view>
<view v-else class="margin">
<!-- <view style="width: 100%;height: 300rpx;">
<image class="blog-showimg" :src="blogInfo.showImg"></image>
<image class="blog-showimg" :src="$image.original(blogInfo.showImg)" lazy-load mode="aspectFill"></image>
</view> -->
<view v-if="blogInfo.remark" class="shuoming">说明:{{blogInfo.remark}}</view>
<view v-else class="shuoming">说明请先点击下方按钮即可获取文章详情由于存储与服务器成本很高不得已部分内容需您观看激励视频广告</view>
@@ -111,7 +111,7 @@
<view class="cover-list-font">点赞</view>
</view>
<view v-if="blogInfo.appResourceId" @click="download(blogInfo.appResourceId)">
<view v-if="blogInfo.appResourceId" @click="download()">
<view class="cover-list-icon">
<image class="ui-img" src="https://img.yidaima.cn/feast/xiazai.svg"
mode="aspectFit">
@@ -370,8 +370,16 @@
})
})
},
download(id) {
this.$tab.navigateTo('/pages/blog/resource?id=' + id + "&type=1")
download() {
const id = this.blogInfo && this.blogInfo.appResourceId
if (!id) {
uni.showToast({
title: '资源信息不存在',
icon: 'none'
})
return
}
this.$tab.navigateTo('/pages/blog/resource?id=' + encodeURIComponent(id) + "&type=1")
},
back(val) {
const pages = getCurrentPages();
@@ -778,4 +786,4 @@
z-index: 1025;
background-color: #fff;
}
</style>
</style>

View File

@@ -3,7 +3,7 @@
<!-- 顶部图片 -->
<view class="top-img">
<image class="ui-img" :src="resourceInfo.showImg" mode="aspectFill"></image>
<image class="ui-img" :src="$image.original(resourceInfo.showImg)" mode="aspectFill"></image>
<text @click="back()" class="cuIcon-back backbut"></text>
</view>
<view class="resource-box">
@@ -45,7 +45,8 @@
</view>
<view v-if="isLookAd == 0" class="shuoming2">复制下方链接打开手机浏览器进行下载</view>
<view v-else class="shuoming2">请先点击下方按钮即可获取资源下载列表</view>
<view v-if="isLookAd == 0" v-for="(item,index) in resourceInfo.appResourceListList" :key="index" class="file-list">
<template v-if="isLookAd == 0">
<view v-for="(item,index) in resourceInfo.appResourceListList" :key="index" class="file-list">
<view class="resource-view">
<view class="resource-img3">
<image class="ui-img" src="https://img.yidaima.cn/feast/files.svg" mode="aspectFit"></image>
@@ -56,6 +57,7 @@
</view>
<view class="file-url-box"><text class="file-url">{{item.listUrl}}</text><text @click="copy(item.listUrl)" class="file-copy">复制</text></view>
</view>
</template>
<view v-if="adUnitId" style="width: 100%; margin-top: 50rpx;">
<ad-custom :unit-id="adUnitId" ad-intervals="30" ></ad-custom>
@@ -65,13 +67,16 @@
</view>
</view>
<view v-if="isLookAd ==1 || isLookAd == 2" style="height: 140rpx; width: 100%;"></view>
<view v-if="isLookAd ==1 || isLookAd == 2 || isLookAd == 3" style="height: 140rpx; width: 100%;"></view>
<view v-if="isLookAd ==1" @click="lookAd()" class="resource-ad">
广告查看
</view>
<view v-if="isLookAd ==2" @click="jfAd()" class="resource-ad">
积分获取 {{resourceInfo.adNumber}} 积分
</view>
<view v-if="isLookAd ==3" @click="payResource()" class="resource-ad">
{{paying ? '支付结果确认中...' : '付费获取 ¥' + formatPrice(resourceInfo.priceFen) + ' '}}
</view>
<u-toast ref="uToast"></u-toast>
</view>
@@ -79,7 +84,8 @@
<script>
import {
getResource,getResourceByUserId,resourceDownLoad,appGetUserById,exchangeResource
getResource,getResourceByUserId,resourceDownLoad,appGetUserById,exchangeResource,
createVirtualResourceOrder,getVirtualResourceOrder
} from "@/api/app/index.js"
import config from '@/config'
let videoAd = null;
@@ -90,8 +96,13 @@
adUnitId:"",
adUnitId2:"",
id:null,
resourceInfo:{},
resourceInfo:{
resourceTitle: '',
showImg: '',
appResourceListList: []
},
isLookAd:null,
paying: false,
tag_style: {
h1: 'line-height: 50px;font-size:16px;',
h2: 'line-height: 50px;font-size:16px',
@@ -125,10 +136,20 @@
}
},
onLoad(option) {
this.adUnitId = uni.getStorageSync("sysSet").zyinfoAd
this.adUnitId2 = uni.getStorageSync("sysSet").downVideoAd
this.userId = uni.getStorageSync("userInfo").userId
this.id = option.id
const sysSet = uni.getStorageSync("sysSet") || {}
const userInfo = uni.getStorageSync("userInfo") || {}
this.adUnitId = sysSet.zyinfoAd || ""
this.adUnitId2 = sysSet.downVideoAd || ""
this.userId = userInfo.userId || null
const id = option && option.id
if (!/^\d+$/.test(String(id || ''))) {
uni.showToast({
title: '资源参数错误,请重新进入',
icon: 'none'
})
return
}
this.id = id
if(option.type){
this.type = option.type
}
@@ -212,7 +233,7 @@
message: "兑换成功",
icon: false
})
that.isLookAd = 0
that.getInfo()
})
}
@@ -237,26 +258,33 @@
},
getInfo(){
var that = this;
getResourceByUserId(this.id, this.userId).then(response => {
console.log(response.data)
getResourceByUserId(this.id).then(response => {
if (!response || !response.data) {
uni.showToast({
title: '资源信息不存在',
icon: 'none'
})
return
}
if(response.data.isAd == 0){
this.isLookAd = 0
resourceDownLoad({id: this.id}).then(response => {})
}else if(response.data.isAd == 1){
this.isLookAd = 1
//resourceDownLoad({id: this.id}).then(response => {})
}else{
}else if(response.data.isAd == 2){
this.isLookAd = 2
}else if(response.data.isAd == 3){
this.isLookAd = 3
}
that.resourceInfo = response.data
var str = that.resourceInfo.explain
var str = that.resourceInfo.explain || ''
if (str.includes("/dev-api")) {
that.resourceInfo.explain = str.replace("/dev-api", that.baseUrl)
} else {
that.resourceInfo.explain = str.replace("/prod-api", that.baseUrl)
}
that.contentDate = response.data.explain
that.contentDate = that.resourceInfo.explain
.replace(/<h1([\s\w"=\/\.:;]+)((?:(style="[^"]+")))/ig, '<h1')
.replace(/<h1([\s\w"=\/\.:;]+)((?:(class="[^"]+")))/ig, '<h1')
.replace(/<h1>/ig, '<h1 class="h1">')
@@ -296,6 +324,122 @@
}
});
},
payResource(){
var that = this;
if (this.paying) {
return;
}
if (!this.userId) {
uni.showToast({
title: '请先登录后购买',
icon: 'none'
});
return;
}
if (!this.resourceInfo.priceFen || this.resourceInfo.priceFen <= 0) {
uni.showToast({
title: '价格信息错误',
icon: 'none'
});
return;
}
if (typeof wx === 'undefined' || typeof wx.requestVirtualPayment !== 'function') {
uni.showToast({
title: '当前微信版本不支持虚拟支付,请升级微信',
icon: 'none'
});
return;
}
this.paying = true;
uni.login({
provider: 'weixin',
success: loginRes => {
createVirtualResourceOrder({
resourceId: that.id,
code: loginRes.code
}).then(response => {
var payParams = response.data;
wx.requestVirtualPayment({
signData: payParams.signData,
paySig: payParams.paySig,
signature: payParams.signature,
mode: payParams.mode,
success: () => {
that.confirmVirtualOrder(payParams.orderNo, 0);
},
fail: err => {
that.paying = false;
var cancelled = err && err.errCode === -2;
uni.showToast({
title: cancelled ? '已取消支付' : '支付未完成,请重试',
icon: 'none'
});
}
});
}).catch(() => {
that.paying = false;
});
},
fail: () => {
that.paying = false;
uni.showToast({
title: '获取微信登录凭证失败',
icon: 'none'
});
}
});
},
confirmVirtualOrder(orderNo, attempt){
var that = this;
var shouldSync = attempt === 1 || attempt === 6;
getVirtualResourceOrder(orderNo, shouldSync).then(response => {
var order = response.data;
if (order.unlocked) {
that.paying = false;
that.$refs.uToast.show({
type: 'success',
title: '',
message: '购买成功',
icon: false
});
that.getInfo();
return;
}
if (order.status === 2 || order.status === 3) {
that.paying = false;
uni.showToast({
title: order.status === 2 ? '订单已退款' : '订单已关闭',
icon: 'none'
});
return;
}
if (attempt < 10) {
setTimeout(function() {
that.confirmVirtualOrder(orderNo, attempt + 1);
}, 1200);
} else {
that.paying = false;
uni.showToast({
title: '支付结果确认中,请稍后重新进入页面',
icon: 'none',
duration: 3000
});
}
}).catch(() => {
if (attempt < 10) {
setTimeout(function() {
that.confirmVirtualOrder(orderNo, attempt + 1);
}, 1200);
} else {
that.paying = false;
}
});
},
formatPrice(priceFen){
var value = Number(priceFen || 0) / 100;
return value.toFixed(2);
},
back(val) {
const pages = getCurrentPages();
if (pages.length > 1) {
@@ -451,4 +595,4 @@
top: 100rpx;
font-size: 50rpx;
}
</style>
</style>

View File

@@ -1,6 +1,6 @@
<template>
<view class="">
<image style="position: relative;z-index: 1;" class="fengrui-img" src="https://img.yidaima.cn/feast/index_bj.jpg"
<image style="position: relative;z-index: 1;" class="fengrui-img" src="/static/home/index-bg.jpg"
mode="aspectFill"></image>
<view style="position: relative;z-index: 2;" class="index-box">
<view class="notice-box">
@@ -10,7 +10,7 @@
</view>
</view>
<!-- 轮播图 -->
<carousel :img-list="swiperData" url-key="url" @selected="selectedBanner"/>
<carousel :img-list="swiperData"/>
<!-- <uni-swiper-dot class="uni-swiper-dot-box" :info="swiperData" :current="current" field="content">
<swiper autoplay :circular="true" interval="2000" class="swiper-box" :current="swiperDotIndex"
@change="changeSwiper">
@@ -22,7 +22,7 @@
</swiper>
</uni-swiper-dot> -->
<view class="index-info">
<view class="mt30 grid text-center col-4 bg-white" style="padding: 30rpx 0; border-radius: 15rpx;row-gap: 30rpx;">
<view class="mt30 grid text-center col-3 bg-white" style="padding: 30rpx 0; border-radius: 15rpx;row-gap: 30rpx;">
<view @click="Jump('/pages/tool/highQualityCode')">
<image class="cell_3_icon flex justify-center align-center" style="height:65rpx;" src="https://img.yidaima.cn/feast/sjbz.png" mode="aspectFit">
</image>
@@ -33,11 +33,6 @@
</image>
<view>资源分享</view>
</view>
<view @click="Jump('/pages/tool/video')">
<image class="cell_3_icon flex justify-center align-center" style="height: 65rpx;" src="https://img.yidaima.cn/feast/sp.png" mode="aspectFit">
</image>
<view>演示视频</view>
</view>
<view @click="Jump('/pages/tool/freeCode')">
<image class="cell_3_icon flex justify-center align-center" style="height: 65rpx;" src="https://img.yidaima.cn/feast/sycc.png" mode="aspectFit">
</image>
@@ -64,15 +59,18 @@
</view>
<view style="height: 240rpx;" v-else>
<!-- <image class="blog-img" :src="baseUrl+item.showImg"></image> -->
<image class="blog-img" :src="item.showImg"></image>
<image class="blog-img" :src="articleImage(item)" lazy-load mode="aspectFill" @error="articleImageError(item)"></image>
<view class="info-box">
<view class="ellipsis-multiline">
{{item.title}}
</view>
<view class="info-icon">
<image v-if="item.isAd == 0" class="muen-sld-icon" src="https://img.yidaima.cn/feast/guanggao.svg" mode=""></image>
<image v-if="item.appResourceId" class="muen-sld-icon" src="https://img.yidaima.cn/feast/xiazai.svg" mode=""></image>
<image v-if="item.weight == 999" class="muen-sld-icon2" src="https://img.yidaima.cn/feast/top.svg" mode=""></image>
<image v-if="item.appResource.isAd == 0" class="muen-sld-icon" src="https://img.yidaima.cn/mf.svg" mode=""></image>
<image v-if="item.appResource.isAd == 1" class="muen-sld-icon" src="https://img.yidaima.cn/feast/guanggao.svg" mode=""></image>
<image v-if="item.appResource.isAd == 2" class="muen-sld-icon" src="https://img.yidaima.cn/jf.svg" mode=""></image>
<image v-if="item.appResource.isAd == 3" class="muen-sld-icon" src="https://img.yidaima.cn/ff.svg" mode=""></image>
<image v-if="item.appResourceId" class="muen-sld-icon" src="https://img.yidaima.cn/feast/xiazai.svg" mode=""></image>
<image v-if="item.weight == 999" class="muen-sld-icon2" src="https://img.yidaima.cn/feast/top.svg" mode=""></image>
</view>
<view class="muen-sld-time"><text style="float: left;">{{item.createTime}}</text>
<text class="cuIcon-attention look-number"><text>{{item.lookNumber}}</text></text></view>
@@ -132,7 +130,7 @@
getConfigKey
} from "@/api/app/public.js"
import {
listArticle,newUser,wxLogin,autoLoginWx,getSysSet
listArticle,newUser,wxLogin,getSysSet
} from "@/api/app/index.js"
import {
getQiniuToken
@@ -203,27 +201,19 @@
uni.login({
provider: 'weixin',
success: loginRes => {
//获取openid
autoLoginWx(loginRes.code).then(response => {
var antoInfo = JSON.parse(response.msg)
var data = {
openId: antoInfo.openid,
oldUserId : 0
}
//邀请用户
if(option.userid && option.userid != 'undefined'){
data.oldUserId = option.userid
}
//登录
wxLogin(data).then(logininfo => {
setToken(logininfo.token)
//设置用户信息
this.$store.dispatch('GetInfo').then(res => {
})
var data = {
code: loginRes.code,
oldUserId : 0
}
//邀请用户
if(option.userid && option.userid != 'undefined'){
data.oldUserId = option.userid
}
wxLogin(data).then(logininfo => {
setToken(logininfo.token)
this.$store.dispatch('GetInfo').then(res => {
})
})
}
});
//获取系统配置数据
@@ -241,12 +231,6 @@
that.modalName = "indexModal"
uni.setStorageSync("isIndexModal", that.modalInfo)
}
//轮播图
that.swiperData = []
var swiper = setinfo.indexSwiper.split(",")
for(var i=0; i < swiper.length; i++){
that.swiperData.push({image:swiper[i]})
}
})
//获取文章列表
this.getBlogList()
@@ -285,6 +269,41 @@
}
},
methods: {
articleImage(item) {
if (item && item.imageFallback) {
return this.$image.original(item.showImg)
}
return this.$image.articleThumbnail(item)
},
articleImageError(item) {
if (!item || item.imageFallback || !item.showImg) {
return
}
this.$set(item, 'imageFallback', true)
},
setArticleSwiper(articleList) {
this.swiperData = (articleList || [])
.filter(item => item && Number(item.weight) !== 999)
.slice(0, 5)
.map(item => ({
id: item.id,
image: this.$image.articleThumbnail(item),
fallbackImage: this.$image.original(item.showImg),
url: '/pages/blog/bloginfo?id=' + item.id
}))
},
getArticleSwiper(pageSize) {
listArticle({
pageNum: 1,
pageSize: pageSize,
isShow: this.queryParams.isShow
}).then(response => {
this.setArticleSwiper(response.rows)
if (this.swiperData.length < 5 && response.rows.length < response.total) {
this.getArticleSwiper(Math.min(pageSize + 5, response.total))
}
})
},
offApp(){
uni.exitMiniProgram({
success: function () {
@@ -332,6 +351,10 @@
getBlogList(){
var that = this;
listArticle(this.queryParams).then(response => {
that.setArticleSwiper(response.rows)
if (that.swiperData.length < 5 && response.rows.length < response.total) {
that.getArticleSwiper(response.rows.length + 5)
}
that.blogList = response.rows
var allTotal = this.queryParams.pageNum * this.queryParams.pageSize
that.total = response.total
@@ -603,4 +626,4 @@
width: 100%;
}
}
</style>
</style>

View File

@@ -1,10 +1,10 @@
<template>
<view class="my">
<image src="https://v2.api-m.com/api/wallpaper?return=302" mode="aspectFill" class="my_bg"></image>
<image src="/static/mine/default-profile-bg.jpg" mode="aspectFill" class="my_bg"></image>
<view class="header_cell">
<view style="margin-top: 40rpx;" class="user_info">
<view class="flex justify-center align-center">
<image src="https://v2.api-m.com/api/head?return=302" mode="aspectFill" class="user_photo"></image>
<image src="/static/mine/default-avatar.jpg" mode="aspectFill" class="user_photo"></image>
<view>
<view class="text-black text-bold">
<text v-if="userid" class="text-xl" style="font-weight: bold;">微信用户_{{userid}}</text>
@@ -53,7 +53,7 @@
<!-- <view style="width: 100%; margin-top: 30rpx;">
<ad-custom unit-id="adunit-ff28399b17818338" ad-intervals="30" ></ad-custom>
</view> -->
<view class="mt30 grid text-center col-4 bg-white"
<view class="mt30 grid text-center col-3 bg-white"
style="padding: 30rpx 0; border-radius: 15rpx;row-gap: 30rpx;">
<view @click="exchange()">
<view class="cell_3_icon flex justify-center align-center"><text
@@ -65,16 +65,11 @@
class="text-cyan cuIcon-selection"></text></view>
<view>兑换记录</view>
</view>
<view @click="integralRecord()">
<view class="cell_3_icon flex justify-center align-center"><text class="text-cyan cuIcon-coin"></text>
</view>
<view>积分记录</view>
</view>
<view @click="recharge()">
<view class="cell_3_icon flex justify-center align-center"><text
class="text-olive cuIcon-moneybag"></text></view>
<view>充值积分</view>
<view @click="integralRecord()">
<view class="cell_3_icon flex justify-center align-center"><text class="text-cyan cuIcon-coin"></text>
</view>
<view>消费记录</view>
</view>
</view>
<!-- 功能列表 -->
@@ -108,7 +103,7 @@
<image class="blogui-img" src="https://img.yidaima.cn/feast/more.svg" mode=""></image>
</view>
</view>
<view class="metergasis-li" hover-class="fengrui-li-hover" @tap="categoryNew()">
<view v-if="false" class="metergasis-li" hover-class="fengrui-li-hover" @tap="categoryNew()">
<view class="metergasis-li-img">
<image class="blogui-img" src="https://img.yidaima.cn/feast/weixin.svg" mode="aspectFill">
</image>
@@ -135,19 +130,6 @@
<image class="blogui-img" src="https://img.yidaima.cn/feast/more.svg" mode=""></image>
</view>
</view>
<view class="metergasis-li" hover-class="fengrui-li-hover" @tap="guanzhu(2)">
<view style="width: 55rpx; height: 55rpx;" class="metergasis-li-img">
<image class="blogui-img" src="https://img.yidaima.cn/feast/adduser.svg" mode="aspectFill">
</image>
</view>
<view style="margin-left: 27rpx;" class="metergasis-li-h">
添加好友
</view>
<text class="metergasis-li-h2">添加成功可获得 {{addUserNumber}} 积分</text>
<view class="metergasis-li-rgth">
<image class="blogui-img" src="https://img.yidaima.cn/feast/more.svg" mode=""></image>
</view>
</view>
<view class="metergasis-li" hover-class="fengrui-li-hover" @tap="lottery()">
<view class="metergasis-li-img">
<image class="blogui-img" src="http://imgs.emoboy.vip/static/mine/choujiang.svg" mode="aspectFill"></image>
@@ -189,7 +171,6 @@
<script>
import {
autoLoginWx,
wxLogin,
getUser,
addAppIntegra
@@ -218,8 +199,7 @@
adIntegral: 0,
adYesNumber: 0,
adNumber: 0,
newUserNumber: 0,
addUserNumber: 0
newUserNumber: 0
};
},
// 分享好友配置
@@ -319,9 +299,6 @@
exchange(){
this.$tab.navigateTo('/pages/tool/exchange')
},
recharge() {
this.$tab.navigateTo('/pages/mine/recharge')
},
categoryNew(){
uni.switchTab({
url: '/pages/search/index'
@@ -428,7 +405,6 @@
that.adIntegral = response.ad.split(",")[0]
that.adNumber = response.ad.split(",")[1]
that.newUserNumber = response.newUserNumber
that.addUserNumber = response.addUserNumber
})
},
autologin() {
@@ -437,25 +413,15 @@
uni.login({
provider: 'weixin',
success: loginRes => {
//获取openid
autoLoginWx(loginRes.code).then(response => {
var antoInfo = JSON.parse(response.msg)
console.log(antoInfo)
console.log(antoInfo.openid)
//登录
wxLogin({
openId: antoInfo.openid
}).then(logininfo => {
console.log(logininfo)
setToken(logininfo.token)
//设置用户信息
this.$store.dispatch('GetInfo').then(res => {
that.userid = uni.getStorageSync("userInfo").userId
that.getUserInfo()
})
wxLogin({
code: loginRes.code
}).then(logininfo => {
setToken(logininfo.token)
this.$store.dispatch('GetInfo').then(res => {
that.userid = uni.getStorageSync("userInfo").userId
that.getUserInfo()
})
})
}
});
},
@@ -670,4 +636,4 @@
}
}
}
</style>
</style>

View File

@@ -2,7 +2,7 @@
<view>
<view v-if="dataList.length != 0" class="re-box">
<view>
<text style="font-size: 40rpx;color: #0081ff;" class="cuIcon-titles"></text><text style="font-size: 35rpx;">积分明细</text>
<text style="font-size: 40rpx;color: #0081ff;" class="cuIcon-titles"></text><text style="font-size: 35rpx;">消费明细</text>
</view>
<view style="margin-top: 40rpx;">
<view v-for="(item,index) in dataList" :key="index" class="flex solid-bottom padding justify-between">
@@ -17,9 +17,12 @@
<view v-if="item.isAdd == 0" class="re-number">+{{item.integralNumber}}
<text class="cuIcon-vip" style="margin-left: 15rpx;font-size: 40rpx;"></text>
</view>
<view v-else style="color: #07C160;" class="re-number">-{{item.integralNumber}}
<view v-if="item.isAdd == 1" style="color: #07C160;" class="re-number">-{{item.integralNumber}}
<text class="cuIcon-vip" style="margin-left: 15rpx;font-size: 40rpx;"></text>
</view>
<view v-if="item.isAdd == 3" style="color: #07C160;" class="re-number">-¥{{formatMoney(item.integralNumber)}}
<text class="cuIcon-recharge" style="margin-left: 15rpx;font-size: 40rpx;"></text>
</view>
</view>
@@ -88,6 +91,9 @@
this.getDataList()
},
methods: {
formatMoney(priceFen) {
return (Number(priceFen || 0) / 100).toFixed(2)
},
getDataList(){
var that = this;
listAppIntegra(this.queryParams).then(response => {

View File

@@ -1,399 +0,0 @@
<template>
<view class="recharge-container">
<view class="header">
<text class="title">充值积分</text>
<text class="subtitle">更多积分享受更多精彩内容</text>
</view>
<view class="recharge-list">
<view class="recharge-item"
v-for="(item, index) in rechargeOptions"
:key="index"
@click="handleRecharge(item)"
:class="{'selected': selectedIndex === index}">
<view class="item-content">
<view class="price-box">
<text class="price-symbol">¥</text>
<text class="price-value">{{item.price}}</text>
</view>
<view class="points-box">
<view class="main-points">
<text class="num">{{item.points}}</text>
<text class="unit">积分</text>
</view>
<view class="bonus">
<text class="tag">赠送</text>
<text class="num">+{{item.bonus}}</text>
</view>
</view>
<view class="total-box">
<text class="label">总计</text>
<text class="value">{{item.total}}积分</text>
</view>
<view class="best-value" v-if="index === 2">
<text>超值优惠</text>
</view>
</view>
</view>
</view>
<view class="notice">
<view class="notice-item">
<text class="dot">·</text>
<text>充值积分可用于兑换平台内所有资源</text>
</view>
<view class="notice-item">
<text class="dot">·</text>
<text>充值金额越多赠送积分越多</text>
</view>
</view>
<view class="submit-btn" :class="{'disabled': selectedIndex === -1}" @click="submitRecharge">
<text v-if="selectedIndex === -1">请选择充值金额</text>
<text v-else>确认支付 ¥{{rechargeOptions[selectedIndex].price}}</text>
</view>
</view>
</template>
<style lang="less" scoped>
.recharge-container {
min-height: 100vh;
background-color: #f8f8f8;
padding: 30rpx;
.header {
text-align: center;
margin-bottom: 50rpx;
padding: 40rpx 0;
.title {
font-size: 44rpx;
font-weight: bold;
display: block;
margin-bottom: 20rpx;
color: #333;
}
.subtitle {
font-size: 28rpx;
color: #999;
}
}
.recharge-list {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 20rpx;
margin-bottom: 40rpx;
.recharge-item {
position: relative;
border-radius: 16rpx;
overflow: hidden;
.item-content {
background: #fff;
padding: 30rpx;
height: 100%;
box-shadow: 0 2rpx 12rpx rgba(0,0,0,0.05);
border: 2rpx solid #eee;
transition: all 0.3s;
.price-box {
margin-bottom: 20rpx;
.price-symbol {
font-size: 32rpx;
color: #333;
font-weight: bold;
}
.price-value {
font-size: 48rpx;
color: #333;
font-weight: bold;
margin-left: 4rpx;
}
}
.points-box {
.main-points {
margin-bottom: 10rpx;
.num {
font-size: 32rpx;
color: #666;
margin-right: 8rpx;
}
.unit {
font-size: 26rpx;
color: #666;
}
}
.bonus {
.tag {
background: #fff1f0;
color: #ff4d4f;
padding: 2rpx 10rpx;
border-radius: 8rpx;
font-size: 22rpx;
margin-right: 8rpx;
}
.num {
color: #ff4d4f;
font-size: 24rpx;
}
}
}
.total-box {
margin-top: 20rpx;
font-size: 24rpx;
.label {
color: #999;
margin-right: 8rpx;
}
.value {
color: #333;
font-weight: 500;
}
}
}
.best-value {
position: absolute;
top: 0;
right: 0;
background: linear-gradient(135deg, #ff6b6b, #ff8585);
color: #fff;
font-size: 22rpx;
padding: 6rpx 20rpx;
border-radius: 0 16rpx 0 16rpx;
}
&.selected {
.item-content {
border-color: #007AFF;
background: #f0f7ff;
transform: translateY(-2rpx);
box-shadow: 0 4rpx 16rpx rgba(0,122,255,0.1);
}
}
}
}
.notice {
padding: 30rpx;
background: #fff;
border-radius: 16rpx;
margin-bottom: 120rpx;
.notice-item {
display: flex;
align-items: center;
margin-bottom: 16rpx;
font-size: 26rpx;
color: #666;
&:last-child {
margin-bottom: 0;
}
.dot {
color: #007AFF;
margin-right: 10rpx;
font-weight: bold;
}
}
}
.submit-btn {
position: fixed;
bottom: 40rpx;
left: 30rpx;
right: 30rpx;
height: 90rpx;
line-height: 90rpx;
text-align: center;
background: #007AFF;
color: #fff;
border-radius: 45rpx;
font-size: 32rpx;
box-shadow: 0 4rpx 16rpx rgba(0,122,255,0.2);
transition: all 0.3s;
&.disabled {
background: #ccc;
box-shadow: none;
}
}
}
</style>
<script>
import { createRechargeOrder, updateUserPoints } from "@/api/app/index.js"
export default {
data() {
return {
selectedIndex: -1,
isIOS: false,
rechargeOptions: [
{
price: 10,
points: 100,
bonus: 10,
total: 110
},
{
price: 30,
points: 300,
bonus: 30,
total: 330
},
{
price: 50,
points: 500,
bonus: 50,
total: 550
},
{
price: 100,
points: 1000,
bonus: 100,
total: 1100
},
{
price: 200,
points: 2000,
bonus: 300,
total: 2300
},
{
price: 300,
points: 3000,
bonus: 500,
total: 3500
}
]
}
},
onLoad() {
// 检查是否是iOS设备
const systemInfo = uni.getSystemInfoSync();
this.isIOS = systemInfo.platform === 'ios';
},
methods: {
handleRecharge(item) {
this.selectedIndex = this.rechargeOptions.indexOf(item)
},
submitRecharge() {
if(this.selectedIndex === -1) {
uni.showToast({
title: '请选择充值金额',
icon: 'none'
})
return
}
// iOS设备提示
if(this.isIOS) {
uni.showModal({
title: '提示',
content: '由于相关政策限制iOS设备暂不支持充值功能请使用安卓设备或Windows电脑进行充值。',
showCancel: false,
confirmText: '我知道了'
});
return;
}
const selected = this.rechargeOptions[this.selectedIndex];
uni.showLoading({
title: '加载中...'
});
// 创建充值订单
const orderData = {
amount: selected.price,
points: selected.total,
userId: uni.getStorageSync('userInfo').userId
}
createRechargeOrder(orderData).then(res => {
uni.hideLoading();
if(res.code === 200) {
// 调起微信支付
uni.requestPayment({
provider: 'wxpay',
appId: res.data.appId,
nonceStr: res.data.nonceStr,
package: res.data.packageVal,
signType: res.data.signType,
timeStamp: res.data.timeStamp,
paySign: res.data.paySign,
success: () => {
uni.showToast({
title: '充值成功',
icon: 'success'
});
},
fail: (err) => {
console.log('支付失败', err);
uni.showToast({
title: '支付失败',
icon: 'none'
});
}
});
} else {
uni.showToast({
title: res.msg || '创建订单失败',
icon: 'none'
});
}
}).catch(() => {
uni.hideLoading();
uni.showToast({
title: '网络请求失败',
icon: 'none'
});
});
}
// handlePaySuccess(points) {
// // 更新用户积分
// const pointsData = {
// userId: uni.getStorageSync('userInfo').userId,
// points: points
// }
// updateUserPoints(pointsData).then(res => {
// if(res.code === 200) {
// uni.showToast({
// title: '充值成功',
// icon: 'success'
// });
// // 更新本地存储的用户信息
// let userInfo = uni.getStorageSync('userInfo');
// userInfo.integral = (parseInt(userInfo.integral) || 0) + points;
// uni.setStorageSync('userInfo', userInfo);
// setTimeout(() => {
// uni.navigateBack();
// }, 1500);
// } else {
// uni.showToast({
// title: res.msg || '更新积分失败',
// icon: 'none'
// });
// }
// });
// }
}
}
</script>

View File

@@ -4,13 +4,13 @@
<view class="top-tile">文章搜索</view>
<image class="container" src="https://img.yidaima.cn/feast/xinkong.gif">
<view class="container-h">
悬悬而望
发现优质资源
</view>
<view class="container-slog">
愿我们都不后悔出现在彼此的世界中
软件源码与实用内容在这里轻松找到
</view>
<view class="container-search">
<uni-search-bar v-model="searchValue" style="opacity: 0.9;" radius="190" placeholder="搜索一下,爱上这个世界"
<uni-search-bar v-model="searchValue" style="opacity: 0.9;" radius="190" placeholder="搜索软件、源码、教程或关键词"
@confirm="search" cancelButton="none" bgColor="#fff" />
</view>
</image>
@@ -41,16 +41,17 @@
</view>
</view>
<view style="height: 200rpx;" v-else>
<image class="blog-img" :src="item.showImg"></image>
<image class="blog-img" :src="$image.articleThumbnail(item)" lazy-load mode="aspectFill"></image>
<view class="info-box">
<view class="ellipsis-multiline">
{{item.title}}
</view>
<view class="info-icon">
<image v-if="item.isAd == 0" class="muen-sld-icon" src="https://img.yidaima.cn/feast/guanggao.svg" mode="">
</image>
<image v-if="item.appResourceId" class="muen-sld-icon" src="https://img.yidaima.cn/feast/xiazai.svg" mode="">
</image>
<image v-if="item.appResource.isAd == 0" class="muen-sld-icon" src="https://img.yidaima.cn/mf.svg" mode=""></image>
<image v-if="item.appResource.isAd == 1" class="muen-sld-icon" src="https://img.yidaima.cn/feast/guanggao.svg" mode=""></image>
<image v-if="item.appResource.isAd == 2" class="muen-sld-icon" src="https://img.yidaima.cn/jf.svg" mode=""></image>
<image v-if="item.appResource.isAd == 3" class="muen-sld-icon" src="https://img.yidaima.cn/ff.svg" mode=""></image>
<image v-if="item.appResourceId" class="muen-sld-icon" src="https://img.yidaima.cn/feast/xiazai.svg" mode=""></image>
</view>
<view class="muen-sld-time">{{item.createTime}}<text
class="cuIcon-attention look-number"><text>{{item.lookNumber}}</text></text></view>
@@ -467,4 +468,4 @@
.info-icon {
height: 40rpx;
}
</style>
</style>

View File

@@ -38,7 +38,7 @@
<ad-custom style="height: 337rpx !important;" :unit-id="adUnitId" ad-intervals="30" ></ad-custom>
</view>
<view v-else>
<image class="grid-img" :src="item.compressImgUrl"></image>
<image class="grid-img" :src="$image.original(item.compressImgUrl)" lazy-load mode="aspectFill"></image>
<view class="info-img">
<view class="flex justify-between">
<view v-if="item.isAd != 0" class="img-type"><text class="cuIcon-rechargefill"></text> 免费获取
@@ -621,4 +621,4 @@
margin: 20rpx auto;
overflow: hidden;
}
</style>
</style>

View File

@@ -38,7 +38,7 @@
<ad-custom :unit-id="adUnitId" ad-intervals="30" ></ad-custom>
</view>
<view v-else>
<image class="grid-img" :src="item.compressImgUrl"></image>
<image class="grid-img" :src="$image.original(item.compressImgUrl)" lazy-load mode="aspectFill"></image>
<view class="info-img">
<view class="flex justify-between">
<view v-if="item.isAd != 0" class="img-type"><text class="cuIcon-rechargefill"></text> 免费获取</view>
@@ -434,4 +434,4 @@
margin: 20rpx auto;
overflow: hidden;
}
</style>
</style>

View File

@@ -60,7 +60,7 @@
<view class="goods-list">
<view class="list" v-for="(item, index) in goodsList" @click="onSkip(item)" :key="index">
<view class="pictrue">
<image :src="item.goodsImg"></image>
<image :src="$image.resourceThumbnail(item.goodsImg)" lazy-load mode="aspectFill"></image>
</view>
<view class="title-tag">
<view class="tag">
@@ -701,4 +701,4 @@
}
}
}
</style>
</style>

View File

@@ -3,7 +3,7 @@
<view class="goods-list">
<view class="list">
<view class="pictrue">
<image :src="goodsImg"></image>
<image :src="$image.original(goodsImg)" mode="aspectFill"></image>
</view>
<view class="price-info">
<view class="user-price">
@@ -474,4 +474,4 @@
}
}
}
</style>
</style>

View File

@@ -32,16 +32,18 @@
</view>
</view>
<view style="height: 200rpx;" v-else>
<image class="blog-img" :src="item.showImg"></image>
<image class="blog-img" :src="$image.articleThumbnail(item)" lazy-load mode="aspectFill"></image>
<view class="info-box">
<view class="ellipsis-multiline">
{{item.title}}
</view>
<view class="info-icon">
<image v-if="item.isAd == 0" class="muen-sld-icon" src="https://img.yidaima.cn/feast/guanggao.svg" mode="">
</image>
<image v-if="item.appResourceId" class="muen-sld-icon" src="https://img.yidaima.cn/feast/xiazai.svg" mode="">
</image>
<image v-if="item.appResource.isAd == 0" class="muen-sld-icon" src="https://img.yidaima.cn/mf.svg" mode=""></image>
<image v-if="item.appResource.isAd == 1" class="muen-sld-icon" src="https://img.yidaima.cn/feast/guanggao.svg" mode=""></image>
<image v-if="item.appResource.isAd == 2" class="muen-sld-icon" src="https://img.yidaima.cn/jf.svg" mode=""></image>
<image v-if="item.appResource.isAd == 3" class="muen-sld-icon" src="https://img.yidaima.cn/ff.svg" mode=""></image>
<image v-if="item.appResourceId" class="muen-sld-icon" src="https://img.yidaima.cn/feast/xiazai.svg" mode=""></image>
<image v-if="item.weight == 999" class="muen-sld-icon2" src="https://img.yidaima.cn/feast/top.svg" mode=""></image>
</view>
<view class="muen-sld-time">{{item.createTime}}<text
class="cuIcon-attention look-number"><text>{{item.lookNumber}}</text></text></view>

View File

@@ -32,16 +32,18 @@
</view>
</view>
<view style="height: 200rpx;" v-else>
<image class="blog-img" :src="item.showImg"></image>
<image class="blog-img" :src="$image.articleThumbnail(item)" lazy-load mode="aspectFill"></image>
<view class="info-box">
<view class="ellipsis-multiline">
{{item.title}}
</view>
<view class="info-icon">
<image v-if="item.isAd == 0" class="muen-sld-icon" src="https://img.yidaima.cn/feast/guanggao.svg" mode="">
</image>
<image v-if="item.appResourceId" class="muen-sld-icon" src="https://img.yidaima.cn/feast/xiazai.svg" mode="">
</image>
<image v-if="item.appResource.isAd == 0" class="muen-sld-icon" src="https://img.yidaima.cn/mf.svg" mode=""></image>
<image v-if="item.appResource.isAd == 1" class="muen-sld-icon" src="https://img.yidaima.cn/feast/guanggao.svg" mode=""></image>
<image v-if="item.appResource.isAd == 2" class="muen-sld-icon" src="https://img.yidaima.cn/jf.svg" mode=""></image>
<image v-if="item.appResource.isAd == 3" class="muen-sld-icon" src="https://img.yidaima.cn/ff.svg" mode=""></image>
<image v-if="item.appResourceId" class="muen-sld-icon" src="https://img.yidaima.cn/feast/xiazai.svg" mode=""></image>
<image v-if="item.weight == 999" class="muen-sld-icon2" src="https://img.yidaima.cn/feast/top.svg" mode=""></image>
</view>
<view class="muen-sld-time">{{item.createTime}}<text
class="cuIcon-attention look-number"><text>{{item.lookNumber}}</text></text></view>

View File

@@ -33,36 +33,6 @@
color: 'cyan',
cuIcon: 'https://img.yidaima.cn/zyk.png'
},
{
title: '手机壁纸',
name: 'wallpaper',
color: 'purple',
cuIcon: 'https://img.yidaima.cn/sjbz.png'
},
{
title: '电脑壁纸',
name: 'computer',
color: 'pink',
cuIcon: 'https://img.yidaima.cn/dnbz.png'
},
{
title: '精美头像',
name: 'avatar',
color: 'brown',
cuIcon: 'https://img.yidaima.cn/jmtx.png'
},
{
title: '视频资源',
name: 'video',
color: 'blue',
cuIcon: 'https://img.yidaima.cn/sp.png'
},
{
title: '水印去除',
name: 'shuiyin',
color: 'red',
cuIcon: 'https://img.yidaima.cn/sycc.png'
},
{
title: '手机软件',
name: 'phone',
@@ -74,12 +44,6 @@
name: 'software',
color: 'mauve',
cuIcon: 'https://img.yidaima.cn/dnrj.png'
},
{
title: '积分兑换',
name: 'exchange',
color: 'green',
cuIcon: 'https://img.yidaima.cn/jfdh.png'
}
],
};
@@ -110,4 +74,4 @@
background-color: #FFFFFF;
z-index: 1;
}
</style>
</style>

View File

@@ -26,12 +26,12 @@
</view>
<view v-if="dataList.length != 0" class="bg-white padding">
<view class="grid margin-bottom col-2">
<view @click="info(item.id)" v-for="(item,index) in dataList" :key="index" class="grid-box">
<view v-for="(item,index) in dataList" :key="index" class="grid-box">
<view style="width: 327rpx;height: 377rpx;background-color: white;overflow: hidden;" v-if="item.ad == 1">
<ad-custom style="height: 377rpx !important;" :unit-id="adUnitId" ad-intervals="30" ></ad-custom>
</view>
<view v-else>
<image class="grid-img" :src="item.showImg"></image>
<view v-else @click="info(item.id)">
<image class="grid-img" :src="$image.resourceThumbnail(item)" lazy-load mode="aspectFill"></image>
<view class="grid-name">{{item.resourceTitle}}</view>
<!-- <view v-if="item.isAd == 0" class="ad">激励广告</view> -->
<view class="notad">获取详情</view>
@@ -347,4 +347,4 @@
overflow: hidden;
position: relative;
}
</style>
</style>

View File

@@ -26,12 +26,12 @@
</view>
<view v-if="dataList.length != 0" class="bg-white padding">
<view class="grid margin-bottom col-2">
<view @click="info(item.id)" v-for="(item,index) in dataList" :key="index" class="grid-box">
<view v-for="(item,index) in dataList" :key="index" class="grid-box">
<view style="width: 327rpx;height: 377rpx;background-color: white;overflow: hidden;" v-if="item.ad == 1">
<ad-custom style="height: 377rpx !important;" :unit-id="adUnitId" ad-intervals="30" ></ad-custom>
</view>
<view v-else>
<image class="grid-img" :src="item.showImg"></image>
<view v-else @click="info(item.id)">
<image class="grid-img" :src="$image.resourceThumbnail(item)" lazy-load mode="aspectFill"></image>
<view class="grid-name">{{item.resourceTitle}}</view>
<!-- <view v-if="item.isAd == 0" class="ad">激励广告</view> -->
<view class="notad">获取详情</view>
@@ -348,4 +348,4 @@
overflow: hidden;
position: relative;
}
</style>
</style>

View File

@@ -1,424 +0,0 @@
<template>
<view class="content">
<view class="remove">
<view class="remove-title-clearButton">
<view class="remove-title">
<view class="remove-title-content">
<u--text bold size="18" color="#0081ff" text="快速去水印"></u--text>
</view>
<view class="remove-title-shadow">
<u--text bold color="#0081ff" text="SPEEDY"></u--text>
</view>
</view>
<view class="remove-clearButton">
<u--text @click="clearTextarea" text="清空"></u--text>
</view>
</view>
<view class="remove-textarea">
<u--textarea maxlength="180" border="none" height="140" v-model="input_url"
placeholder="请粘贴需要提取的视频/图集链接,支持抖音,快手,小红书,哔哩哔哩等 100+ 平台"></u--textarea>
</view>
<view class="remove-paste-submit-button">
<view class="remove-paste-button">
<u-button @click="pasteURL" type="primary" plain text="粘贴链接"></u-button>
</view>
<view class="remove-submit-button">
<u-button @click="getAnalysisDate" type="primary" text="立即解析"></u-button>
</view>
</view>
<view style="margin-top: 20rpx;" class="remove-question">
<view class="remove-question-black">
<u--text text="觉得好用点击右上角 “···” 分享给你的朋友吧!"></u--text>
</view>
</view>
<view class="remove-question">
<view class="remove-question-black">
<u--text text="有问题?请看"></u--text>
</view>
<view class="remove-question-blue">
<u--text decoration="underline" @click="jumpPage('/pages/tool/shuiyin/problem')" type="primary"
text="教程和问题"></u--text>
</view>
</view>
</view>
<view v-if="adUnitId" style="width: 96%; margin-top: 30rpx;margin-left: 2%;">
<ad-custom :unit-id="adUnitId" ad-intervals="30" ></ad-custom>
</view>
<!--广告确认弹窗-->
<view class="cu-modal" :class="modalName=='adModal'?'show':''">
<view style="border-radius: 30rpx;" class="cu-dialog">
<view class="cu-bar bg-white justify-end">
<view style="color: black;font-size: 38rpx;margin-top: 40rpx;" class="content">水印去除</view>
<view class="action" @tap="hideModal">
<text class="cuIcon-close text-red"></text>
</view>
</view>
<view class=" bg-white">
<view style="font-size: 33rpx;color: #6a6a6a;padding: 30rpx 60rpx 60rpx 60rpx;">
消耗 <text style="color: #3C9CFF;margin: 0 10rpx;">积分</text> 或者看 <text
style="color: #3C9CFF;margin: 0 10rpx;">视频广告</text> 之后自动获取,存储与传输成本很高不得已加入广告回回血
</view>
<button @tap="nowDownJf" style="margin-bottom: 30rpx;width: 35%;height: 70rpx;font-size: 30rpx;"
class="cu-btn bg-blue"><text style="margin-right: 15rpx;font-size: 30rpx;"
class="cuIcon-vip"></text> 消耗积分</button>
<button @tap="nowDownImg" style="margin-bottom: 40rpx;width: 35%;height: 70rpx;font-size: 30rpx;margin-left: 50rpx;"
class="cu-btn bg-blue"><text style="margin-right: 15rpx;font-size: 30rpx;"
class="cuIcon-recordfill"></text> 观看广告</button>
</view>
</view>
</view>
<u-toast ref="uToast"></u-toast>
</view>
</template>
<script>
let videoAd = null;
import {
delShuiYin,appGetUserById,exchangeResource,getConfigKey
} from "@/api/app/index.js"
export default {
data() {
return {
adUnitId: "",
adUnitId2: "",
isOpenAd: false,
videoAd_id: "",
interstitialAd_id: "",
input_url: "",
tabbarIndex: 1,
modalName: null,
needJf:6,
userId: null,
}
},
onShareAppMessage() {
return {
title: "图片视频水印快速去除支持抖音快手等100+平台",
imageUrl: "/static/appimg/share/shuiyin.jpg",
path: 'pages/tool/shuiyin',
}
},
onShareTimeline(){
return {
title:'图片视频水印快速去除支持抖音快手等100+平台',
query:{
},
imageUrl:'/static/appimg/share/shuiyin.jpg'
}
},
onLoad() {
this.adUnitId = uni.getStorageSync("sysSet").zyinfoAd
this.adUnitId2 = uni.getStorageSync("sysSet").downVideoAd
let _this = this;
this.userId = uni.getStorageSync("userInfo").userId
//获取公告
getConfigKey("miniapp.shuiyin.delintegral").then(response => {
_this.needJf = response.msg
}),
//初始化激励广告
this.CreateAd()
},
onShow() {
let _this = this;
},
methods: {
nowDownJf() {
let that = this;
this.modalName = null
uni.showModal({
title: '提示',
content: '确认要消耗 ' + that.needJf + " 积分兑换吗?",
success: function(res) {
if (res.confirm) {
// 执行确认后的操作
appGetUserById(that.userId).then(response => {
if (that.needJf > response.user.integral) {
uni.showModal({
title: '积分不足',
content: '您的积分为 '+response.user.integral+' ,签到做任务可获得积分',
cancelText: "取消",
confirmText: "获取积分",
confirmColor:'#ff0000',
cancelColor:'#000000',
success: function(res) {
if (res.confirm) {
// 执行确认后的操作
uni.switchTab({
url: '/pages/mine/index'
});
}
else {
// 执行取消后的操作
}
}
})
} else {
var formData = {
source: '视频/图片水印解析',
isAdd: 1,
integralNumber: that.needJf,
userId: that.userId,
}
exchangeResource(formData).then(response => {
that.openYse()
})
}
})
} else {
// 执行取消后的操作
}
}
})
},
hideModal() {
this.modalName = null
},
nowDownImg() {
if (videoAd) {
videoAd.show().catch(() => {
// 失败重试
videoAd.load()
.then(() => videoAd.show())
.catch(err => {
console.error('激励视频 广告显示失败', err)
})
})
}
},
CreateAd() {
var that = this;
if (this.adUnitId2 != '') {
if (wx.createRewardedVideoAd) {
videoAd = wx.createRewardedVideoAd({
adUnitId: this.adUnitId2
})
videoAd.onLoad(() => {})
videoAd.onError((err) => {
that.$refs.uToast.show({
type: 'error',
title: '',
message: "请使用移动端设备访问",
icon: false
})
})
videoAd.onClose((res) => {
if (res && res.isEnded) {
this.modalName = null
that.openYse()
} else {
this.modalName = null
//that.openYse()
}
})
}
}
},
getStrUrl(s) {
var reg = /(http:\/\/|https:\/\/)((\w|=|\?|\.|\/|&|-)+)/g;
var reg = /(https?|http|ftp|file):\/\/[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]/g;
s = s.match(reg);
return (s && s.length ? s[0] : null);
},
openYse() {
let _this = this;
uni.showLoading({
title: '解析中...',
mask: true
});
let getUrl = _this.getStrUrl(_this.input_url)
delShuiYin({
url: getUrl
}).then(response => {
var dataMsg = JSON.parse(response.msg)
uni.hideLoading()
if (dataMsg.code != 200) {
uni.showModal({
title: '提示',
content: dataMsg.msg,
showCancel: false,
confirmText: "确定",
success: function(res) {
if (res.confirm) {
// 执行确认后的操作
}
else {
// 执行取消后的操作
}
}
})
} else {
var antoInfo = dataMsg.data.data_info
if (antoInfo.code != 200) {
uni.showToast({
title: antoInfo.msg,
icon: 'none',
duration: 4000
});
}else{
uni.setStorageSync("analysisData", antoInfo)
_this.input_url = ''
if (antoInfo.pics == "") {
_this.jumpPage("/pages/tool/shuiyin/video")
} else {
_this.jumpPage("/pages/tool/shuiyin/image")
}
}
}
})
},
getAnalysisDate() {
let _this = this;
if (_this.input_url == "" || _this.input_url == null) {
uni.showToast({
title: '请填写内容后解析哦!',
icon: 'none',
duration: 2000
});
} else {
let getUrl = _this.getStrUrl(_this.input_url)
if (getUrl == null) {
uni.showToast({
title: '糟糕!您填写的内容找不到解析地址,无法解析!',
icon: 'none',
duration: 2000
});
_this.input_url = ''
return;
}
_this.modalName = 'adModal'
}
},
pasteURL() {
let _this = this;
uni.getClipboardData({
success: function(res) {
// console.log(res.data)
_this.input_url = res.data
},
fail(e) {
console.log(e)
}
})
},
clearTextarea() {
let _this = this;
uni.showModal({
title: '提示',
content: '确定要清空当前输入框吗?',
success: res => {
if (res.confirm) {
_this.input_url = ""
}
}
})
},
jumpPage(url) {
this.$tab.navigateTo(url)
}
}
}
</script>
<style lang="scss">
page {
background-color: $u-bg-color;
}
.remove {
padding: 20rpx 20rpx 20rpx 20rpx;
}
.remove-title-clearButton {
display: flex;
flex-direction: row;
justify-content: space-between;
}
.remove-textarea {
margin-top: 30rpx;
border-radius: 25rpx;
background-color: #f8f8f8;
box-shadow: 0px 5px 5px 0px #EDEDED;
}
.remove-clearButton {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
}
.remove-title {
position: relative;
}
.remove-title-shadow {
position: absolute;
bottom: -20rpx;
font-style: italic;
opacity: 0.4;
padding-left: 10rpx;
}
.u-textarea[data-v-09988a29] {
border-radius: 12px;
background-color: #fff;
position: relative;
display: flex;
flex-direction: row;
flex: 1;
padding: 9px;
}
.remove-paste-submit-button {
padding-top: 35rpx;
display: flex;
flex-direction: row;
justify-content: space-between;
}
.remove-paste-button,
.remove-submit-button {
width: 45%;
box-shadow: 3px 3px 4px rgba(0, 102, 204, 0.2);
}
.remove-question {
width: 100%;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
padding-top: 10rpx;
}
.remove-question-black {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
padding-right: 10rpx;
}
.remove-question-blue {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
}
.ad-show {
width: 100%;
padding-top: 30rpx;
}
</style>

View File

@@ -1,286 +0,0 @@
<template>
<view class="body">
<view v-if="adUnitId" style="width: 94%; margin-left: 3%;">
<ad-custom :unit-id="adUnitId" ad-intervals="30" ></ad-custom>
</view>
<view class="contents">
<view class="imagesContent">
<view class="titleContent">
<view class="title-content">
<u--text bold size="18" color="#0081ff" text="图集"></u--text>
</view>
<view class="title-shadow">
<u--text bold color="#0081ff" text="IMAGES"></u--text>
</view>
</view>
<view class="imagesContent-images">
<u-swiper @change="imageCurrentChange" imgMode="aspectFit" height="400" :list="imagesList"
previousMargin="30" nextMargin="30" circular :autoplay="false" radius="5" current="imageCurrent"
indicatorMode="dot" indicator indicatorInactiveColor="#3c9cff" indicatorActiveColor="red"
bgColor="#ffffff"></u-swiper>
</view>
<view class="imagesContent-buttonGroup">
<view class="imagesContent-buttonGroup-top">
<view class="imagesContent-buttonGroup-left">
<u-button @click="copyImageUrl" type="primary" plain text="复制链接"></u-button>
</view>
<view class="imagesContent-buttonGroup-right">
<u-button @click="download(imagesList[imageCurrent])" type="primary" text="下载单张"></u-button>
</view>
</view>
<view class="imagesContent-buttonGroup-bottom">
<u-button @click="downloadAll" type="primary" text="下载全部"></u-button>
</view>
</view>
</view>
<view class="copywritingContent">
<view class="titleContent">
<view class="title-content">
<u--text bold size="18" color="#0081ff" text="文案"></u--text>
</view>
<view class="title-shadow">
<u--text bold color="#0081ff" text="TITLE"></u--text>
</view>
</view>
<view class="copywritingContent-textarea">
<u--textarea maxlength="180" height="140" v-model="copywriting" placeholder="文案内容"></u--textarea>
</view>
<view class="copywritingContent-button">
<u-button @click="copyText(copywriting)" type="primary" text="复制文案"></u-button>
</view>
</view>
</view>
</view>
</template>
<script>
import {
addNewDownloadUrl
} from "@/api/app/index.js"
export default {
data() {
return {
adUnitId:"",
imageCurrent: 0,
isOpenAd: false,
videoAd_id: "",
imagesList: [],
copywriting: ""
}
},
onLoad() {
let _this = this;
this.adUnitId = uni.getStorageSync("sysSet").wzinfoAd
uni.getStorage({
key: 'analysisData',
success: function(res) {
_this.imagesList = res.data.pics
_this.copywriting = res.data.title
}
})
},
methods: {
imageCurrentChange(e) {
let _this = this;
_this.imageCurrent = e.current
},
copyImageUrl() {
let _this = this;
// console.log(this.imageCurrent)
_this.copyText(_this.imagesList[_this.imageCurrent])
},
downloadAll() {
let _this = this;
for (let i = 0; i < _this.imagesList.length; i++) {
_this.download(_this.imagesList[i])
}
},
download(url) {
let _this = this;
const downloadTask = uni.downloadFile({
url: url.replace('http://', 'https://'), //仅为示例,并非真实的资源
success: (downloadRes) => {
if (downloadRes.statusCode === 200) {
console.log('下载成功');
uni.saveImageToPhotosAlbum({
filePath: downloadRes.tempFilePath,
success() {
uni.hideLoading()
uni.showToast({
icon: "success",
title: "下载成功!"
})
},
fail: function(err) {
uni.hideLoading();
console.log(err)
if (err.errMsg === "saveImageToPhotosAlbum:fail:auth denied" ||
err
.errMsg === "saveImageToPhotosAlbum:fail auth deny" || err
.errMsg ===
"saveImageToPhotosAlbum:fail authorize no response"
) {
// 这边微信做过调整,必须要在按钮中触发,因此需要在弹框回调中进行调用
uni.showModal({
title: '提示',
content: '需要您授权保存相册',
showCancel: false,
success: modalSuccess => {
uni.openSetting({
success(settingdata) {
console.log(
"settingdata",
settingdata)
if (settingdata
.authSetting[
'scope.writePhotosAlbum'
]) {
uni.showModal({
title: '提示',
content: '获取权限成功,再次点击图片即可保存',
showCancel: false,
})
} else {
uni.showModal({
title: '提示',
content: '获取权限失败,将无法保存到相册哦~',
showCancel: false,
})
}
},
fail(failData) {
console.log("failData",
failData)
},
complete(finishData) {
console.log(
"finishData",
finishData)
}
})
}
})
}
}
})
}
},
fail: (err) => {
uni.hideLoading()
if (err.errMsg.includes("fail url not in domain list")) {
addNewDownloadUrl(url.replace(/^https?:\/\/(.*?)(:\d+)?\/.*$/, '$1')).then(response => {}),
uni.showModal({
title: '提示',
content: '因为微信限制,下载失败,可以通过浏览器链接下载,是否复制链接自行去浏览器下载?',
success: (modalRes) => {
if (modalRes.confirm) {
_this.copyText(url)
}
}
});
} else {
uni.showModal({
title: '提示',
content: '下载失败了',
showCancel: false,
})
}
// console.log(err)
}
});
downloadTask.onProgressUpdate((downloadTaskRes) => {
uni.showLoading({
title: '下载进度' + downloadTaskRes.progress + '%',
mask:true
})
})
},
copyText(text) {
uni.setClipboardData({
data: text,
success: function(res) {
uni.showToast({
title: '复制成功',
});
},
fail() {
uni.showToast({
icon: "error",
title: '复制失败了'
});
}
});
}
}
}
</script>
<style lang="scss">
page {
background-color: $u-bg-color;
}
.ad-show {
width: 100%;
}
.contents {
padding: 20rpx 20rpx;
}
.imagesContent,
.copywritingContent {
margin-top: 30rpx;
padding: 30rpx 20rpx;
box-shadow: 3px 3px 4px rgba(26, 26, 26, 0.2);
background-color: white;
border-radius: 7px;
}
.titleContent {
position: relative;
}
.title-shadow {
position: absolute;
bottom: -20rpx;
font-style: italic;
opacity: 0.4;
padding-left: 10rpx;
}
.imagesContent-images,
.copywritingContent-textarea {
padding: 0 16rpx;
margin-top: 40rpx;
}
.imagesContent-buttonGroup {
padding-left: 20rpx;
padding-right: 20rpx;
padding-top: 30rpx;
display: flex;
flex-direction: column;
}
.imagesContent-buttonGroup-top {
display: flex;
flex-direction: row;
justify-content: space-between;
}
.imagesContent-buttonGroup-bottom,
.copywritingContent-button {
padding-top: 25rpx;
width: 100%;
box-shadow: 3px 3px 4px rgba(0, 102, 204, 0.2);
}
.imagesContent-buttonGroup-left,
.imagesContent-buttonGroup-right {
width: 45%;
box-shadow: 3px 3px 4px rgba(0, 102, 204, 0.2);
}
</style>

View File

@@ -1,170 +0,0 @@
<template>
<view class="body">
<view class="course">
<view class="course-title">
<view class="title-content">
<u--text bold size="18" color="#0081ff" text="使用教程"></u--text>
</view>
<view class="title-shadow">
<u--text bold color="#0081ff" text="COURSE"></u--text>
</view>
</view>
<view class="course-body">
<view class="course-body-view">
<view class="course-body-view-title">
<u--text size="16" :text="courseTitle1"></u--text>
</view>
<view class="course-body-view-contents">
<view class="introduction-content">
<u--text size="14" :text="courseContent1"></u--text>
</view>
<view class="introduction-content-images">
<view class="introduction-content-image">
<u--image :showLoading="true" :src="showPic1_1" width="160px" height="160px"></u--image>
</view>
<view class="introduction-content-image">
<u--image :showLoading="true" :src="showPic1_2" width="160px" height="160px"></u--image>
</view>
</view>
</view>
</view>
<view class="course-body-view">
<view class="course-body-view-title">
<u--text size="16" :text="courseTitle2"></u--text>
</view>
<view class="course-body-view-contents">
<view class="introduction-content">
<u--text size="14" :text="courseContent2_1"></u--text>
</view>
<view class="introduction-content">
<u--text size="14" :text="courseContent2_2"></u--text>
</view>
<view class="introduction-content">
<u--text size="14" :text="courseContent2_3"></u--text>
</view>
<u--text type="error" size="14" :text="promptTitle"></u--text>
</view>
</view>
</view>
</view>
<view class="problem">
<view class="problem-title">
<view class="title-content">
<u--text bold size="18" color="#0081ff" text="常见问题"></u--text>
</view>
<view class="title-shadow">
<u--text bold color="#0081ff" text="PROBLEM"></u--text>
</view>
</view>
<view class="problem-body">
<view v-for="(item,index) in proContentList" :key="index" class="problem-body-view">
<view class="problem-body-view-title">
<u--text size="16" :text="item.problemTitle"></u--text>
</view>
<view class="problem-body-view-contents">
<view class="introduction-content">
<u--text size="14" :text="item.problemContent"></u--text>
</view>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
courseTitle1: "01 如何复制视频链接",
courseContent1: "打开您的APP然后点击分享就会出现一个复制链接的选项点击复制链接(注意链接不要超过150字),然后来到小程序,粘贴链接再点解析就可以去水印了。",
showPic1_1: "https://www.myazurepicture.llgulugulu.top/api/picture/getImageByte?pid=075b593ed4c9000d027a9ce83936d815",
showPic1_2: "https://www.myazurepicture.llgulugulu.top/api/picture/getImageByte?pid=8e2e0e22653ab150c40fb1c0a12ecc56",
courseTitle2: "02 为什么下载失败",
courseContent2_1: "由于手机系统及微信的安全机制视频大小不能超过10M左右所以超过这个大小的视频需要解析成功后复制无水印链接到浏览器下载。",
courseContent2_2: "1、如果您是安卓手机直接复制无水印链接然后任意一个浏览器打开即可。",
courseContent2_3: "2、如果您是苹果手机需要下载软件 documents 才能在浏览器中进行下载视频。",
promptTitle: "温馨提示:进入下载界面请及时下载!若退出重新进入需要花费新的积分!",
proContentList: [{
problemTitle: "1、无法下载视频",
problemContent: "请先授权保存到手机相册的权限。由于手机系统及微信的安全机制视频大小不能超过10M左右所以超过这个大小的视频需要解析成功后复制无水印链接到浏览器下载。"
},
{
problemTitle: "2、为什么下载视频那么慢",
problemContent: "有些视频比较长,或者多人同时下载,会导致下载速度缓慢,可以点击旁边的【复制链接】按钮到手机浏览器上打开即可使用手机上的网速下载。"
},
{
problemTitle: "3、提示域名不合法等无法下载视频",
problemContent: "因为微信小程序需要配置download域名没有配置的则不能下载在您遇到不能下载的时候会记录此时的域名后续会手动加上。可以在解析成功后点击下载按钮旁边的【复制链接】按钮粘贴到手机浏览器打开即可下载。"
},
{
problemTitle: "4、为什么视频成功解析了还有水印",
problemContent: "视频自带的无法去除哦如果这个视频在该平台APP直接播放是没有水印的解析后却有水印请联系客服。"
},
{
problemTitle: "5、为什么小程序突然不能使用了显示网络错误",
problemContent: "因为每天的凌晨3点到3点半系统会进行自我维护这段时间暂时不可用其他时间段不能用请联系客服。"
},
]
}
}
}
</script>
<style lang="scss">
page {
background-color: $u-bg-color;
}
.course,
.problem {
padding: 20rpx 20rpx 5rpx 20rpx;
}
.course-title,
.problem-title {
position: relative;
}
.title-shadow {
position: absolute;
bottom: -20rpx;
font-style: italic;
opacity: 0.4;
padding-left: 10rpx;
}
.course-body,
.problem-body {
padding-top: 10rpx;
}
.course-body-view,
.problem-body-view {
padding-top: 20rpx;
}
.course-body-view-title,
.problem-body-view-title {
padding-bottom: 6rpx;
}
.introduction-content {
padding-top: 5rpx;
padding-bottom: 5rpx;
text-indent: 2em;
}
.introduction-content-images {
display: flex;
flex-direction: row;
}
.introduction-content-image {
width: 50%;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
}
</style>

View File

@@ -1,421 +0,0 @@
<template>
<view class="body">
<view v-if="adUnitId" style="width: 94%; margin-left: 3%;">
<ad-custom :unit-id="adUnitId" ad-intervals="30" ></ad-custom>
</view>
<view class="contents">
<view class="videoContent">
<view class="titleContent">
<view class="title-content">
<u--text bold size="18" color="#0081ff" text="视频"></u--text>
</view>
<view class="title-shadow">
<u--text bold color="#0081ff" text="VIDEO"></u--text>
</view>
</view>
<view class="videoContent-video">
<video :src="videoUrl" class="video" @error="videoErrorCallback"></video>
</view>
<view class="videoContent-buttonGroup">
<view class="videoContent-buttonGroup-left">
<u-button @click="copyText(videoUrl)" type="primary" plain text="复制链接"></u-button>
</view>
<view class="videoContent-buttonGroup-right">
<u-button @click="downloadVideo(videoUrl)" type="primary" text="保存视频"></u-button>
</view>
</view>
<view class="videoContent-problem">
<u--text @click="showTips" align="center" type="primary" decoration="underline"
text="下载失败?点我查看解决方案"></u--text>
</view>
</view>
<view class="coverContent">
<view class="titleContent">
<view class="title-content">
<u--text bold size="18" color="#0081ff" text="封面"></u--text>
</view>
<view class="title-shadow">
<u--text bold color="#0081ff" text="COVER"></u--text>
</view>
</view>
<view class="coverContent-image">
<u--image radius="7" mode="widthFix" :src="coverUrl" width="100%" height="auto"></u--image>
</view>
<view class="coverContent-buttonGroup">
<view class="coverContent-buttonGroup-left">
<u-button @click="copyText(coverUrl)" type="primary" plain text="复制链接"></u-button>
</view>
<view class="coverContent-buttonGroup-right">
<u-button @click="downloadImage(coverUrl)" type="primary" text="保存封面"></u-button>
</view>
</view>
</view>
<view class="copywritingContent">
<view class="titleContent">
<view class="title-content">
<u--text bold size="18" color="#0081ff" text="文案"></u--text>
</view>
<view class="title-shadow">
<u--text bold color="#0081ff" text="TITLE"></u--text>
</view>
</view>
<view class="copywritingContent-textarea">
<u--textarea maxlength="180" height="140" v-model="copywriting" placeholder="文案内容"></u--textarea>
</view>
<view class="copywritingContent-button">
<u-button @click="copyText(copywriting)" type="primary" text="复制文案"></u-button>
</view>
</view>
</view>
<u-toast ref="uToast"></u-toast>
</view>
</template>
<script>
// var App = require("@/common.js");
import {
addNewDownloadUrl
} from "@/api/app/index.js"
export default {
data() {
return {
adUnitId:"",
isOpenAd: false,
videoAd_id: "",
videoUrl: "",
audioUrl: "",
coverUrl: "",
copywriting: "",
}
},
onLoad() {
let _this = this;
this.adUnitId = uni.getStorageSync("sysSet").wzinfoAd
uni.getStorage({
key: 'analysisData',
success: function(res) {
console.log(res)
_this.videoUrl = res.data.url
_this.coverUrl = res.data.img
_this.copywriting = res.data.title
}
})
},
methods: {
downloadImage(url) {
let _this = this;
const downloadTask = uni.downloadFile({
url: url.replace('http://', 'https://'), //仅为示例,并非真实的资源
success: (downloadRes) => {
if (downloadRes.statusCode === 200) {
console.log('下载成功');
uni.saveImageToPhotosAlbum({
filePath: downloadRes.tempFilePath,
success() {
uni.hideLoading()
uni.showToast({
icon: "success",
title: "下载成功!"
})
},
fail: function(err) {
uni.hideLoading();
if (err.errMsg === "saveImageToPhotosAlbum:fail:auth denied" ||
err
.errMsg === "saveImageToPhotosAlbum:fail auth deny" || err
.errMsg ===
"saveImageToPhotosAlbum:fail authorize no response"
) {
// 这边微信做过调整,必须要在按钮中触发,因此需要在弹框回调中进行调用
uni.showModal({
title: '提示',
content: '需要您授权保存相册',
showCancel: false,
success: modalSuccess => {
uni.openSetting({
success(settingdata) {
console.log(
"settingdata",
settingdata)
if (settingdata
.authSetting[
'scope.writePhotosAlbum'
]) {
uni.showModal({
title: '提示',
content: '获取权限成功,再次点击图片即可保存',
showCancel: false,
})
} else {
uni.showModal({
title: '提示',
content: '获取权限失败,将无法保存到相册哦~',
showCancel: false,
})
}
},
fail(failData) {
console.log("failData",
failData)
},
complete(finishData) {
console.log(
"finishData",
finishData)
}
})
}
})
}
}
})
}
},
fail: (err) => {
uni.hideLoading()
if (err.errMsg.includes("fail url not in domain list")) {
// App._get("/api/download/addNewDownloadUrl", {
// url: url.replace(/^https?:\/\/(.*?)(:\d+)?\/.*$/, '$1')
// }, res => {
// })
addNewDownloadUrl(url.replace(/^https?:\/\/(.*?)(:\d+)?\/.*$/, '$1')).then(response => {}),
uni.showModal({
title: '提示',
content: '因为微信限制,下载失败,可以通过浏览器链接下载,是否复制链接自行去浏览器下载?',
success: (modalRes) => {
if (modalRes.confirm) {
_this.copyText(url)
}
}
});
} else {
uni.showModal({
title: '提示',
content: '下载失败了',
showCancel: false,
})
}
// console.log(err)
}
});
downloadTask.onProgressUpdate((downloadTaskRes) => {
uni.showLoading({
title: '下载进度' + downloadTaskRes.progress + '%',
mask: true
})
})
},
downloadVideo(url) {
let _this = this;
this.$refs.uToast.show({
type: 'success',
title: '',
message: "下载中,请稍等 ",
icon: false
})
const downloadTask = uni.downloadFile({
url: url.replace('http://', 'https://'), //仅为示例,并非真实的资源
success: (downloadRes) => {
if (downloadRes.statusCode === 200) {
console.log('下载成功');
uni.saveVideoToPhotosAlbum({
filePath: downloadRes.tempFilePath,
success() {
uni.hideLoading()
uni.showToast({
icon: "success",
title: "下载成功!"
})
},
fail: function(err) {
uni.hideLoading();
if (err.errMsg === "saveImageToPhotosAlbum:fail:auth denied" ||
err
.errMsg === "saveImageToPhotosAlbum:fail auth deny" || err
.errMsg ===
"saveImageToPhotosAlbum:fail authorize no response"
) {
// 这边微信做过调整,必须要在按钮中触发,因此需要在弹框回调中进行调用
uni.showModal({
title: '提示',
content: '需要您授权保存相册',
showCancel: false,
success: modalSuccess => {
uni.openSetting({
success(settingdata) {
console.log(
"settingdata",
settingdata)
if (settingdata
.authSetting[
'scope.writePhotosAlbum'
]) {
uni.showModal({
title: '提示',
content: '获取权限成功,再次点击图片即可保存',
showCancel: false,
})
} else {
uni.showModal({
title: '提示',
content: '获取权限失败,将无法保存到相册哦~',
showCancel: false,
})
}
},
fail(failData) {
console.log("failData",
failData)
},
complete(finishData) {
console.log(
"finishData",
finishData)
}
})
}
})
}
}
})
}
},
fail: (err) => {
uni.hideLoading()
if (err.errMsg.includes("fail url not in domain list")) {
// App._get("/api/download/addNewDownloadUrl", {
// url: url.replace(/^https?:\/\/(.*?)(:\d+)?\/.*$/, '$1')
// }, res => {
// })
addNewDownloadUrl(url.replace(/^https?:\/\/(.*?)(:\d+)?\/.*$/, '$1')).then(response => {}),
uni.showModal({
title: '提示',
content: '因为微信限制,下载失败,可以通过浏览器链接下载,是否复制链接自行去浏览器下载?',
success: (modalRes) => {
if (modalRes.confirm) {
_this.copyText(url)
}
}
});
} else {
uni.showModal({
title: '提示',
content: '下载失败了',
showCancel: false,
})
}
// console.log(err)
}
});
downloadTask.onProgressUpdate((downloadTaskRes) => {
uni.showLoading({
title: '下载进度' + downloadTaskRes.progress + '%',
mask: true
})
})
},
videoErrorCallback: function(e) {
// console.log(e)
uni.showModal({
content: e.mp["@warning"],
showCancel: false
})
},
showTips() {
uni.showModal({
showCancel: false,
content: '点击“复制链接”到浏览器打开即可下载推荐使用QQ浏览器打开'
})
},
copyText(text) {
uni.setClipboardData({
data: text,
success: function(res) {
uni.showToast({
title: '复制成功',
});
},
fail() {
uni.showToast({
icon: "error",
title: '复制失败了'
});
}
});
}
}
}
</script>
<style lang="scss">
page {
background-color: $u-bg-color;
}
.ad-show {
width: 100%;
}
.contents {
padding: 20rpx 20rpx;
}
.videoContent,
.coverContent,
.copywritingContent {
margin-top: 30rpx;
padding: 30rpx 20rpx;
box-shadow: 3px 3px 4px rgba(26, 26, 26, 0.2);
background-color: white;
border-radius: 7px;
}
.titleContent {
position: relative;
}
.title-shadow {
position: absolute;
bottom: -20rpx;
font-style: italic;
opacity: 0.4;
padding-left: 10rpx;
}
.video {
width: 100%;
border-radius: 8px;
}
.videoContent-video,
.coverContent-image,
.copywritingContent-textarea {
padding: 0 16rpx;
margin-top: 40rpx;
}
.videoContent-buttonGroup,
.coverContent-buttonGroup,
.copywritingContent-button {
padding-left: 20rpx;
padding-right: 20rpx;
padding-top: 30rpx;
display: flex;
flex-direction: row;
justify-content: space-between;
}
.videoContent-buttonGroup-left,
.videoContent-buttonGroup-right,
.coverContent-buttonGroup-left,
.coverContent-buttonGroup-right {
width: 45%;
box-shadow: 3px 3px 4px rgba(0, 102, 204, 0.2);
}
.videoContent-problem {
margin-top: 30rpx;
}
</style>

View File

@@ -26,12 +26,12 @@
</view>
<view v-if="dataList.length != 0" class="bg-white padding">
<view class="grid margin-bottom col-2">
<view @click="info(item.id)" v-for="(item,index) in dataList" :key="index" class="grid-box">
<view v-for="(item,index) in dataList" :key="index" class="grid-box">
<view style="width: 327rpx;height: 377rpx;background-color: white;overflow: hidden;" v-if="item.ad == 1">
<ad-custom style="height: 377rpx !important;" :unit-id="adUnitId" ad-intervals="30" ></ad-custom>
</view>
<view v-else>
<image class="grid-img" :src="item.showImg"></image>
<view v-else @click="info(item.id)">
<image class="grid-img" :src="$image.resourceThumbnail(item)" lazy-load mode="aspectFill"></image>
<view class="grid-name">{{item.resourceTitle}}</view>
<!-- <view v-if="item.isAd == 0" class="ad">激励广告</view> -->
<view class="notad">获取详情</view>
@@ -347,4 +347,4 @@
overflow: hidden;
position: relative;
}
</style>
</style>

View File

@@ -38,7 +38,7 @@
<ad-custom style="height: 655rpx !important;" :unit-id="adUnitId" ad-intervals="30" ></ad-custom>
</view>
<view v-else>
<image class="grid-img" :src="item.compressImgUrl"></image>
<image class="grid-img" :src="$image.original(item.compressImgUrl)" lazy-load mode="aspectFill"></image>
<view class="info-img">
<view class="flex justify-between">
<view v-if="item.isAd != 0" class="img-type"><text class="cuIcon-rechargefill"></text> 免费获取</view>
@@ -440,4 +440,4 @@
margin: 20rpx auto;
overflow: hidden;
}
</style>
</style>

View File

@@ -1,6 +1,7 @@
import tab from './tab'
import auth from './auth'
import modal from './modal'
import image from '@/utils/image'
export default {
install(Vue) {
@@ -10,5 +11,7 @@ export default {
Vue.prototype.$auth = auth
// 模态框对象
Vue.prototype.$modal = modal
// CDN image normalization and responsive thumbnail helpers
Vue.prototype.$image = image
}
}

BIN
static/home/index-bg.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

69
utils/image.js Normal file
View File

@@ -0,0 +1,69 @@
const CDN_HOST = 'img.yidaima.cn'
// JPEG is used deliberately here. Some older iOS/WeChat image decoders cannot
// display the WebP thumbnails returned by Qiniu.
const ARTICLE_CARD = 'imageView2/1/w/600/h/375/format/jpg/q/75/ignore-error/1'
const RESOURCE_CARD = 'imageView2/1/w/500/h/400/format/jpg/q/75/ignore-error/1'
function original(url) {
if (!url || typeof url !== 'string') {
return url || ''
}
const value = url.trim()
const httpPrefix = `http://${CDN_HOST}/`
if (value.indexOf(httpPrefix) === 0) {
return `https://${value.substring('http://'.length)}`
}
if (value.indexOf(`//${CDN_HOST}/`) === 0) {
return `https:${value}`
}
return value
}
function qiniuThumbnail(url, operation) {
const normalized = original(url)
if (!normalized || normalized.indexOf(`https://${CDN_HOST}/`) !== 0) {
return normalized
}
// Keep signed or already processed URLs intact.
if (normalized.indexOf('?') >= 0) {
return normalized
}
return `${normalized}?${operation}`
}
function compatibleThumbnail(url) {
const normalized = original(url)
if (!normalized) {
return ''
}
// The API may still return a cached showImgThumb containing format/webp.
// Rewrite that Qiniu operation on the client while the backend rolls over.
if (normalized.indexOf(`https://${CDN_HOST}/`) === 0) {
return normalized.replace(/\/format\/webp(?=\/|$)/i, '/format/jpg')
}
return normalized
}
function articleThumbnail(image) {
if (image && typeof image === 'object') {
return compatibleThumbnail(image.showImgThumb) || qiniuThumbnail(image.showImg, ARTICLE_CARD)
}
return qiniuThumbnail(image, ARTICLE_CARD)
}
function resourceThumbnail(image) {
if (image && typeof image === 'object') {
return compatibleThumbnail(image.showImgThumb) || qiniuThumbnail(image.showImg, RESOURCE_CARD)
}
return qiniuThumbnail(image, RESOURCE_CARD)
}
export default {
original,
compatibleThumbnail,
articleThumbnail,
resourceThumbnail
}

View File

@@ -35,6 +35,7 @@ const request = config => {
let [error, res] = response
if (error) {
toast('请返回重试')
uni.hideLoading()
reject('请返回重试')
return
}
@@ -48,21 +49,27 @@ const request = config => {
})
}
})
uni.hideLoading()
reject('无效的会话,或者会话已过期,请重新登录。')
return
} else if (code === 500) {
setTimeout(()=>{
toast(msg)
},200);
uni.hideLoading()
reject('500')
return
} else if (code !== 200) {
toast(msg)
uni.hideLoading()
reject(code)
return
}
resolve(res.data)
uni.hideLoading()
})
.catch(error => {
let { message } = error
let message = error && error.message ? error.message : '请求失败'
if (message === 'Network Error') {
message = '后端接口连接异常'
} else if (message.includes('timeout')) {