Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
U
uniapp_vedio
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
android
uniapp_vedio
Commits
64d49eb9
Commit
64d49eb9
authored
May 31, 2024
by
jyx
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
代码优化
parent
afe8cef8
Changes
35
Hide whitespace changes
Inline
Side-by-side
Showing
35 changed files
with
1923 additions
and
2683 deletions
+1923
-2683
App.vue
vedio/App.vue
+6
-2
index.js
vedio/common/services/index.js
+325
-322
userServices.js
vedio/common/services/userServices.js
+28
-17
apiRequest.js
vedio/common/utils/apiRequest.js
+26
-23
storageUtil.js
vedio/common/utils/storageUtil.js
+42
-33
book-search-box.vue
vedio/components/book-search-box/book-search-box.vue
+64
-63
bookshelf-list.vue
vedio/components/bookshelf/components/bookshelf-list.vue
+4
-3
c-list.vue
vedio/components/c-list/c-list.vue
+2
-2
warehouse-list.vue
vedio/components/warehouse/components/warehouse-list.vue
+2
-2
index.js
vedio/components/warehouse/services/index.js
+1
-1
warehouse.vue
vedio/components/warehouse/warehouse.vue
+8
-8
develop.js
vedio/config/env/develop.js
+1
-1
product.js
vedio/config/env/product.js
+1
-1
book-content.vue
vedio/page-subs/sub_A/book-content/book-content.vue
+24
-19
detail-buy.vue
vedio/page-subs/sub_A/book-content/components/detail-buy.vue
+9
-9
vip-pop.vue
vedio/page-subs/sub_A/book-content/components/vip-pop.vue
+5
-5
index.js
vedio/page-subs/sub_A/book-content/services/index.js
+110
-101
search-header-bar.vue
...e-subs/sub_A/book-search/components/search-header-bar.vue
+115
-114
search-placeholder.vue
...-subs/sub_A/book-search/components/search-placeholder.vue
+2
-1
search-result.vue
.../page-subs/sub_A/book-search/components/search-result.vue
+88
-88
index.js
vedio/page-subs/sub_A/book-search/services/index.js
+72
-65
vip-apply.vue
vedio/page-subs/sub_B/vip-apply/vip-apply.vue
+5
-5
home.vue
vedio/pages/home.vue
+1
-1
loading.vue
vedio/pages/loading.vue
+18
-8
common.scss
vedio/scss/common.scss
+13
-0
changelog.md
vedio/uni_modules/uni-easyinput/changelog.md
+113
-0
common.js
..._modules/uni-easyinput/components/uni-easyinput/common.js
+54
-0
uni-easyinput.vue
.../uni-easyinput/components/uni-easyinput/uni-easyinput.vue
+693
-0
package.json
vedio/uni_modules/uni-easyinput/package.json
+88
-0
changelog.md
vedio/uni_modules/yingbing-flip/changelog.md
+0
-10
flip.wxs
vedio/uni_modules/yingbing-flip/components/modules/flip.wxs
+0
-367
flip_bindingx.js
...modules/yingbing-flip/components/modules/flip_bindingx.js
+0
-546
yingbing-flip.vue
.../yingbing-flip/components/yingbing-flip/yingbing-flip.vue
+0
-420
util.js
vedio/uni_modules/yingbing-flip/js_sdk/util.js
+0
-446
utils.js
vedio/utils/utils.js
+3
-0
No files found.
vedio/App.vue
View file @
64d49eb9
<
script
>
import
{
PAKEAGE_NAME
}
from
'./utils/utils.js'
;
import
checkUpdate
from
'./utils/update.js'
;
export
default
{
onLaunch
:
function
(
options
)
{
...
...
@@ -86,7 +89,7 @@
bottomSafePadding
:
12
,
h5Url
:
'https://api.mints-id.com/index.html'
,
baseUrl
:
'https://dx.mints-tech.cn/minip-api/miniApi'
,
// baseUrl: 'http://192.168.110.
71:8301/minip-api
/miniApi',
// baseUrl: 'http://192.168.110.
42:8303
/miniApi',
titleButtonWidth
:
38
,
token
:
''
,
userId
:
0
,
...
...
@@ -96,7 +99,7 @@
versionName
:
'v 1.0.0'
,
auth
:
false
,
// 三要素实名认证
userInfo
:
null
,
pkgName
:
'com.duben.dybookhm'
pkgName
:
PAKEAGE_NAME
}
};
</
script
>
...
...
@@ -118,4 +121,5 @@
@import
'./scss/agreement.scss'
;
@import
"@/uni_modules/uview-ui/index.scss"
;
@import
'@/uni.scss'
;
@import
'@/static/readiconfont.css'
;
</
style
>
\ No newline at end of file
vedio/common/services/index.js
View file @
64d49eb9
const
{
postNotification
,
addNormalNotificationObserver
,
removeNotificationObserver
}
=
require
(
"../utils/notificationCenter"
);
import
Dict
from
"../models/Dict.js"
;
import
{
apiPOST
,
apiGET
}
from
"../utils/apiRequest.js"
import
{
readStorage
,
saveStorage
}
from
"../utils/storageUtil.js"
;
import
{
dateFormat
,
stringToDate
}
from
"../utils/timeUtil.js"
;
import
{
isEmpty
}
from
"../utils/util.js"
;
/** ================= 阅读时间 ================= */
let
READ_TIME_COUNT_MAP
=
null
;
let
KEY_STORAGE_READ_TIME_COUNT
=
"READ_TIME_COUNT"
;
/**
* 读取阅读时间计时
*/
function
getReadTimeCount
()
{
if
(
!
READ_TIME_COUNT_MAP
)
{
READ_TIME_COUNT_MAP
=
readStorage
(
KEY_STORAGE_READ_TIME_COUNT
)
||
{}
}
let
date
=
dateFormat
(
new
Date
(),
"yyyy-MM-dd"
);
let
count
=
READ_TIME_COUNT_MAP
[
date
]
||
0
;
return
count
;
}
/**
* 存储阅读时间计时
*/
function
setReadTimeCount
(
count
)
{
if
(
!
READ_TIME_COUNT_MAP
)
{
READ_TIME_COUNT_MAP
=
readStorage
(
KEY_STORAGE_READ_TIME_COUNT
)
||
{}
}
let
date
=
dateFormat
(
new
Date
(),
"yyyy-MM-dd"
);
let
result
=
READ_TIME_COUNT_MAP
[
date
]
||
0
;
result
=
result
+
count
;
READ_TIME_COUNT_MAP
[
date
]
=
result
;
saveStorage
(
KEY_STORAGE_READ_TIME_COUNT
,
READ_TIME_COUNT_MAP
);
}
let
startReadTime
=
null
;
// 开始阅读时间
/**
* 开始阅读计时
*/
function
startCountReadTime
()
{
startReadTime
=
new
Date
();
}
/**
* 停止阅读计时
*/
function
endCountReadTime
()
{
if
(
!
startReadTime
)
return
;
let
endReadTime
=
new
Date
();
let
start
=
dateFormat
(
startReadTime
,
"yyyy-MM-dd"
);
start
=
start
.
split
(
"-"
);
let
end
=
dateFormat
(
endReadTime
,
"yyyy-MM-dd"
);
end
=
end
.
split
(
"-"
);
let
isSameDay
=
true
;
start
.
forEach
((
item
,
index
)
=>
{
if
(
item
!=
end
[
index
])
{
isSameDay
=
false
;
}
})
let
count
=
0
;
if
(
isSameDay
)
{
count
=
endReadTime
.
getTime
()
-
startReadTime
.
getTime
();
}
else
{
let
dayStart
=
stringToDate
(
end
.
join
(
"-"
))
count
=
endReadTime
.
getTime
()
-
dayStart
.
getTime
();
}
startReadTime
=
null
;
setReadTimeCount
(
count
);
}
/** ================= 收藏 ================= */
const
KEY_NOTIFICATION_COLLECTION_CHANGE
=
'COLLECTION_CHANGE'
;
/**
* 收藏列表变动通知
* @param {Object} bookId
* @param {Object} isCollect
*/
function
noticeCollectionListChange
(
bookId
,
isCollect
)
{
postNotification
(
KEY_NOTIFICATION_COLLECTION_CHANGE
,
{
bookId
,
isCollect
});
}
/**
* 收藏列表变动监听
* @param {Object} fn
* @param {Object} observer
*/
function
watchCollectionChange
(
fn
,
observer
)
{
addNormalNotificationObserver
(
KEY_NOTIFICATION_COLLECTION_CHANGE
,
fn
,
observer
);
}
/**
* 移除收藏列表变动监听
* @param {Object} observer
*/
function
removeCollectionChangeWatch
(
observer
)
{
removeNotificationObserver
(
KEY_NOTIFICATION_COLLECTION_CHANGE
,
observer
);
}
/** ================= 字典 ================= */
const
DictMap
=
{};
// 系统字典缓存数据
const
ENUM_DICT_NAME
=
{
SEX
:
"sys_user_sex"
}
/**
* 获取系统字典
*/
function
getSystemDict
(
types
=
[],
callback
)
{
let
result
=
{};
let
emptyKeys
=
[];
types
.
map
(
key
=>
{
let
value
=
DictMap
[
key
];
if
(
value
)
{
result
[
key
]
=
value
;
}
else
{
emptyKeys
.
push
(
key
);
}
})
if
(
isEmpty
(
emptyKeys
))
{
if
(
typeof
callback
==
'function'
)
callback
(
true
,
result
);
return
;
}
apiPOST
({
url
:
`/system/dictData/getDataByDictType`
,
data
:
emptyKeys
,
callback
:
(
success
,
data
)
=>
{
if
(
success
)
{
Object
.
keys
(
data
).
map
(
key
=>
{
DictMap
[
key
]
=
new
Dict
(
data
[
key
])
});
getSystemDict
(
types
,
callback
);
}
else
{
if
(
typeof
callback
==
'function'
)
callback
(
false
)
}
}
})
}
/**
* 收藏、取消收藏书籍
* @param {Object} isCollected
* @param {Object} bookId
* @param {Object} callback
*/
function
collectionBook
(
isCollected
,
bookId
,
callback
)
{
let
url
=
isCollected
?
'/readSystem/v1/collect/collect'
:
"/readSystem/v1/collect/cancel"
;
url
=
`
${
url
}
?articleId=
${
bookId
}
`
apiGET
({
url
,
callback
})
}
/** 获取充值入口开关
* @param {Object} callback
*/
function
getOpens
(
callback
)
{
apiGET
({
url
:
`/v1/article/opens`
,
callback
})
}
/**
* 获取VIP套餐列表
* @param {Object} callback
*/
function
getPackData
(
callback
)
{
apiPOST
({
url
:
`/vip/getVipProducts/point`
,
callback
})
}
/**
* 提交反馈
*/
function
getFeedback
(
text
,
callback
)
{
apiPOST
({
url
:
`/v1/feedback/`
,
data
:
{
title
:
'反馈'
,
content
:
text
,
type
:
1
},
callback
})
}
/**
* 获取openId
* @param {Object} code wx code
* @param {Object} callback
*/
function
getOpenId
(
code
,
callback
)
{
apiPOST
({
url
:
`/getOpenId`
,
data
:
{
code
},
callback
})
}
/**
* 支付类型
*/
const
ENUM_PAY_TYPE
=
{
VIP
:
{
value
:
1
,
name
:
"购买会员"
},
BEAN
:
{
value
:
2
,
name
:
"购买书豆"
}
}
/**
* 获取开通VIP支付信息
* @param {Object} id
* @param {Object} amount
* @param {Object} openId
* @param {Object} callback
*/
function
getPayInfo
(
id
,
amount
,
openId
,
callback
,
typeId
=
ENUM_PAY_TYPE
.
VIP
.
value
)
{
apiPOST
({
url
:
`/wx/pay/createOrder`
,
data
:
{
typeId
,
memberTypeId
:
id
,
amount
:
Number
(
amount
),
openId
},
callback
})
}
function
getPayInfoDy
(
pid
)
{
apiPOST
({
url
:
`/vip/getVipPayParams/douyin`
,
data
:
{
pid
:
pid
},
callback
})
}
/**
* 获取书豆套餐数据
* @param {Object} callback
*/
function
getBookBeanPackData
(
callback
)
{
apiPOST
({
url
:
`//system/bookLegumesType/list`
,
callback
})
}
/**
* 解锁书籍
* @param {Object} bookId
* @param {Object} callback
*/
function
buyBookWithBookBean
(
bookId
,
callback
)
{
apiPOST
({
url
:
`/system/bookUser/create`
,
data
:
{
articleId
:
bookId
},
callback
})
}
module
.
exports
=
{
getOpens
,
getReadTimeCount
,
startCountReadTime
,
endCountReadTime
,
noticeCollectionListChange
,
watchCollectionChange
,
removeCollectionChangeWatch
,
collectionBook
,
ENUM_DICT_NAME
,
getSystemDict
,
getBookBeanPackData
,
getPackData
,
getOpenId
,
getFeedback
,
ENUM_PAY_TYPE
,
getPayInfoDy
,
getPayInfo
,
buyBookWithBookBean
,
const
{
postNotification
,
addNormalNotificationObserver
,
removeNotificationObserver
}
=
require
(
"../utils/notificationCenter"
);
import
Dict
from
"../models/Dict.js"
;
import
{
apiPOST
,
apiGET
}
from
"../utils/apiRequest.js"
import
{
readStorage
,
saveStorage
}
from
"../utils/storageUtil.js"
;
import
{
dateFormat
,
stringToDate
}
from
"../utils/timeUtil.js"
;
import
{
isEmpty
}
from
"../utils/util.js"
;
/** ================= 阅读时间 ================= */
let
READ_TIME_COUNT_MAP
=
null
;
let
KEY_STORAGE_READ_TIME_COUNT
=
"READ_TIME_COUNT"
;
/**
* 读取阅读时间计时
*/
function
getReadTimeCount
()
{
if
(
!
READ_TIME_COUNT_MAP
)
{
READ_TIME_COUNT_MAP
=
readStorage
(
KEY_STORAGE_READ_TIME_COUNT
)
||
{}
}
let
date
=
dateFormat
(
new
Date
(),
"yyyy-MM-dd"
);
let
count
=
READ_TIME_COUNT_MAP
[
date
]
||
0
;
return
count
;
}
/**
* 存储阅读时间计时
*/
function
setReadTimeCount
(
count
)
{
if
(
!
READ_TIME_COUNT_MAP
)
{
READ_TIME_COUNT_MAP
=
readStorage
(
KEY_STORAGE_READ_TIME_COUNT
)
||
{}
}
let
date
=
dateFormat
(
new
Date
(),
"yyyy-MM-dd"
);
let
result
=
READ_TIME_COUNT_MAP
[
date
]
||
0
;
result
=
result
+
count
;
READ_TIME_COUNT_MAP
[
date
]
=
result
;
saveStorage
(
KEY_STORAGE_READ_TIME_COUNT
,
READ_TIME_COUNT_MAP
);
}
let
startReadTime
=
null
;
// 开始阅读时间
/**
* 开始阅读计时
*/
function
startCountReadTime
()
{
startReadTime
=
new
Date
();
}
/**
* 停止阅读计时
*/
function
endCountReadTime
()
{
if
(
!
startReadTime
)
return
;
let
endReadTime
=
new
Date
();
let
start
=
dateFormat
(
startReadTime
,
"yyyy-MM-dd"
);
start
=
start
.
split
(
"-"
);
let
end
=
dateFormat
(
endReadTime
,
"yyyy-MM-dd"
);
end
=
end
.
split
(
"-"
);
let
isSameDay
=
true
;
start
.
forEach
((
item
,
index
)
=>
{
if
(
item
!=
end
[
index
])
{
isSameDay
=
false
;
}
})
let
count
=
0
;
if
(
isSameDay
)
{
count
=
endReadTime
.
getTime
()
-
startReadTime
.
getTime
();
}
else
{
let
dayStart
=
stringToDate
(
end
.
join
(
"-"
))
count
=
endReadTime
.
getTime
()
-
dayStart
.
getTime
();
}
startReadTime
=
null
;
setReadTimeCount
(
count
);
}
/** ================= 收藏 ================= */
const
KEY_NOTIFICATION_COLLECTION_CHANGE
=
'COLLECTION_CHANGE'
;
/**
* 收藏列表变动通知
* @param {Object} bookId
* @param {Object} isCollect
*/
function
noticeCollectionListChange
(
bookId
,
isCollect
)
{
postNotification
(
KEY_NOTIFICATION_COLLECTION_CHANGE
,
{
bookId
,
isCollect
});
}
/**
* 收藏列表变动监听
* @param {Object} fn
* @param {Object} observer
*/
function
watchCollectionChange
(
fn
,
observer
)
{
addNormalNotificationObserver
(
KEY_NOTIFICATION_COLLECTION_CHANGE
,
fn
,
observer
);
}
/**
* 移除收藏列表变动监听
* @param {Object} observer
*/
function
removeCollectionChangeWatch
(
observer
)
{
removeNotificationObserver
(
KEY_NOTIFICATION_COLLECTION_CHANGE
,
observer
);
}
/** ================= 字典 ================= */
const
DictMap
=
{};
// 系统字典缓存数据
const
ENUM_DICT_NAME
=
{
SEX
:
"sys_user_sex"
}
/**
* 获取系统字典
*/
function
getSystemDict
(
types
=
[],
callback
)
{
let
result
=
{};
let
emptyKeys
=
[];
types
.
map
(
key
=>
{
let
value
=
DictMap
[
key
];
if
(
value
)
{
result
[
key
]
=
value
;
}
else
{
emptyKeys
.
push
(
key
);
}
})
if
(
isEmpty
(
emptyKeys
))
{
if
(
typeof
callback
==
'function'
)
callback
(
true
,
result
);
return
;
}
apiPOST
({
url
:
`/system/dictData/getDataByDictType`
,
data
:
emptyKeys
,
callback
:
(
success
,
data
)
=>
{
if
(
success
)
{
Object
.
keys
(
data
).
map
(
key
=>
{
DictMap
[
key
]
=
new
Dict
(
data
[
key
])
});
getSystemDict
(
types
,
callback
);
}
else
{
if
(
typeof
callback
==
'function'
)
callback
(
false
)
}
}
})
}
/**
* 收藏、取消收藏书籍
* @param {Object} isCollected
* @param {Object} bookId
* @param {Object} callback
*/
function
collectionBook
(
isCollected
,
bookId
,
callback
)
{
let
url
=
isCollected
?
'/book/collect'
:
"/book/collectCancel"
;
// url = `${url}?articleId=${bookId}`
apiPOST
({
url
,
data
:
{
articleId
:
bookId
},
callback
})
}
/** 获取充值入口开关
* @param {Object} callback
*/
function
getOpens
(
callback
)
{
apiGET
({
url
:
`/v1/article/opens`
,
callback
})
}
/**
* 获取VIP套餐列表
* @param {Object} callback
*/
function
getPackData
(
callback
)
{
apiPOST
({
url
:
`/vip/getVipProducts/point`
,
callback
})
}
/**
* 提交反馈
*/
function
getFeedback
(
text
,
callback
)
{
apiPOST
({
url
:
`/v1/feedback/`
,
data
:
{
title
:
'反馈'
,
content
:
text
,
type
:
1
},
callback
})
}
/**
* 获取openId
* @param {Object} code wx code
* @param {Object} callback
*/
function
getOpenId
(
code
,
callback
)
{
apiPOST
({
url
:
`/getOpenId`
,
data
:
{
code
},
callback
})
}
/**
* 支付类型
*/
const
ENUM_PAY_TYPE
=
{
VIP
:
{
value
:
1
,
name
:
"购买会员"
},
BEAN
:
{
value
:
2
,
name
:
"购买书豆"
}
}
/**
* 获取开通VIP支付信息
* @param {Object} id
* @param {Object} amount
* @param {Object} openId
* @param {Object} callback
*/
function
getPayInfo
(
id
,
amount
,
openId
,
callback
,
typeId
=
ENUM_PAY_TYPE
.
VIP
.
value
)
{
apiPOST
({
url
:
`/wx/pay/createOrder`
,
data
:
{
typeId
,
memberTypeId
:
id
,
amount
:
Number
(
amount
),
openId
},
callback
})
}
function
getPayInfoDy
(
pid
)
{
apiPOST
({
url
:
`/vip/getVipPayParams/douyin`
,
data
:
{
pid
:
pid
},
callback
})
}
/**
* 获取书豆套餐数据
* @param {Object} callback
*/
function
getBookBeanPackData
(
callback
)
{
apiPOST
({
url
:
`//system/bookLegumesType/list`
,
callback
})
}
/**
* 解锁书籍
* @param {Object} bookId
* @param {Object} callback
*/
function
buyBookWithBookBean
(
bookId
,
callback
)
{
apiPOST
({
url
:
`/system/bookUser/create`
,
data
:
{
articleId
:
bookId
},
callback
})
}
module
.
exports
=
{
getOpens
,
getReadTimeCount
,
startCountReadTime
,
endCountReadTime
,
noticeCollectionListChange
,
watchCollectionChange
,
removeCollectionChangeWatch
,
collectionBook
,
ENUM_DICT_NAME
,
getSystemDict
,
getBookBeanPackData
,
getPackData
,
getOpenId
,
getFeedback
,
ENUM_PAY_TYPE
,
getPayInfoDy
,
getPayInfo
,
buyBookWithBookBean
,
}
\ No newline at end of file
vedio/common/services/userServices.js
View file @
64d49eb9
...
...
@@ -14,8 +14,12 @@ import {
import
User
from
"../models/User.js"
;
import
{
isEmpty
,
isNotEmpty
isNotEmpty
,
}
from
"../utils/util.js"
;
import
{
PAKEAGE_NAME
}
from
"../../utils/utils.js"
;
import
{
printError
}
from
"../utils/printUtil.js"
;
...
...
@@ -49,18 +53,20 @@ function successHandler(url, param, res, callback) {
uni
.
setStorageSync
(
'showLoginModal'
,
false
)
}
})
}
if
(
res
.
status
!=
200
)
{
toastMessage
(
`服务器异常,
${
res
.
status
}
`
)
printError
(
"请求失败"
,
url
,
param
,
res
.
status
,
res
.
errMsg
);
}
console
.
log
(
res
)
if
(
res
.
statusCode
!=
200
)
{
toastMessage
(
`服务器异常,
${
res
.
statusCode
}
`
)
printError
(
"请求失败"
,
url
,
param
,
res
.
statusCode
,
res
.
errMsg
);
if
(
typeof
callback
==
'function'
)
callback
(
false
,
res
.
errMsg
)
}
else
{
if
(
res
.
data
.
code
==
200
)
{
if
(
res
.
data
.
status
==
200
)
{
if
(
typeof
callback
==
'function'
)
callback
(
true
,
res
.
data
.
data
)
}
else
if
(
res
.
data
.
code
==
401
)
{
tokenExpireFn
()
if
(
typeof
callback
==
'function'
)
callback
(
false
,
res
.
data
.
message
);
}
else
{
}
else
{
toastMessage
(
`服务器异常,
${
res
.
data
.
code
}
`
)
printError
(
"请求失败"
,
url
,
param
,
res
.
data
.
code
);
if
(
typeof
callback
==
'function'
)
callback
(
false
,
res
.
data
.
code
)
...
...
@@ -103,7 +109,10 @@ function refreshUserInfo() {
name
:
userData
.
username
,
nickName
:
userData
.
nickname
,
avater
:
userData
.
avatar
,
})
isVip
:
userData
.
expireTime
>
0
})
console
.
log
(
user
)
console
.
log
(
userData
)
saveNickname
(
userData
.
nickname
);
saveUserInfo
(
user
);
// 存储用户数据
postNotification
(
KEY_NOTIFICATION_LOGIN_SUCCESS
);
// 通知登录成功
...
...
@@ -138,13 +147,13 @@ function postPhone(data, callback) {
// 请求token
function
requestToken
(
data
,
callback
)
{
let
url
=
`
${
config
[
"BASE_URL"
]}
/user/ttLogin`
;
let
header
=
{
pkg
Name
:
'com.duben.dybookhm'
,
token
:
``
let
header
=
{
pkg
name
:
PAKEAGE_NAME
,
token
:
``
}
uni
.
request
({
url
,
data
,
data
,
header
,
method
:
"POST"
,
success
:
(
res
)
=>
{
...
...
@@ -158,18 +167,19 @@ function requestToken(data, callback) {
// 请求用户数据
function
requestUserInfo
(
callback
)
{
let
url
=
`
${
config
[
'BASE_URL'
]}
/
system/user/getCurrentUserInfo
`
;
let
url
=
`
${
config
[
'BASE_URL'
]}
/
user/baseMsg
`
;
let
header
=
{
Authorization
:
`
${
readToken
()}
`
token
:
`
${
readToken
()}
`
,
pkgname
:
PAKEAGE_NAME
}
uni
.
request
({
url
,
header
,
method
:
"POST"
,
success
:
(
res
)
=>
{
success
:
(
res
)
=>
{
successHandler
(
url
,
{},
res
,
callback
);
},
fail
:
(
error
)
=>
{
fail
:
(
error
)
=>
{
failHandler
(
url
,
data
,
error
,
callback
);
}
})
...
...
@@ -221,7 +231,8 @@ function saveToken(token) {
function
readToken
()
{
if
(
!
LOCAL_TOKEN
)
{
LOCAL_TOKEN
=
readStorage
(
KEY_STORAGE_TOKEN
)
// LOCAL_TOKEN = readStorage(KEY_STORAGE_TOKEN)
LOCAL_TOKEN
=
readStorage
(
'token'
)
}
return
LOCAL_TOKEN
;
}
...
...
vedio/common/utils/apiRequest.js
View file @
64d49eb9
...
...
@@ -9,8 +9,11 @@ import {
printError
,
}
from
"./printUtil.js"
import
{
appendParam
appendParam
,
}
from
"./util"
;
import
{
PAKEAGE_NAME
}
from
"../../utils/utils"
;
import
{
addNormalNotificationObserver
,
removeNotificationObserver
...
...
@@ -65,11 +68,11 @@ let apiRequest = function({
let
option
=
{};
// 请求参数
// url 处理
let
handlerUrl
=
`
${
config
[
"BASE_URL"
]}${
urlModule
?
urlModule
:
""
}${
url
}
`
;
if
(
handlerUrl
.
indexOf
(
"?"
)
==
-
1
)
{
handlerUrl
=
`
${
handlerUrl
}
?t=
${
new
Date
().
getTime
()}
`
;
}
else
{
handlerUrl
=
`
${
handlerUrl
}
&t=
${
new
Date
().
getTime
()}
`
;
}
//
if (handlerUrl.indexOf("?") == -1) {
//
handlerUrl = `${handlerUrl}?t=${new Date().getTime()}`;
//
} else {
//
handlerUrl = `${handlerUrl}&t=${new Date().getTime()}`;
//
}
option
=
{
url
:
handlerUrl
,
method
...
...
@@ -87,7 +90,7 @@ let apiRequest = function({
}
else
{
// 其余对象照常插入
option
.
data
=
data
;
}
}
}
console
.
log
(
'123'
)
// token处理
let
token
=
readToken
();
...
...
@@ -96,9 +99,9 @@ let apiRequest = function({
if
(
typeof
originQuery
.
complete
==
'function'
)
originQuery
.
complete
();
return
;
}
option
.
header
=
{
pkgName
:
'com.duben.dybookhm'
,
token
:
`
${
token
}
`
option
.
header
=
{
pkgName
:
PAKEAGE_NAME
,
token
:
`
${
token
}
`
}
// header处理
if
(
header
)
{
...
...
@@ -106,7 +109,7 @@ let apiRequest = function({
...
option
.
header
,
...
header
}
}
}
console
.
log
(
'123'
)
printInfo
(
"start Req"
,
option
);
let
requestTask
=
uni
.
request
({
...
...
@@ -237,9 +240,9 @@ function apiUPLOAD({
}
option
.
url
=
`
${
option
.
url
}
?t=
${
new
Date
().
getTime
()}
`
;
// 路径
option
.
header
=
{
pkgName
:
'com.duben.dybookhm'
,
token
:
`
${
token
}
`
option
.
header
=
{
pkgName
:
PAKEAGE_NAME
,
token
:
`
${
token
}
`
}
if
(
header
)
{
option
.
header
=
{
...
...
@@ -283,12 +286,12 @@ function successHandler(originQuery, requestTask, res) {
apiRequest
(
originQuery
);
}
removeNotificationObserver
(
KEY_NOTIFICATION_LOGIN_SUCCESS
,
requestTask
);
},
requestTask
);
},
requestTask
);
if
(
uni
.
getStorageSync
(
'showLoginModal'
))
{
return
}
uni
.
setStorageSync
(
'showLoginModal'
,
true
)
}
uni
.
setStorageSync
(
'showLoginModal'
,
true
)
uni
.
showModal
({
title
:
"登录状态已过期"
,
content
:
"当前登录状态已过期,请重新登录!"
,
...
...
@@ -299,8 +302,8 @@ function successHandler(originQuery, requestTask, res) {
showLoginView
();
}
else
{
logout
(()
=>
{},
true
);
}
uni
.
setStorageSync
(
'showLoginModal'
,
false
)
}
uni
.
setStorageSync
(
'showLoginModal'
,
false
)
}
})
}
...
...
@@ -312,14 +315,14 @@ function successHandler(originQuery, requestTask, res) {
tokenExpireFn
();
}
else
{
if
(
typeof
res
.
data
==
'string'
)
res
.
data
=
JSON
.
parse
(
res
.
data
);
if
(
res
.
data
.
code
==
200
)
{
if
(
res
.
data
.
status
==
200
)
{
printDebug
(
"请求结果"
,
originQuery
.
url
,
res
.
data
.
data
);
if
(
typeof
originQuery
.
callback
==
'function'
)
originQuery
.
callback
(
true
,
res
.
data
.
data
);
}
else
if
(
res
.
data
.
code
==
401
)
{
}
else
if
(
res
.
data
.
status
==
401
)
{
tokenExpireFn
()
if
(
typeof
originQuery
.
callback
==
'function'
)
originQuery
.
callback
(
false
,
res
.
data
.
msg
);
}
else
{
toastMessage
(
res
.
data
.
message
?
res
.
data
.
message
:
res
.
data
.
code
?
res
.
data
.
code
:
"未知错误"
);
toastMessage
(
res
.
data
.
message
?
res
.
data
.
message
:
res
.
data
.
status
?
res
.
data
.
status
:
"未知错误"
);
printError
(
"请求失败"
,
originQuery
.
url
,
res
.
data
.
message
);
if
(
typeof
originQuery
.
callback
==
'function'
)
originQuery
.
callback
(
false
,
res
.
data
.
message
);
}
...
...
vedio/common/utils/storageUtil.js
View file @
64d49eb9
const
{
printError
}
=
require
(
"./printUtil"
)
function
saveStorage
(
key
,
value
)
{
try
{
uni
.
setStorageSync
(
key
,
value
)
}
catch
(
error
)
{
printError
(
"save storage 错误"
,
error
.
errMsg
,
key
,
value
);
}
}
function
readStorage
(
key
)
{
try
{
return
uni
.
getStorageSync
(
key
);
}
catch
(
error
)
{
printError
(
"read storage 错误"
,
error
.
errMsg
,
key
);
}
}
function
removeStorage
(
key
)
{
try
{
return
uni
.
removeStorageSync
(
key
);
}
catch
(
error
)
{
printError
(
"remove storage 错误"
,
error
.
errMsg
,
key
);
}
}
module
.
exports
=
{
saveStorage
,
readStorage
,
removeStorage
}
const
{
printError
}
=
require
(
"./printUtil"
)
function
saveStorage
(
key
,
value
)
{
try
{
uni
.
setStorageSync
(
key
,
value
)
}
catch
(
error
)
{
printError
(
"save storage 错误"
,
error
.
errMsg
,
key
,
value
);
}
}
function
readStorage
(
key
)
{
try
{
return
uni
.
getStorageSync
(
key
);
}
catch
(
error
)
{
printError
(
"read storage 错误"
,
error
.
errMsg
,
key
);
}
}
function
removeStorage
(
key
)
{
try
{
return
uni
.
removeStorageSync
(
key
);
}
catch
(
error
)
{
printError
(
"remove storage 错误"
,
error
.
errMsg
,
key
);
}
}
function
clearStorage
(
key
)
{
try
{
return
uni
.
clearStorageSync
(
key
);
}
catch
(
error
)
{
printError
(
"remove storage 错误"
,
error
.
errMsg
,
key
);
}
}
module
.
exports
=
{
saveStorage
,
readStorage
,
removeStorage
,
clearStorage
}
\ No newline at end of file
vedio/components/book-search-box/book-search-box.vue
View file @
64d49eb9
<
template
>
<view
class=
"search-box"
@
click=
"search"
>
<view
class=
"search-zone c-flex_row c-align_center"
>
<view
class=
"item"
>
<uni-icons
type=
'search'
size=
'28'
color=
"#e5e5e5"
></uni-icons>
</view>
<input
class=
"item c-flex_1"
placeholder=
"搜索书名/作者名"
disabled
/>
<view
class=
"
button item"
>
搜索
</view>
</view>
</view>
</
template
>
<
script
>
import
{
gotoBookSearchPage
}
from
"../../common/services/page-route.js"
import
{
ENUM_SEARCH_TYPE
}
from
"../../static/enums/enum_value.js"
;
export
default
{
props
:
{
searchType
:
{
type
:
Object
,
default
:
function
()
{
return
ENUM_SEARCH_TYPE
.
WAREHOUSE
}
}
},
methods
:
{
search
()
{
gotoBookSearchPage
(
this
.
searchType
);
}
}
}
</
script
>
<
style
lang=
"scss"
scoped
>
.search-box
{
background
:
transparent
;
padding
:
10rpx
20rpx
;
<
template
>
<view
class=
"search-box"
@
click=
"search"
>
<view
class=
"search-zone c-flex_row c-align_center"
>
<view
class=
"item"
>
<uni-icons
type=
'search'
size=
'28'
color=
"#e5e5e5"
></uni-icons>
</view>
<input
class=
"item c-flex_1"
placeholder=
"搜索书名/作者名"
disabled
/>
<view
class=
"
mbutton item"
>
搜索
</view>
</view>
</view>
</
template
>
<
script
>
import
{
gotoBookSearchPage
}
from
"../../common/services/page-route.js"
import
{
ENUM_SEARCH_TYPE
}
from
"../../static/enums/enum_value.js"
;
export
default
{
props
:
{
searchType
:
{
type
:
Object
,
default
:
function
()
{
return
ENUM_SEARCH_TYPE
.
WAREHOUSE
}
}
},
methods
:
{
search
()
{
gotoBookSearchPage
(
this
.
searchType
);
}
}
}
</
script
>
<
style
lang=
"scss"
scoped
>
.search-box
{
background
:
transparent
;
padding
:
10rpx
20rpx
;
.search-zone
{
border-radius
:
35rpx
;
background
:
#fff
;
padding
:
4rpx
;
font-size
:
28rpx
;
.item
{
margin-left
:
20rpx
;
}
.button
{
height
:
70rpx
;
line-height
:
70rpx
;
width
:
120rpx
;
text-align
:
center
;
color
:
#fff
;
background
:
#007aff
;
border-radius
:
35rpx
;
}
}
}
width
:
100%
;
border-radius
:
35rpx
;
background
:
#fff
;
padding
:
4rpx
;
font-size
:
28rpx
;
.item
{
margin-left
:
20rpx
;
}
.mbutton
{
width
:
100rpx
;
height
:
70rpx
;
line-height
:
70rpx
;
text-align
:
center
;
color
:
#fff
;
background
:
#007aff
;
border-radius
:
35rpx
;
}
}
}
</
style
>
\ No newline at end of file
vedio/components/bookshelf/components/bookshelf-list.vue
View file @
64d49eb9
<
template
>
<view>
<c-list
ref=
'list'
:showShelfEmpty=
"true"
flag=
'bookshelf'
:needLogin=
"true"
:height=
"height"
url=
'/
v1/collec
t/'
:param=
"requestParam"
@
change=
'changeData'
>
<c-list
ref=
'list'
:showShelfEmpty=
"true"
flag=
'bookshelf'
:needLogin=
"true"
:height=
"height"
url=
'/
book/collectLis
t/'
:param=
"requestParam"
@
change=
'changeData'
method=
"POST"
>
<book-list-item
v-for=
'(item, index) in dataList'
:key=
'index'
:item=
'item'
@
tapItem=
'tapItem($event, index)'
@
close=
'tapClose($event, index)'
>
<template
v-slot:footer
>
...
...
@@ -59,7 +59,8 @@
}
},
changeData
(
e
)
{
this
.
dataList
=
e
.
detail
.
data
.
map
(
item
=>
{
console
.
log
(
e
)
this
.
dataList
=
e
.
detail
.
data
.
list
.
map
(
item
=>
{
return
new
BookshelfBookItem
(
item
)
})
},
...
...
vedio/components/c-list/c-list.vue
View file @
64d49eb9
...
...
@@ -290,8 +290,8 @@
...
param
,
...
this
.
param
}
}
}
apiRequest
({
url
:
this
.
url
,
method
:
this
.
method
||
"GET"
,
...
...
vedio/components/warehouse/components/warehouse-list.vue
View file @
64d49eb9
<
template
>
<view>
<c-list
ref=
'list'
flag=
'warehouse'
method=
"POST"
:height=
"height"
url=
'/
v1/article
/'
:param=
"requestParam"
<c-list
ref=
'list'
flag=
'warehouse'
method=
"POST"
:height=
"height"
url=
'/
book/articleList
/'
:param=
"requestParam"
@
change=
'changeData'
>
<book-list-item
v-for=
'(item, index) in dataList'
:key=
'index'
:item=
'item'
:showClose=
'false'
@
tapItem=
'tapItem($event, index)'
@
close=
'tapClose($event, index)'
>
...
...
@@ -39,7 +39,7 @@
computed
:
{
requestParam
:
function
()
{
return
{
tag
Id
:
this
.
category
.
value
category
Id
:
this
.
category
.
value
}
}
},
...
...
vedio/components/warehouse/services/index.js
View file @
64d49eb9
...
...
@@ -5,7 +5,7 @@ import {
function
getCategorys
(
callback
)
{
apiPOST
({
url
:
"/
v1/tag
/"
,
url
:
"/
book/categoryList
/"
,
callback
})
}
...
...
vedio/components/warehouse/warehouse.vue
View file @
64d49eb9
...
...
@@ -75,7 +75,7 @@
watch
:
{
categroyChange
:
{
handler
:
function
(
n
,
o
)
{
this
.
$nextTick
(()
=>
{
this
.
$nextTick
(()
=>
{
let
ref
=
this
.
$refs
.
bookList
;
if
(
ref
)
{
ref
[
n
.
currentIndex
].
initRefresh
();
...
...
@@ -88,13 +88,13 @@
methods
:
{
show
()
{
setTimeout
(()
=>
{
// 匹配用户直接跳转小说
var
bookId
=
uni
.
getStorageSync
(
'firstBookId'
)
// 匹配用户直接跳转小说
var
bookId
=
uni
.
getStorageSync
(
'firstBookId'
)
if
(
bookId
!=
''
)
{
gotoBookContentPage
(
bookId
);
uni
.
setStorage
({
key
:
'firstBookId'
,
data
:
''
gotoBookContentPage
(
bookId
);
uni
.
setStorage
({
key
:
'firstBookId'
,
data
:
''
});
}
},
800
);
...
...
@@ -120,7 +120,7 @@
getCategoryData
()
{
getCategorys
((
success
,
data
)
=>
{
if
(
success
)
{
let
result
=
data
?
data
.
map
(
item
=>
{
let
result
=
data
.
records
?
data
.
records
.
map
(
item
=>
{
return
new
Category
(
item
)
}).
sort
((
a
,
b
)
=>
{
return
a
.
sort
-
b
.
sort
...
...
vedio/config/env/develop.js
View file @
64d49eb9
...
...
@@ -9,7 +9,7 @@ const {
}
}
=
require
(
"../configEnum"
);
export
default
{
// BASE_URL: "http://192.168.110.
6:8800
",
// BASE_URL: "http://192.168.110.
42:8303/miniApi
",
BASE_URL
:
"https://dx.mints-tech.cn/minip-api/miniApi"
,
BASE_URL_MODULE
:
""
,
BASE_SOCKET_URL
:
""
,
...
...
vedio/config/env/product.js
View file @
64d49eb9
...
...
@@ -9,7 +9,7 @@ const {
}
}
=
require
(
"../configEnum"
);
export
default
{
// BASE_URL: "http
s://book.mints-id.com
",
// BASE_URL: "http
://192.168.110.42:8303/miniApi
",
BASE_URL
:
"https://dx.mints-tech.cn/minip-api/miniApi"
,
BASE_URL_MODULE
:
""
,
BASE_SOCKET_URL
:
""
,
...
...
vedio/page-subs/sub_A/book-content/book-content.vue
View file @
64d49eb9
<
template
>
<
view
:style=
"[bgStyle]"
>
<
z-paging
:style=
"[bgStyle]"
>
<c-empty
v-if=
'showEmpty'
></c-empty>
<template
v-else
>
<detail-warn></detail-warn>
...
...
@@ -18,13 +18,13 @@
<c-login
:isShareLink=
"true"
></c-login>
<popup
:show=
"showMoibleLogin"
@
close=
"showMoibleLogin=false"
>
<view>
<button
open-type=
"getPhoneNumber"
@
getphonenumber=
"MygetPhonenumber"
>
<view>
请先绑定手机号
</view>
<view
style=
"color:green;"
>
去绑定
</view>
<button
open-type=
"getPhoneNumber"
@
getphonenumber=
"MygetPhonenumber"
>
<view>
请先绑定手机号
</view>
<view
style=
"color:green;"
>
去绑定
</view>
</button>
</view>
</popup>
</
view
>
</
z-paging
>
</template>
<
script
>
...
...
@@ -126,7 +126,12 @@
// 用户已登录需要记录阅读记录
if
(
info
.
userInfo
)
{
addReadRecord
(
this
.
bookId
)
}
}
console
.
log
(
info
)
console
.
log
(
this
.
userInfo
)
// this.showVipOpen = data.openVips
// // 用户变动,需要刷新数据
// this.$nextTick(() => {
// uni.startPullDownRefresh({})
...
...
@@ -246,10 +251,10 @@
},
// 文章数据刷新
refreshBookData
(
bookId
)
{
getOpens
((
success
,
data
)
=>
{
// this.showBeanOpen = data.openBeans
this
.
showVipOpen
=
data
.
openVips
})
//
getOpens((success, data) => {
//
// this.showBeanOpen = data.openBeans
//
this.showVipOpen = data.openVips
//
})
getBookDetailData
(
bookId
,
(
success
,
data
)
=>
{
setTimeout
(()
=>
{
uni
.
stopPullDownRefresh
();
...
...
@@ -300,19 +305,19 @@
this
.
tapVipPop
()
},
// 展示充值VIP弹框
tapVipPop
()
{
if
(
this
.
mobileLoginLock
)
{
this
.
showMoibleLogin
=
true
return
}
tapVipPop
()
{
if
(
this
.
mobileLoginLock
)
{
this
.
showMoibleLogin
=
true
return
}
this
.
showVip
=
true
;
},
// 展示充值书豆弹框
tapBeanPop
()
{
if
(
this
.
mobileLoginLock
)
{
this
.
showMoibleLogin
=
true
return
if
(
this
.
mobileLoginLock
)
{
this
.
showMoibleLogin
=
true
return
}
this
.
showBean
=
true
;
...
...
vedio/page-subs/sub_A/book-content/components/detail-buy.vue
View file @
64d49eb9
...
...
@@ -168,15 +168,15 @@
this
.
imageError
=
true
},
refreshPackData
()
{
getPackData
((
success
,
data
)
=>
{
if
(
success
)
{
this
.
vipPackList
=
data
.
map
(
item
=>
{
let
result
=
new
Pack
(
item
);
result
.
isBeanPack
=
false
;
return
result
;
})
}
})
//
getPackData((success, data) => {
//
if (success) {
//
this.vipPackList = data.map(item => {
//
let result = new Pack(item);
//
result.isBeanPack = false;
//
return result;
//
})
//
}
//
})
getBookBeanPackData
((
success
,
data
)
=>
{
if
(
success
)
{
this
.
beanPackList
=
data
.
map
(
item
=>
{
...
...
vedio/page-subs/sub_A/book-content/components/vip-pop.vue
View file @
64d49eb9
...
...
@@ -120,11 +120,11 @@
this
.
showPop
=
false
;
},
refrehsPackData
()
{
getPackData
((
success
,
data
)
=>
{
this
.
packList
=
data
.
map
(
item
=>
{
return
new
Pack
(
item
);
})
})
//
getPackData((success, data) => {
//
this.packList = data.map(item => {
//
return new Pack(item);
//
})
//
})
},
choosePack
(
item
,
index
)
{
this
.
selectedIndex
=
index
;
...
...
vedio/page-subs/sub_A/book-content/services/index.js
View file @
64d49eb9
import
{
addNormalNotificationObserver
,
postNotification
,
removeNotificationObserver
}
from
"../../../../common/utils/notificationCenter"
;
import
{
readStorage
,
saveStorage
}
from
"../../../../common/utils/storageUtil"
;
import
ContentFormat
from
"../models/ContentFormat"
;
import
{
apiGET
,
apiPOST
}
from
"../../../../common/utils/apiRequest.js"
/** 获取文章详情
* @param {Object} bookId
* @param {Object} callback
*/
function
getBookDetailData
(
bookId
,
callback
)
{
apiPOST
({
url
:
`/v1/article/info?id=
${
bookId
}
`
,
callback
})
}
/** 获取推荐文章
* @param {Object} bookId
* @param {Object} callback
*/
function
getBookRecommendData
(
bookId
,
callback
)
{
apiPOST
({
url
:
`/v1/article/recommend?id=
${
bookId
}
`
,
callback
})
}
/** 添加阅读记录
* @param {Object} bookId
* @param {Object} callback
*/
function
addReadRecord
(
bookId
,
callback
)
{
apiGET
({
url
:
`/readSystem/system/readRecord/addReadRecord?articleId=
${
bookId
}
`
,
callback
})
}
// 样式设置
const
KEY_STORAGE_CONTENT_FORMAT
=
"KEY_SOTRAGE_CONTENT_FORMAT"
;
const
KEY_NOTIFICATION_CONTENT_FORMAT_CHANGE
=
"KEY_NOTIFICATION_CONTENT_FORMAT_CHANGE"
;
function
saveContentFormat
(
format
)
{
let
result
=
readContentFormat
();
Object
.
keys
(
format
).
forEach
(
key
=>
{
let
value
=
format
[
key
];
result
[
key
]
=
value
||
result
[
key
];
})
saveStorage
(
KEY_STORAGE_CONTENT_FORMAT
,
result
);
notifyContentFormatChange
(
new
ContentFormat
(
result
));
}
function
readContentFormat
()
{
let
result
=
readStorage
(
KEY_STORAGE_CONTENT_FORMAT
);
if
(
result
)
{
result
=
new
ContentFormat
(
result
);
}
else
{
result
=
new
ContentFormat
({
fontSize
:
17
,
backgroundColor
:
"#fff"
})
}
return
result
;
}
function
notifyContentFormatChange
(
format
)
{
postNotification
(
KEY_NOTIFICATION_CONTENT_FORMAT_CHANGE
,
format
);
}
function
watchContentFormatChange
(
fn
,
observer
)
{
if
(
typeof
fn
==
'function'
)
fn
.
call
(
observer
,
readContentFormat
());
addNormalNotificationObserver
(
KEY_NOTIFICATION_CONTENT_FORMAT_CHANGE
,
(
data
)
=>
{
if
(
typeof
fn
==
'function'
)
fn
.
call
(
observer
,
data
);
},
observer
)
}
function
removeContentFormatChangeWatch
(
observer
)
{
removeNotificationObserver
(
KEY_NOTIFICATION_CONTENT_FORMAT_CHANGE
,
observer
);
}
module
.
exports
=
{
getBookDetailData
,
getBookRecommendData
,
addReadRecord
,
/**
* content format
*/
saveContentFormat
,
readContentFormat
,
notifyContentFormatChange
,
watchContentFormatChange
,
removeContentFormatChangeWatch
import
{
addNormalNotificationObserver
,
postNotification
,
removeNotificationObserver
}
from
"../../../../common/utils/notificationCenter"
;
import
{
readStorage
,
saveStorage
}
from
"../../../../common/utils/storageUtil"
;
import
ContentFormat
from
"../models/ContentFormat"
;
import
{
apiGET
,
apiPOST
}
from
"../../../../common/utils/apiRequest.js"
/** 获取文章详情
* @param {Object} bookId
* @param {Object} callback
*/
function
getBookDetailData
(
bookId
,
callback
)
{
apiPOST
({
url
:
`/book/info`
,
data
:
{
id
:
bookId
},
callback
})
}
/** 获取推荐文章
* @param {Object} bookId
* @param {Object} callback
*/
function
getBookRecommendData
(
bookId
,
callback
)
{
apiPOST
({
url
:
`/book/recommend`
,
data
:
{
id
:
bookId
},
callback
})
}
/** 添加阅读记录
* @param {Object} bookId
* @param {Object} callback
*/
function
addReadRecord
(
bookId
,
callback
)
{
apiPOST
({
url
:
`/book/addReadRecord`
,
data
:
{
articleId
:
bookId
},
callback
})
}
// 样式设置
const
KEY_STORAGE_CONTENT_FORMAT
=
"KEY_SOTRAGE_CONTENT_FORMAT"
;
const
KEY_NOTIFICATION_CONTENT_FORMAT_CHANGE
=
"KEY_NOTIFICATION_CONTENT_FORMAT_CHANGE"
;
function
saveContentFormat
(
format
)
{
let
result
=
readContentFormat
();
Object
.
keys
(
format
).
forEach
(
key
=>
{
let
value
=
format
[
key
];
result
[
key
]
=
value
||
result
[
key
];
})
saveStorage
(
KEY_STORAGE_CONTENT_FORMAT
,
result
);
notifyContentFormatChange
(
new
ContentFormat
(
result
));
}
function
readContentFormat
()
{
let
result
=
readStorage
(
KEY_STORAGE_CONTENT_FORMAT
);
if
(
result
)
{
result
=
new
ContentFormat
(
result
);
}
else
{
result
=
new
ContentFormat
({
fontSize
:
17
,
backgroundColor
:
"#fff"
})
}
return
result
;
}
function
notifyContentFormatChange
(
format
)
{
postNotification
(
KEY_NOTIFICATION_CONTENT_FORMAT_CHANGE
,
format
);
}
function
watchContentFormatChange
(
fn
,
observer
)
{
if
(
typeof
fn
==
'function'
)
fn
.
call
(
observer
,
readContentFormat
());
addNormalNotificationObserver
(
KEY_NOTIFICATION_CONTENT_FORMAT_CHANGE
,
(
data
)
=>
{
if
(
typeof
fn
==
'function'
)
fn
.
call
(
observer
,
data
);
},
observer
)
}
function
removeContentFormatChangeWatch
(
observer
)
{
removeNotificationObserver
(
KEY_NOTIFICATION_CONTENT_FORMAT_CHANGE
,
observer
);
}
module
.
exports
=
{
getBookDetailData
,
getBookRecommendData
,
addReadRecord
,
/**
* content format
*/
saveContentFormat
,
readContentFormat
,
notifyContentFormatChange
,
watchContentFormatChange
,
removeContentFormatChangeWatch
}
\ No newline at end of file
vedio/page-subs/sub_A/book-search/components/search-header-bar.vue
View file @
64d49eb9
<
template
>
<view
class=
"search-header-bar"
>
<view
class=
"input-box item c-flex_1"
>
<uni-easyinput
:value=
'searchKeyword'
placeholder=
"请输入书名或者作者名"
:focus=
'focus'
:styles=
"inputStyles"
confirmType=
"search"
trim=
"all"
:inputBorder=
"true"
@
clear=
'clearInput'
@
change=
'changeInput'
></uni-easyinput>
</view>
<view
class=
"button-box item"
@
click=
"tapSearch"
>
<view
class=
"title"
>
搜索
</view>
</view>
</view>
</
template
>
<
script
>
import
{
saveSearchHistory
}
from
"../services/index.js"
export
default
{
props
:
{
keyword
:
{
type
:
String
,
default
:
""
}
},
data
:
function
()
{
return
{
searchKeyword
:
""
,
focus
:
true
,
height
:
0
,
}
},
computed
:
{
inputStyles
:
function
()
{
return
{
borderColor
:
"#e5e5e5"
}
}
},
watch
:
{
keyword
:
{
handler
:
function
(
n
)
{
this
.
searchKeyword
=
n
},
immediate
:
true
},
searchKeyword
:
{
handler
:
function
(
n
,
o
)
{
if
(
n
==
o
)
return
;
if
(
!
n
)
{
this
.
clearSearch
();
}
else
{
this
.
startSearch
(
n
)
}
},
immediate
:
true
},
},
methods
:
{
clearSearch
()
{
this
.
$emit
(
"clear"
);
},
startSearch
(
keyword
)
{
saveSearchHistory
(
keyword
);
this
.
$emit
(
"start"
,
{
detail
:
{
keyword
}
})
},
clearInput
()
{
this
.
searchKeyword
=
""
;
this
.
focus
=
false
;
},
changeInput
(
e
)
{
this
.
searchKeyword
=
e
;
},
tapSearch
()
{
this
.
focus
=
false
;
}
}
}
</
script
>
<
style
lang=
"scss"
scoped
>
.search-header-bar
{
padding
:
15rpx
30rpx
;
display
:
flex
;
flex-direction
:
row
;
align-items
:
center
;
background
:
#fff
;
font-size
:
28rpx
;
.item
{
margin-right
:
15rpx
;
}
.item
:last-child
{
margin-right
:
0
;
}
.input-box
{}
.button-box
{
height
:
50rpx
;
line-height
:
50rpx
;
width
:
120rpx
;
text-align
:
center
;
border-radius
:
10rpx
;
background
:
#007aff
;
color
:
#fff
;
}
}
<
template
>
<view
class=
"search-header-bar"
>
<view
class=
"input-box item c-flex_1"
>
<uni-easyinput
v-model=
"searchKeyword"
placeholder=
"请输入书名或者作者名"
:focus=
'focus'
confirmType=
"search"
trim=
"all"
:inputBorder=
"true"
@
clear=
"clearInput"
@
change=
"changeInput"
@
confirm=
"changeInput"
></uni-easyinput>
</view>
<view
class=
"button-box item"
@
click=
"tapSearch"
>
<view
class=
"title"
>
搜索
</view>
</view>
</view>
</
template
>
<
script
>
import
{
saveSearchHistory
}
from
"../services/index.js"
export
default
{
props
:
{
keyword
:
{
type
:
String
,
default
:
""
}
},
data
:
function
()
{
return
{
searchKeyword
:
""
,
focus
:
true
,
height
:
0
,
}
},
computed
:
{
inputStyles
:
function
()
{
return
{
borderColor
:
"#e5e5e5"
}
}
},
watch
:
{
keyword
:
{
handler
:
function
(
n
)
{
this
.
searchKeyword
=
n
},
immediate
:
true
},
searchKeyword
:
{
handler
:
function
(
n
,
o
)
{
if
(
n
==
o
)
return
;
if
(
!
n
)
{
this
.
clearSearch
();
}
else
{
this
.
startSearch
(
n
)
}
},
immediate
:
true
},
},
methods
:
{
clearSearch
()
{
this
.
$emit
(
"clear"
);
},
startSearch
(
keyword
)
{
saveSearchHistory
(
keyword
);
this
.
$emit
(
"start"
,
{
detail
:
{
keyword
}
})
},
clearInput
()
{
this
.
searchKeyword
=
""
;
this
.
focus
=
false
;
},
changeInput
(
e
)
{
this
.
searchKeyword
=
e
;
},
tapSearch
()
{
this
.
focus
=
false
;
}
}
}
</
script
>
<
style
lang=
"scss"
scoped
>
.search-header-bar
{
padding
:
15rpx
30rpx
;
display
:
flex
;
flex-direction
:
row
;
align-items
:
center
;
background
:
#fff
;
font-size
:
28rpx
;
.item
{
margin-right
:
15rpx
;
}
.item
:last-child
{
margin-right
:
0
;
}
.input-box
{}
.button-box
{
height
:
50rpx
;
line-height
:
50rpx
;
width
:
120rpx
;
text-align
:
center
;
border-radius
:
10rpx
;
background
:
#007aff
;
color
:
#fff
;
}
}
</
style
>
\ No newline at end of file
vedio/page-subs/sub_A/book-search/components/search-placeholder.vue
View file @
64d49eb9
...
...
@@ -26,6 +26,7 @@
import
{
saveSearchHistory
,
watchSearchHistoryChange
,
clearSearchHistory
,
removeSearchHistoryChangeWatch
,
getHotRecommondData
,
}
from
"../services/index.js"
...
...
@@ -68,7 +69,7 @@
},
methods
:
{
tapDeleteHistory
()
{
saveSearchHistory
([]
)
clearSearchHistory
(
)
},
tapItem
(
e
,
flag
)
{
this
.
$emit
(
'chooseKeyword'
,
{
...
...
vedio/page-subs/sub_A/book-search/components/search-result.vue
View file @
64d49eb9
<
template
>
<c-list
ref=
"list"
flag=
'search'
:needLogin=
"needLogin"
:height=
"height"
:url=
'requestUrl'
:param=
'requestParam'
@
change=
'changeData'
>
<book-list-item
v-for=
'(item, index) in dataList'
:key=
'index'
:item=
'item'
:showClose=
"false"
@
tapItem=
'tapItem($event, index)'
>
</book-list-item>
</c-list>
</
template
>
<
script
>
import
WarehouseBookItem
from
"../../../../components/warehouse/models/WarehouseBookItem.js"
import
{
gotoBookContentPage
}
from
"../../../../common/services/page-route.js"
import
{
ENUM_SEARCH_TYPE
}
from
"../../../../static/enums/enum_value.js"
export
default
{
props
:
{
height
:
{
type
:
Number
,
default
:
0
},
keyword
:
{
type
:
String
,
default
:
""
},
result
:
{
type
:
Array
,
default
:
function
()
{
return
null
}
},
searchType
:
{
type
:
Object
,
default
:
function
()
{
return
ENUM_SEARCH_TYPE
.
WAREHOUSE
}
}
},
data
:
function
()
{
return
{
dataList
:
null
}
},
computed
:
{
needLogin
:
function
()
{
return
this
.
searchType
&&
this
.
searchType
.
value
==
ENUM_SEARCH_TYPE
.
BOOKSHELF
.
value
},
requestUrl
:
function
()
{
return
!
this
.
searchType
||
this
.
searchType
.
value
==
ENUM_SEARCH_TYPE
.
WAREHOUSE
.
value
?
"/book/articleList/"
:
"/
readSystem/v1/collect/"
},
requestParam
:
function
()
{
return
{
searchName
:
this
.
keyword
}
}
},
watch
:
{
result
:
{
handler
:
function
(
n
)
{
this
.
dataList
=
n
;
},
immediate
:
true
}
},
methods
:
{
refreshList
()
{
let
ref
=
this
.
$refs
.
list
;
if
(
ref
)
{
ref
.
onPullRefreshing
();
}
},
changeData
(
e
)
{
this
.
dataList
=
e
.
detail
.
data
.
map
(
item
=>
{
return
new
WarehouseBookItem
(
item
)
})
},
tapItem
(
e
,
index
)
{
gotoBookContentPage
(
e
.
detail
.
data
.
id
)
},
}
}
</
script
>
<
style
>
<
template
>
<c-list
ref=
"list"
flag=
'search'
method=
"POST"
:needLogin=
"needLogin"
:height=
"height"
:url=
'requestUrl'
:param=
'requestParam'
@
change=
'changeData'
>
<book-list-item
v-for=
'(item, index) in dataList'
:key=
'index'
:item=
'item'
:showClose=
"false"
@
tapItem=
'tapItem($event, index)'
>
</book-list-item>
</c-list>
</
template
>
<
script
>
import
WarehouseBookItem
from
"../../../../components/warehouse/models/WarehouseBookItem.js"
import
{
gotoBookContentPage
}
from
"../../../../common/services/page-route.js"
import
{
ENUM_SEARCH_TYPE
}
from
"../../../../static/enums/enum_value.js"
export
default
{
props
:
{
height
:
{
type
:
Number
,
default
:
0
},
keyword
:
{
type
:
String
,
default
:
""
},
result
:
{
type
:
Array
,
default
:
function
()
{
return
null
}
},
searchType
:
{
type
:
Object
,
default
:
function
()
{
return
ENUM_SEARCH_TYPE
.
WAREHOUSE
}
}
},
data
:
function
()
{
return
{
dataList
:
null
,
}
},
computed
:
{
needLogin
:
function
()
{
return
this
.
searchType
&&
this
.
searchType
.
value
==
ENUM_SEARCH_TYPE
.
BOOKSHELF
.
value
},
requestUrl
:
function
()
{
return
!
this
.
searchType
||
this
.
searchType
.
value
==
ENUM_SEARCH_TYPE
.
WAREHOUSE
.
value
?
"/book/articleList/"
:
"/
book/collect/"
},
requestParam
:
function
()
{
return
{
searchName
:
this
.
keyword
}
}
},
watch
:
{
result
:
{
handler
:
function
(
n
)
{
this
.
dataList
=
n
;
},
immediate
:
true
}
},
methods
:
{
refreshList
()
{
let
ref
=
this
.
$refs
.
list
;
if
(
ref
)
{
ref
.
onPullRefreshing
();
}
},
changeData
(
e
)
{
this
.
dataList
=
e
.
detail
.
data
.
map
(
item
=>
{
return
new
WarehouseBookItem
(
item
)
})
},
tapItem
(
e
,
index
)
{
gotoBookContentPage
(
e
.
detail
.
data
.
id
)
},
}
}
</
script
>
<
style
>
</
style
>
\ No newline at end of file
vedio/page-subs/sub_A/book-search/services/index.js
View file @
64d49eb9
import
{
addNormalNotificationObserver
,
postNotification
,
removeNotificationObserver
}
from
"../../../../common/utils/notificationCenter"
;
import
{
readStorage
,
saveStorage
}
from
"../../../../common/utils/storageUtil"
;
const
KEY_STORAGE_SEARCH_HISTORY
=
"KEY_STORAGE_SEARCH_HISTORY"
;
const
KEY_NOTIFICATION_SEARCH_HISTORY_CHANGE
=
'KEY_NOTIFICATION_SEARCH_HISTORY_CHANGE'
;
const
MAX_SEARCH_HISTORY_LENGTH
=
10
;
function
saveSearchHistory
(
keyword
)
{
if
(
!
keyword
)
return
;
let
result
=
readSearchHistory
();
if
(
result
.
indexOf
(
keyword
)
!=
-
1
)
return
;
if
(
result
.
length
==
MAX_SEARCH_HISTORY_LENGTH
)
{
result
.
shift
();
}
result
.
push
(
keyword
);
saveStorage
(
KEY_STORAGE_SEARCH_HISTORY
,
result
);
noticeSearchHistoryChange
(
result
);
}
function
readSearchHistory
()
{
let
result
=
readStorage
(
KEY_STORAGE_SEARCH_HISTORY
);
return
result
||
[]
}
function
noticeSearchHistoryChange
(
result
)
{
if
(
!
result
)
{
result
=
readSearchHistory
();
}
postNotification
(
KEY_NOTIFICATION_SEARCH_HISTORY_CHANGE
,
{
result
})
}
function
watchSearchHistoryChange
(
fn
,
observer
)
{
if
(
typeof
fn
==
'function'
)
fn
.
call
(
observer
,
readSearchHistory
());
addNormalNotificationObserver
(
KEY_NOTIFICATION_SEARCH_HISTORY_CHANGE
,
(
info
)
=>
{
if
(
typeof
fn
==
'function'
)
fn
.
call
(
observer
,
info
.
result
)
},
observer
);
}
function
removeSearchHistoryChangeWatch
(
observer
)
{
removeNotificationObserver
(
KEY_NOTIFICATION_SEARCH_HISTORY_CHANGE
,
observer
);
}
function
getHotRecommondData
(
pageNo
,
pageSize
,
callback
)
{
if
(
typeof
callback
==
'function'
)
callback
(
true
,
[]);
}
module
.
exports
=
{
/**
* 搜索历史
*/
saveSearchHistory
,
import
{
addNormalNotificationObserver
,
postNotification
,
removeNotificationObserver
}
from
"../../../../common/utils/notificationCenter"
;
import
{
readStorage
,
saveStorage
,
clearStorage
}
from
"../../../../common/utils/storageUtil"
;
const
KEY_STORAGE_SEARCH_HISTORY
=
"KEY_STORAGE_SEARCH_HISTORY"
;
const
KEY_NOTIFICATION_SEARCH_HISTORY_CHANGE
=
'KEY_NOTIFICATION_SEARCH_HISTORY_CHANGE'
;
const
MAX_SEARCH_HISTORY_LENGTH
=
10
;
function
saveSearchHistory
(
keyword
)
{
if
(
!
keyword
)
return
;
let
result
=
readSearchHistory
();
if
(
result
.
indexOf
(
keyword
)
!=
-
1
)
return
;
if
(
result
.
length
==
MAX_SEARCH_HISTORY_LENGTH
)
{
result
.
shift
();
}
result
.
push
(
keyword
);
saveStorage
(
KEY_STORAGE_SEARCH_HISTORY
,
result
);
noticeSearchHistoryChange
(
result
);
}
function
clearSearchHistory
()
{
clearStorage
(
KEY_STORAGE_SEARCH_HISTORY
);
noticeSearchHistoryChange
([]);
}
function
readSearchHistory
()
{
let
result
=
readStorage
(
KEY_STORAGE_SEARCH_HISTORY
);
return
result
||
[]
}
function
noticeSearchHistoryChange
(
result
)
{
if
(
!
result
)
{
result
=
readSearchHistory
();
}
postNotification
(
KEY_NOTIFICATION_SEARCH_HISTORY_CHANGE
,
{
result
})
}
function
watchSearchHistoryChange
(
fn
,
observer
)
{
if
(
typeof
fn
==
'function'
)
fn
.
call
(
observer
,
readSearchHistory
());
addNormalNotificationObserver
(
KEY_NOTIFICATION_SEARCH_HISTORY_CHANGE
,
(
info
)
=>
{
if
(
typeof
fn
==
'function'
)
fn
.
call
(
observer
,
info
.
result
)
},
observer
);
}
function
removeSearchHistoryChangeWatch
(
observer
)
{
removeNotificationObserver
(
KEY_NOTIFICATION_SEARCH_HISTORY_CHANGE
,
observer
);
}
function
getHotRecommondData
(
pageNo
,
pageSize
,
callback
)
{
if
(
typeof
callback
==
'function'
)
callback
(
true
,
[]);
}
module
.
exports
=
{
/**
* 搜索历史
*/
saveSearchHistory
,
readSearchHistory
,
watchSearchHistoryChange
,
removeSearchHistoryChangeWatch
,
/**
* 热门推荐
*/
getHotRecommondData
,
clearSearchHistory
,
watchSearchHistoryChange
,
removeSearchHistoryChangeWatch
,
/**
* 热门推荐
*/
getHotRecommondData
,
}
\ No newline at end of file
vedio/page-subs/sub_B/vip-apply/vip-apply.vue
View file @
64d49eb9
...
...
@@ -134,11 +134,11 @@
})
},
refrehsPackData
()
{
getPackData
((
success
,
data
)
=>
{
this
.
packList
=
data
.
map
(
item
=>
{
return
new
Pack
(
item
);
})
})
//
getPackData((success, data) => {
//
this.packList = data.map(item => {
//
return new Pack(item);
//
})
//
})
},
choosePack
(
item
,
index
)
{
this
.
selectedIndex
=
index
;
...
...
vedio/pages/home.vue
View file @
64d49eb9
...
...
@@ -110,6 +110,6 @@
<
style
lang=
"scss"
>
.body
{
height
:
100%
;
background-color
:
white
;
//
background-color: white;
}
</
style
>
\ No newline at end of file
vedio/pages/loading.vue
View file @
64d49eb9
...
...
@@ -47,8 +47,8 @@
methods
:
{
ttLoging
()
{
var
that
=
this
;
var
obj
=
tt
.
getLaunchOptionsSync
()
var
obj
=
tt
.
getLaunchOptionsSync
()
var
tips2
=
''
;
// 投放测试
var
thirdParam
=
""
;
var
bookId
=
''
;
...
...
@@ -59,16 +59,26 @@
if
(
this
.
tips1
==
'mints_book'
||
tips2
==
'mints_book'
)
{
this
.
slotParam
=
JSON
.
stringify
(
obj
.
query
);
this
.
$refs
.
select
.
open
(
'center'
);
}
}
// 首次跳转进小书页面
if
(
bookId
!=
''
)
{
uni
.
setStorage
({
key
:
'firstBookId'
,
data
:
bookId
uni
.
setStorage
({
key
:
'firstBookId'
,
data
:
bookId
});
}
// app.globalData.userId = data.idcode;
// uni.setStorage({
// key: 'token',
// data: 'D6E76AC8E89ABE548B56568B8814D578D6980EAB68926EB1E7C07BF9E96A316F5F433703067DF5142735505C42F58997'
// });
// setTimeout(() => {
// redirectTo('home');
// }, 1000);
// return
tt
.
login
({
force
:
true
,
success
(
res
)
{
...
...
@@ -83,7 +93,7 @@
showLoading
:
false
,
success
:
({
data
})
=>
{
})
=>
{
app
.
globalData
.
userId
=
data
.
idcode
;
uni
.
setStorage
({
key
:
'token'
,
...
...
vedio/scss/common.scss
View file @
64d49eb9
...
...
@@ -300,4 +300,17 @@ body {
line-height
:
40rpx
;
padding
:
0
16rpx
;
display
:
inline-block
;
}
.c-flex_row
{
display
:
flex
;
flex-direction
:
row
;
}
.c-align_center
{
align-items
:
center
;
}
.c-flex_1
{
flex
:
1
;
}
\ No newline at end of file
vedio/uni_modules/uni-easyinput/changelog.md
0 → 100644
View file @
64d49eb9
## 1.1.18(2024-04-11)
-
修复 easyinput组件双向绑定问题
## 1.1.17(2024-03-28)
-
修复 在头条小程序下丢失事件绑定的问题
## 1.1.16(2024-03-20)
-
修复 在密码输入情况下 清除和小眼睛覆盖bug 在edge浏览器下显示双眼睛bug
## 1.1.15(2024-02-21)
-
新增 左侧插槽:left
## 1.1.14(2024-02-19)
-
修复 onBlur的emit传值错误
## 1.1.12(2024-01-29)
-
补充 adjust-position文档属性补充
## 1.1.11(2024-01-29)
-
补充 adjust-position属性传递值:(Boolean)当键盘弹起时,是否自动上推页面
## 1.1.10(2024-01-22)
-
去除 移除无用的log输出
## 1.1.9(2023-04-11)
-
修复 vue3 下 keyboardheightchange 事件报错的bug
## 1.1.8(2023-03-29)
-
优化 trim 属性默认值
## 1.1.7(2023-03-29)
-
新增 cursor-spacing 属性
## 1.1.6(2023-01-28)
-
新增 keyboardheightchange 事件,可监听键盘高度变化
## 1.1.5(2022-11-29)
-
优化 主题样式
## 1.1.4(2022-10-27)
-
修复 props 中背景颜色无默认值的bug
## 1.1.0(2022-06-30)
-
新增 在 uni-forms 1.4.0 中使用可以在 blur 时校验内容
-
新增 clear 事件,点击右侧叉号图标触发
-
新增 change 事件 ,仅在输入框失去焦点或用户按下回车时触发
-
优化 组件样式,组件获取焦点时高亮显示,图标颜色调整等
## 1.0.5(2022-06-07)
-
优化 clearable 显示策略
## 1.0.4(2022-06-07)
-
优化 clearable 显示策略
## 1.0.3(2022-05-20)
-
修复 关闭图标某些情况下无法取消的 bug
## 1.0.2(2022-04-12)
-
修复 默认值不生效的 bug
## 1.0.1(2022-04-02)
-
修复 value 不能为 0 的 bug
## 1.0.0(2021-11-19)
-
优化 组件 UI,并提供设计资源,详见:
[
https://uniapp.dcloud.io/component/uniui/resource
](
https://uniapp.dcloud.io/component/uniui/resource
)
-
文档迁移,详见:
[
https://uniapp.dcloud.io/component/uniui/uni-easyinput
](
https://uniapp.dcloud.io/component/uniui/uni-easyinput
)
## 0.1.4(2021-08-20)
-
修复 在 uni-forms 的动态表单中默认值校验不通过的 bug
## 0.1.3(2021-08-11)
-
修复 在 uni-forms 中重置表单,错误信息无法清除的问题
## 0.1.2(2021-07-30)
-
优化 vue3 下事件警告的问题
## 0.1.1
-
优化 errorMessage 属性支持 Boolean 类型
## 0.1.0(2021-07-13)
-
组件兼容 vue3,如何创建 vue3 项目,详见
[
uni-app 项目支持 vue3 介绍
](
https://ask.dcloud.net.cn/article/37834
)
## 0.0.16(2021-06-29)
-
修复 confirmType 属性(仅 type="text" 生效)导致多行文本框无法换行的 bug
## 0.0.15(2021-06-21)
-
修复 passwordIcon 属性拼写错误的 bug
## 0.0.14(2021-06-18)
-
新增 passwordIcon 属性,当 type=password 时是否显示小眼睛图标
-
修复 confirmType 属性不生效的问题
## 0.0.13(2021-06-04)
-
修复 disabled 状态可清出内容的 bug
## 0.0.12(2021-05-12)
-
新增 组件示例地址
## 0.0.11(2021-05-07)
-
修复 input-border 属性不生效的问题
## 0.0.10(2021-04-30)
-
修复 ios 遮挡文字、显示一半的问题
## 0.0.9(2021-02-05)
-
调整为 uni_modules 目录规范
-
优化 兼容 nvue 页面
vedio/uni_modules/uni-easyinput/components/uni-easyinput/common.js
0 → 100644
View file @
64d49eb9
/**
* @desc 函数防抖
* @param func 目标函数
* @param wait 延迟执行毫秒数
* @param immediate true - 立即执行, false - 延迟执行
*/
export
const
debounce
=
function
(
func
,
wait
=
1000
,
immediate
=
true
)
{
let
timer
;
return
function
()
{
let
context
=
this
,
args
=
arguments
;
if
(
timer
)
clearTimeout
(
timer
);
if
(
immediate
)
{
let
callNow
=
!
timer
;
timer
=
setTimeout
(()
=>
{
timer
=
null
;
},
wait
);
if
(
callNow
)
func
.
apply
(
context
,
args
);
}
else
{
timer
=
setTimeout
(()
=>
{
func
.
apply
(
context
,
args
);
},
wait
)
}
}
}
/**
* @desc 函数节流
* @param func 函数
* @param wait 延迟执行毫秒数
* @param type 1 使用表时间戳,在时间段开始的时候触发 2 使用表定时器,在时间段结束的时候触发
*/
export
const
throttle
=
(
func
,
wait
=
1000
,
type
=
1
)
=>
{
let
previous
=
0
;
let
timeout
;
return
function
()
{
let
context
=
this
;
let
args
=
arguments
;
if
(
type
===
1
)
{
let
now
=
Date
.
now
();
if
(
now
-
previous
>
wait
)
{
func
.
apply
(
context
,
args
);
previous
=
now
;
}
}
else
if
(
type
===
2
)
{
if
(
!
timeout
)
{
timeout
=
setTimeout
(()
=>
{
timeout
=
null
;
func
.
apply
(
context
,
args
)
},
wait
)
}
}
}
}
vedio/uni_modules/uni-easyinput/components/uni-easyinput/uni-easyinput.vue
0 → 100644
View file @
64d49eb9
<
template
>
<view
class=
"uni-easyinput"
:class=
"
{ 'uni-easyinput-error': msg }" :style="boxStyle">
<view
class=
"uni-easyinput__content"
:class=
"inputContentClass"
:style=
"inputContentStyle"
>
<uni-icons
v-if=
"prefixIcon"
class=
"content-clear-icon"
:type=
"prefixIcon"
color=
"#c0c4cc"
@
click=
"onClickIcon('prefix')"
size=
"22"
></uni-icons>
<slot
name=
"left"
>
</slot>
<!-- #ifdef MP-ALIPAY -->
<textarea
:enableNative=
"enableNative"
v-if=
"type === 'textarea'"
class=
"uni-easyinput__content-textarea"
:class=
"
{ 'input-padding': inputBorder }" :name="name" :value="val" :placeholder="placeholder"
:placeholderStyle="placeholderStyle" :disabled="disabled" placeholder-class="uni-easyinput__placeholder-class"
:maxlength="inputMaxlength" :focus="focused" :autoHeight="autoHeight" :cursor-spacing="cursorSpacing"
:adjust-position="adjustPosition" @input="onInput" @blur="_Blur" @focus="_Focus" @confirm="onConfirm"
@keyboardheightchange="onkeyboardheightchange">
</textarea>
<input
:enableNative=
"enableNative"
v-else
:type=
"type === 'password' ? 'text' : type"
class=
"uni-easyinput__content-input"
:style=
"inputStyle"
:name=
"name"
:value=
"val"
:password=
"!showPassword && type === 'password'"
:placeholder=
"placeholder"
:placeholderStyle=
"placeholderStyle"
placeholder-class=
"uni-easyinput__placeholder-class"
:disabled=
"disabled"
:maxlength=
"inputMaxlength"
:focus=
"focused"
:confirmType=
"confirmType"
:cursor-spacing=
"cursorSpacing"
:adjust-position=
"adjustPosition"
@
focus=
"_Focus"
@
blur=
"_Blur"
@
input=
"onInput"
@
confirm=
"onConfirm"
@
keyboardheightchange=
"onkeyboardheightchange"
/>
<!-- #endif -->
<!-- #ifndef MP-ALIPAY -->
<textarea
v-if=
"type === 'textarea'"
class=
"uni-easyinput__content-textarea"
:class=
"
{ 'input-padding': inputBorder }" :name="name" :value="val" :placeholder="placeholder"
:placeholderStyle="placeholderStyle" :disabled="disabled" placeholder-class="uni-easyinput__placeholder-class"
:maxlength="inputMaxlength" :focus="focused" :autoHeight="autoHeight" :cursor-spacing="cursorSpacing"
:adjust-position="adjustPosition" @input="onInput" @blur="_Blur" @focus="_Focus" @confirm="onConfirm"
@keyboardheightchange="onkeyboardheightchange">
</textarea>
<input
v-else
:type=
"type === 'password' ? 'text' : type"
class=
"uni-easyinput__content-input"
:style=
"inputStyle"
:name=
"name"
:value=
"val"
:password=
"!showPassword && type === 'password'"
:placeholder=
"placeholder"
:placeholderStyle=
"placeholderStyle"
placeholder-class=
"uni-easyinput__placeholder-class"
:disabled=
"disabled"
:maxlength=
"inputMaxlength"
:focus=
"focused"
:confirmType=
"confirmType"
:cursor-spacing=
"cursorSpacing"
:adjust-position=
"adjustPosition"
@
focus=
"_Focus"
@
blur=
"_Blur"
@
input=
"onInput"
@
confirm=
"onConfirm"
@
keyboardheightchange=
"onkeyboardheightchange"
/>
<!-- #endif -->
<template
v-if=
"type === 'password' && passwordIcon"
>
<!-- 开启密码时显示小眼睛 -->
<uni-icons
v-if=
"isVal"
class=
"content-clear-icon"
:class=
"
{ 'is-textarea-icon': type === 'textarea' }"
:type="showPassword ? 'eye-slash-filled' : 'eye-filled'" :size="22"
:color="focusShow ? primaryColor : '#c0c4cc'" @click="onEyes">
</uni-icons>
</
template
>
<
template
v-if=
"suffixIcon"
>
<uni-icons
v-if=
"suffixIcon"
class=
"content-clear-icon"
:type=
"suffixIcon"
color=
"#c0c4cc"
@
click=
"onClickIcon('suffix')"
size=
"22"
></uni-icons>
</
template
>
<
template
v-else
>
<uni-icons
v-if=
"clearable && isVal && !disabled && type !== 'textarea'"
class=
"content-clear-icon"
:class=
"
{ 'is-textarea-icon': type === 'textarea' }" type="clear" :size="clearSize"
:color="msg ? '#dd524d' : focusShow ? primaryColor : '#c0c4cc'" @click="onClear">
</uni-icons>
</
template
>
<slot
name=
"right"
></slot>
</view>
</view>
</template>
<
script
>
/**
* Easyinput 输入框
* @description 此组件可以实现表单的输入与校验,包括 "text" 和 "textarea" 类型。
* @tutorial https://ext.dcloud.net.cn/plugin?id=3455
* @property {String} value 输入内容
* @property {String } type 输入框的类型(默认text) password/text/textarea/..
* @value text 文本输入键盘
* @value textarea 多行文本输入键盘
* @value password 密码输入键盘
* @value number 数字输入键盘,注意iOS上app-vue弹出的数字键盘并非9宫格方式
* @value idcard 身份证输入键盘,信、支付宝、百度、QQ小程序
* @value digit 带小数点的数字键盘 ,App的nvue页面、微信、支付宝、百度、头条、QQ小程序支持
* @property {Boolean} clearable 是否显示右侧清空内容的图标控件,点击可清空输入框内容(默认true)
* @property {Boolean} autoHeight 是否自动增高输入区域,type为textarea时有效(默认true)
* @property {String } placeholder 输入框的提示文字
* @property {String } placeholderStyle placeholder的样式(内联样式,字符串),如"color: #ddd"
* @property {Boolean} focus 是否自动获得焦点(默认false)
* @property {Boolean} disabled 是否禁用(默认false)
* @property {Number } maxlength 最大输入长度,设置为 -1 的时候不限制最大长度(默认140)
* @property {String } confirmType 设置键盘右下角按钮的文字,仅在type="text"时生效(默认done)
* @property {Number } clearSize 清除图标的大小,单位px(默认15)
* @property {String} prefixIcon 输入框头部图标
* @property {String} suffixIcon 输入框尾部图标
* @property {String} primaryColor 设置主题色(默认#2979ff)
* @property {Boolean} trim 是否自动去除两端的空格
* @property {Boolean} cursorSpacing 指定光标与键盘的距离,单位 px
* @property {Boolean} ajust-position 当键盘弹起时,是否上推内容,默认值:true
* @value both 去除两端空格
* @value left 去除左侧空格
* @value right 去除右侧空格
* @value start 去除左侧空格
* @value end 去除右侧空格
* @value all 去除全部空格
* @value none 不去除空格
* @property {Boolean} inputBorder 是否显示input输入框的边框(默认true)
* @property {Boolean} passwordIcon type=password时是否显示小眼睛图标
* @property {Object} styles 自定义颜色
* @event {Function} input 输入框内容发生变化时触发
* @event {Function} focus 输入框获得焦点时触发
* @event {Function} blur 输入框失去焦点时触发
* @event {Function} confirm 点击完成按钮时触发
* @event {Function} iconClick 点击图标时触发
* @example <uni-easyinput v-model="mobile"></uni-easyinput>
*/
function
obj2strClass
(
obj
)
{
let
classess
=
''
;
for
(
let
key
in
obj
)
{
const
val
=
obj
[
key
];
if
(
val
)
{
classess
+=
`
${
key
}
`
;
}
}
return
classess
;
}
function
obj2strStyle
(
obj
)
{
let
style
=
''
;
for
(
let
key
in
obj
)
{
const
val
=
obj
[
key
];
style
+=
`
${
key
}
:
${
val
}
;`
;
}
return
style
;
}
export
default
{
name
:
'uni-easyinput'
,
emits
:
[
'click'
,
'iconClick'
,
'update:modelValue'
,
'input'
,
'focus'
,
'blur'
,
'confirm'
,
'clear'
,
'eyes'
,
'change'
,
'keyboardheightchange'
],
model
:
{
prop
:
'modelValue'
,
event
:
'update:modelValue'
},
options
:
{
// #ifdef MP-TOUTIAO
virtualHost
:
false
,
// #endif
// #ifndef MP-TOUTIAO
virtualHost
:
true
// #endif
},
inject
:
{
form
:
{
from
:
'uniForm'
,
default
:
null
},
formItem
:
{
from
:
'uniFormItem'
,
default
:
null
}
},
props
:
{
name
:
String
,
value
:
[
Number
,
String
],
modelValue
:
[
Number
,
String
],
type
:
{
type
:
String
,
default
:
'text'
},
clearable
:
{
type
:
Boolean
,
default
:
true
},
autoHeight
:
{
type
:
Boolean
,
default
:
false
},
placeholder
:
{
type
:
String
,
default
:
' '
},
placeholderStyle
:
String
,
focus
:
{
type
:
Boolean
,
default
:
false
},
disabled
:
{
type
:
Boolean
,
default
:
false
},
maxlength
:
{
type
:
[
Number
,
String
],
default
:
140
},
confirmType
:
{
type
:
String
,
default
:
'done'
},
clearSize
:
{
type
:
[
Number
,
String
],
default
:
24
},
inputBorder
:
{
type
:
Boolean
,
default
:
true
},
prefixIcon
:
{
type
:
String
,
default
:
''
},
suffixIcon
:
{
type
:
String
,
default
:
''
},
trim
:
{
type
:
[
Boolean
,
String
],
default
:
false
},
cursorSpacing
:
{
type
:
Number
,
default
:
0
},
passwordIcon
:
{
type
:
Boolean
,
default
:
true
},
adjustPosition
:
{
type
:
Boolean
,
default
:
true
},
primaryColor
:
{
type
:
String
,
default
:
'#2979ff'
},
styles
:
{
type
:
Object
,
default
()
{
return
{
color
:
'#333'
,
backgroundColor
:
'#fff'
,
disableColor
:
'#F7F6F6'
,
borderColor
:
'#e5e5e5'
};
}
},
errorMessage
:
{
type
:
[
String
,
Boolean
],
default
:
''
},
// #ifdef MP-ALIPAY
enableNative
:
{
type
:
Boolean
,
default
:
false
}
// #endif
},
data
()
{
return
{
focused
:
false
,
val
:
''
,
showMsg
:
''
,
border
:
false
,
isFirstBorder
:
false
,
showClearIcon
:
false
,
showPassword
:
false
,
focusShow
:
false
,
localMsg
:
''
,
isEnter
:
false
// 用于判断当前是否是使用回车操作
};
},
computed
:
{
// 输入框内是否有值
isVal
()
{
const
val
=
this
.
val
;
// fixed by mehaotian 处理值为0的情况,字符串0不在处理范围
if
(
val
||
val
===
0
)
{
return
true
;
}
return
false
;
},
msg
()
{
// console.log('computed', this.form, this.formItem);
// if (this.form) {
// return this.errorMessage || this.formItem.errMsg;
// }
// TODO 处理头条 formItem 中 errMsg 不更新的问题
return
this
.
localMsg
||
this
.
errorMessage
;
},
// 因为uniapp的input组件的maxlength组件必须要数值,这里转为数值,用户可以传入字符串数值
inputMaxlength
()
{
return
Number
(
this
.
maxlength
);
},
// 处理外层样式的style
boxStyle
()
{
return
`color:
${
this
.
inputBorder
&&
this
.
msg
?
'#e43d33'
:
this
.
styles
.
color
}
;`
;
},
// input 内容的类和样式处理
inputContentClass
()
{
return
obj2strClass
({
'is-input-border'
:
this
.
inputBorder
,
'is-input-error-border'
:
this
.
inputBorder
&&
this
.
msg
,
'is-textarea'
:
this
.
type
===
'textarea'
,
'is-disabled'
:
this
.
disabled
,
'is-focused'
:
this
.
focusShow
});
},
inputContentStyle
()
{
const
focusColor
=
this
.
focusShow
?
this
.
primaryColor
:
this
.
styles
.
borderColor
;
const
borderColor
=
this
.
inputBorder
&&
this
.
msg
?
'#dd524d'
:
focusColor
;
return
obj2strStyle
({
'border-color'
:
borderColor
||
'#e5e5e5'
,
'background-color'
:
this
.
disabled
?
this
.
styles
.
disableColor
:
this
.
styles
.
backgroundColor
});
},
// input右侧样式
inputStyle
()
{
const
paddingRight
=
this
.
type
===
'password'
||
this
.
clearable
||
this
.
prefixIcon
?
''
:
'10px'
;
return
obj2strStyle
({
'padding-right'
:
paddingRight
,
'padding-left'
:
this
.
prefixIcon
?
''
:
'10px'
});
}
},
watch
:
{
value
(
newVal
)
{
this
.
val
=
newVal
;
},
modelValue
(
newVal
)
{
this
.
val
=
newVal
;
},
focus
(
newVal
)
{
this
.
$nextTick
(()
=>
{
this
.
focused
=
this
.
focus
;
this
.
focusShow
=
this
.
focus
;
});
}
},
created
()
{
this
.
init
();
// TODO 处理头条vue3 computed 不监听 inject 更改的问题(formItem.errMsg)
if
(
this
.
form
&&
this
.
formItem
)
{
this
.
$watch
(
'formItem.errMsg'
,
newVal
=>
{
this
.
localMsg
=
newVal
;
});
}
},
mounted
()
{
this
.
$nextTick
(()
=>
{
this
.
focused
=
this
.
focus
;
this
.
focusShow
=
this
.
focus
;
});
},
methods
:
{
/**
* 初始化变量值
*/
init
()
{
if
(
this
.
value
||
this
.
value
===
0
)
{
this
.
val
=
this
.
value
;
}
else
if
(
this
.
modelValue
||
this
.
modelValue
===
0
||
this
.
modelValue
===
''
)
{
this
.
val
=
this
.
modelValue
;
}
else
{
this
.
val
=
null
;
}
},
/**
* 点击图标时触发
* @param {Object} type
*/
onClickIcon
(
type
)
{
this
.
$emit
(
'iconClick'
,
type
);
},
/**
* 显示隐藏内容,密码框时生效
*/
onEyes
()
{
this
.
showPassword
=
!
this
.
showPassword
;
this
.
$emit
(
'eyes'
,
this
.
showPassword
);
},
/**
* 输入时触发
* @param {Object} event
*/
onInput
(
event
)
{
let
value
=
event
.
detail
.
value
;
// 判断是否去除空格
if
(
this
.
trim
)
{
if
(
typeof
this
.
trim
===
'boolean'
&&
this
.
trim
)
{
value
=
this
.
trimStr
(
value
);
}
if
(
typeof
this
.
trim
===
'string'
)
{
value
=
this
.
trimStr
(
value
,
this
.
trim
);
}
}
if
(
this
.
errMsg
)
this
.
errMsg
=
''
;
this
.
val
=
value
;
// TODO 兼容 vue2
this
.
$emit
(
'input'
,
value
);
// TODO 兼容 vue3
this
.
$emit
(
'update:modelValue'
,
value
);
},
/**
* 外部调用方法
* 获取焦点时触发
* @param {Object} event
*/
onFocus
()
{
this
.
$nextTick
(()
=>
{
this
.
focused
=
true
;
});
this
.
$emit
(
'focus'
,
null
);
},
_Focus
(
event
)
{
this
.
focusShow
=
true
;
this
.
$emit
(
'focus'
,
event
);
},
/**
* 外部调用方法
* 失去焦点时触发
* @param {Object} event
*/
onBlur
()
{
this
.
focused
=
false
;
this
.
$emit
(
'blur'
,
null
);
},
_Blur
(
event
)
{
let
value
=
event
.
detail
.
value
;
this
.
focusShow
=
false
;
this
.
$emit
(
'blur'
,
event
);
// 根据类型返回值,在event中获取的值理论上讲都是string
if
(
this
.
isEnter
===
false
)
{
this
.
$emit
(
'change'
,
this
.
val
);
}
// 失去焦点时参与表单校验
if
(
this
.
form
&&
this
.
formItem
)
{
const
{
validateTrigger
}
=
this
.
form
;
if
(
validateTrigger
===
'blur'
)
{
this
.
formItem
.
onFieldChange
();
}
}
},
/**
* 按下键盘的发送键
* @param {Object} e
*/
onConfirm
(
e
)
{
this
.
$emit
(
'confirm'
,
this
.
val
);
this
.
isEnter
=
true
;
this
.
$emit
(
'change'
,
this
.
val
);
this
.
$nextTick
(()
=>
{
this
.
isEnter
=
false
;
});
},
/**
* 清理内容
* @param {Object} event
*/
onClear
(
event
)
{
this
.
val
=
''
;
// TODO 兼容 vue2
this
.
$emit
(
'input'
,
''
);
// TODO 兼容 vue2
// TODO 兼容 vue3
this
.
$emit
(
'update:modelValue'
,
''
);
// 点击叉号触发
this
.
$emit
(
'clear'
);
},
/**
* 键盘高度发生变化的时候触发此事件
* 兼容性:微信小程序2.7.0+、App 3.1.0+
* @param {Object} event
*/
onkeyboardheightchange
(
event
)
{
this
.
$emit
(
'keyboardheightchange'
,
event
);
},
/**
* 去除空格
*/
trimStr
(
str
,
pos
=
'both'
)
{
if
(
pos
===
'both'
)
{
return
str
.
trim
();
}
else
if
(
pos
===
'left'
)
{
return
str
.
trimLeft
();
}
else
if
(
pos
===
'right'
)
{
return
str
.
trimRight
();
}
else
if
(
pos
===
'start'
)
{
return
str
.
trimStart
();
}
else
if
(
pos
===
'end'
)
{
return
str
.
trimEnd
();
}
else
if
(
pos
===
'all'
)
{
return
str
.
replace
(
/
\s
+/g
,
''
);
}
else
if
(
pos
===
'none'
)
{
return
str
;
}
return
str
;
}
}
};
</
script
>
<
style
lang=
"scss"
>
$uni-error
:
#e43d33
;
$uni-border-1
:
#dcdfe6
!
default
;
.uni-easyinput
{
/* #ifndef APP-NVUE */
width
:
100%
;
/* #endif */
flex
:
1
;
position
:
relative
;
text-align
:
left
;
color
:
#333
;
font-size
:
14px
;
}
.uni-easyinput__content
{
flex
:
1
;
/* #ifndef APP-NVUE */
width
:
100%
;
display
:
flex
;
box-sizing
:
border-box
;
// min-height: 36px;
/* #endif */
flex-direction
:
row
;
align-items
:
center
;
// 处理border动画刚开始显示黑色的问题
border-color
:
#fff
;
transition-property
:
border-color
;
transition-duration
:
0
.3s
;
}
.uni-easyinput__content-input
{
/* #ifndef APP-NVUE */
width
:
auto
;
/* #endif */
position
:
relative
;
overflow
:
hidden
;
flex
:
1
;
line-height
:
1
;
font-size
:
14px
;
height
:
35px
;
// min-height: 36px;
/*ifdef H5*/
&
:
:-
ms-reveal
{
display
:
none
;
}
&
:
:-
ms-clear
{
display
:
none
;
}
&
:
:-
o-clear
{
display
:
none
;
}
/*endif*/
}
.uni-easyinput__placeholder-class
{
color
:
#999
;
font-size
:
12px
;
// font-weight: 200;
}
.is-textarea
{
align-items
:
flex-start
;
}
.is-textarea-icon
{
margin-top
:
5px
;
}
.uni-easyinput__content-textarea
{
position
:
relative
;
overflow
:
hidden
;
flex
:
1
;
line-height
:
1
.5
;
font-size
:
14px
;
margin
:
6px
;
margin-left
:
0
;
height
:
80px
;
min-height
:
80px
;
/* #ifndef APP-NVUE */
min-height
:
80px
;
width
:
auto
;
/* #endif */
}
.input-padding
{
padding-left
:
10px
;
}
.content-clear-icon
{
padding
:
0
5px
;
}
.label-icon
{
margin-right
:
5px
;
margin-top
:
-1px
;
}
// 显示边框
.is-input-border
{
/* #ifndef APP-NVUE */
display
:
flex
;
box-sizing
:
border-box
;
/* #endif */
flex-direction
:
row
;
align-items
:
center
;
border
:
1px
solid
$uni-border-1
;
border-radius
:
4px
;
/* #ifdef MP-ALIPAY */
overflow
:
hidden
;
/* #endif */
}
.uni-error-message
{
position
:
absolute
;
bottom
:
-17px
;
left
:
0
;
line-height
:
12px
;
color
:
$uni-error
;
font-size
:
12px
;
text-align
:
left
;
}
.uni-error-msg--boeder
{
position
:
relative
;
bottom
:
0
;
line-height
:
22px
;
}
.is-input-error-border
{
border-color
:
$uni-error
;
.uni-easyinput__placeholder-class
{
color
:
mix
(
#fff
,
$uni-error
,
50%
);
}
}
.uni-easyinput--border
{
margin-bottom
:
0
;
padding
:
10px
15px
;
// padding-bottom: 0;
border-top
:
1px
#eee
solid
;
}
.uni-easyinput-error
{
padding-bottom
:
0
;
}
.is-first-border
{
/* #ifndef APP-NVUE */
border
:
none
;
/* #endif */
/* #ifdef APP-NVUE */
border-width
:
0
;
/* #endif */
}
.is-disabled
{
background-color
:
#f7f6f6
;
color
:
#d5d5d5
;
.uni-easyinput__placeholder-class
{
color
:
#d5d5d5
;
font-size
:
12px
;
}
}
</
style
>
vedio/uni_modules/
yingbing-flip
/package.json
→
vedio/uni_modules/
uni-easyinput
/package.json
View file @
64d49eb9
{
"id"
:
"
yingbing-flip
"
,
"displayName"
:
"
好用翻页组件
"
,
"version"
:
"1.
0.4
"
,
"description"
:
"
高性能翻页组件
"
,
"id"
:
"
uni-easyinput
"
,
"displayName"
:
"
uni-easyinput 增强输入框
"
,
"version"
:
"1.
1.18
"
,
"description"
:
"
Easyinput 组件是对原生input组件的增强
"
,
"keywords"
:
[
"翻页"
"uni-ui"
,
"uniui"
,
"input"
,
"uni-easyinput"
,
"输入框"
],
"repository"
:
"https://git
ee.com/yingbing-developer/yingbing-flip.git
"
,
"repository"
:
"https://git
hub.com/dcloudio/uni-ui
"
,
"engines"
:
{
"HBuilderX"
:
"
^3.1.0
"
"HBuilderX"
:
""
},
"dcloudext"
:
{
"type"
:
"component-vue"
,
"directories"
:
{
"example"
:
"../../temps/example_temps"
},
"dcloudext"
:
{
"sale"
:
{
"regular"
:
{
"price"
:
"0.00"
...
...
@@ -28,52 +34,53 @@
"data"
:
"无"
,
"permissions"
:
"无"
},
"npmurl"
:
""
"npmurl"
:
"https://www.npmjs.com/package/@dcloudio/uni-ui"
,
"type"
:
"component-vue"
},
"uni_modules"
:
{
"dependencies"
:
[],
"dependencies"
:
[
"uni-scss"
,
"uni-icons"
],
"encrypt"
:
[],
"platforms"
:
{
"cloud"
:
{
"tcb"
:
"y"
,
"aliyun"
:
"y"
"aliyun"
:
"y"
,
"alipay"
:
"n"
},
"client"
:
{
"Vue"
:
{
"vue2"
:
"u"
,
"vue3"
:
"u"
},
"App"
:
{
"app-vue"
:
"
u
"
,
"app-nvue"
:
"
u
"
"app-vue"
:
"
y
"
,
"app-nvue"
:
"
y
"
},
"H5-mobile"
:
{
"Safari"
:
"
u
"
,
"Android Browser"
:
"
u
"
,
"微信浏览器(Android)"
:
"
u
"
,
"QQ浏览器(Android)"
:
"
u
"
"Safari"
:
"
y
"
,
"Android Browser"
:
"
y
"
,
"微信浏览器(Android)"
:
"
y
"
,
"QQ浏览器(Android)"
:
"
y
"
},
"H5-pc"
:
{
"Chrome"
:
"
u
"
,
"IE"
:
"
u
"
,
"Edge"
:
"
u
"
,
"Firefox"
:
"
u
"
,
"Safari"
:
"
u
"
"Chrome"
:
"
y
"
,
"IE"
:
"
y
"
,
"Edge"
:
"
y
"
,
"Firefox"
:
"
y
"
,
"Safari"
:
"
y
"
},
"小程序"
:
{
"微信"
:
"u"
,
"阿里"
:
"u"
,
"百度"
:
"u"
,
"字节跳动"
:
"u"
,
"QQ"
:
"u"
,
"钉钉"
:
"u"
,
"快手"
:
"u"
,
"飞书"
:
"u"
,
"京东"
:
"u"
"微信"
:
"y"
,
"阿里"
:
"y"
,
"百度"
:
"y"
,
"字节跳动"
:
"y"
,
"QQ"
:
"y"
},
"快应用"
:
{
"华为"
:
"u"
,
"联盟"
:
"u"
},
"Vue"
:
{
"vue2"
:
"y"
,
"vue3"
:
"y"
}
}
}
...
...
vedio/uni_modules/yingbing-flip/changelog.md
deleted
100644 → 0
View file @
afe8cef8
## 1.0.4(2023-09-02)
*
解决插槽中有scroll-view等滚动组件时滑动报错的问题
## 1.0.3(2023-08-23)
*
解决APP-NVUE端resetLoading不生效的问题
## 1.0.2(2023-07-25)
*
解决竖直翻页时,点击上下2侧翻页不准确得问题
## 1.0.1(2023-07-24)
*
解决APP-NVUE无法点击左右2侧翻页得问题
## 1.0.0(2023-07-22)
*
第一次更新
vedio/uni_modules/yingbing-flip/components/modules/flip.wxs
deleted
100644 → 0
View file @
afe8cef8
function touchstart (event, ins) {
var state = ins.getState()
if ( state.isTouch || state.disableTouch ) {
return
}
state.isTouch = true
state.touchTime = 0
state.interval = true
setInterval(ins)
var touch = event.touches[0]
state.startX = touch.pageX
state.startY = touch.pageY
}
function touchmove (event, ins) {
var state = ins.getState()
if ( state.isTouch && !state.disableTouch ) {
var touch = event.touches[0]
state.offset = state.vertical ? touch.pageY - state.startY : touch.pageX - state.startX;
if (state.direction) {
var rect = ins.getBoundingClientRect()
var size = state.vertical ? rect.height : rect.width
state.offset = state.direction == 'next' ? state.offset + state.sliderFault : state.offset - state.sliderFault
if ( (state.offset > 0 && state.direction == 'next') || (state.offset < 0 && state.direction == 'prev') ) {
state.offset = 0
}
if ( Math.abs(state.offset) <= size ) {
animation(state.offset, 0, ins)
}
} else {
if ( Math.abs(state.offset) < state.sliderFault ) {
return
}
if ( state.offset < 0 ) {
if ( state.nextIndex < state.count && state.nextIndex != 0 ) {
if ( state.type != 'none' ) {state.direction = 'next'}
} else if ( state.pullupable && state.loadingState != 'loading' && state.loadingState != 'success' && state.loadingState != 'fail' ) {
state.loadingType = 'pullup'
state.offset = state.offset + state.sliderFault
pulling(state.offset, ins)
}
} else {
if ( state.prevIndex >= 0 && state.prevIndex != state.count - 1 ) {
if ( state.type != 'none' ) {state.direction = 'prev'}
} else if ( state.pulldownable && state.loadingState != 'loading' && state.loadingState != 'success' && state.loadingState != 'fail' ) {
state.loadingType = 'pulldown'
state.offset = state.offset - state.sliderFault
pulling(state.offset, ins)
}
}
}
}
}
function touchend (event, ins) {
touchaction(event, ins)
}
function touchcancel (event, ins) {
touchaction(event, ins)
}
function touchaction (event, ins,isFlipTo) {
var state = ins.getState()
clearInterval(ins)
if ( state.isTouch && !state.disableTouch ) {
var rect = ins.getBoundingClientRect()
var size = state.vertical ? rect.height : rect.width
var start = state.vertical ? state.startY : state.startX
if ( !state.direction && state.touchTime <= 200 && (!state.unableClickPage || state.type == 'none') && !isFlipTo ) {
//获取点击位置,判断向哪里翻页
if (start > (size / 4) * 3 && state.nextIndex < state.count && state.nextIndex != 0 ) {
state.direction = 'next'
}
if (start < (size / 4) && state.prevIndex >= 0 && state.prevIndex != state.count - 1 ) {
state.direction = 'prev'
}
}
if (state.direction) {
state.disableTouch = true
if (state.touchTime <= 200) {
var duration = state.type == 'none' ? 0 : state.duration;
var value = state.direction == 'next' ? 1 : -1;
animation(-value * size, duration, ins);
ins.setTimeout(function () {
resetShadow(ins, true)
ins.callMethod('handleFlipChange', value);
}, duration + 50)
} else {
var duration = state.type == 'none' ? 0 : state.duration;
if (Math.abs(state.offset) >= size / 4) {
var value = state.direction == 'next' ? 1 : -1;
animation(-value * size, duration, ins);
ins.setTimeout(function () {
resetShadow(ins, true)
ins.callMethod('handleFlipChange', value);
}, duration + 50)
} else {
animation(0, duration, ins);
ins.setTimeout(function () {
resetShadow(ins)
resetFlip(ins);
}, duration + 50)
}
}
} else if ( state.loadingState == 'default' ) {
resetPulling(ins)
} else if ( state.loadingState == 'ready' ) {
pullingRefresh(ins)
} else {
resetShadow(ins, false)
resetFlip(ins)
}
}
}
function propWatcher (newVal, oldVal, ins) {
ins.setTimeout(function () {
var state = ins.getState()
state.vertical = newVal.vertical
state.pulldownable = newVal.pulldownable
state.pullupable = newVal.pullupable
state.pulldownHeight = newVal.pulldownHeight
state.loadingState = newVal.loadingState
state.pullupHeight = newVal.pullupHeight
state.duration = newVal.duration
state.nextIndex = newVal.nextIndex
state.prevIndex = newVal.prevIndex
state.currentIndex = newVal.currentIndex
state.sliderFault = newVal.sliderFault
state.count = newVal.count
state.type = newVal.type
state.unableClickPage = newVal.unableClickPage
state.translate = newVal.translate
if ( oldVal && newVal.currentIndex != oldVal.currentIndex ) {
resetFlip(ins);
}
if ( oldVal && newVal.loadingState != oldVal.loadingState && state.loadingState ) {
resetPulling(ins)
ins.callMethod('resetLoading')
}
if (oldVal && newVal.flipTo != oldVal.flipTo && newVal.flipTo != 0 ) {
if ( !state.disableTouch ) {
if ( newVal.flipTo < 0 && state.prevIndex >= 0 && (state.prevIndex != state.count - 1) ) {
state.isTouch = true
state.touchTime = 0
state.direction = 'prev'
touchaction(null, ins, true)
}
if ( newVal.flipTo > 0 && state.nextIndex < state.count && state.nextIndex != 0 ) {
state.isTouch = true
state.touchTime = 0
state.direction = 'next'
touchaction(null, ins, true)
}
}
}
}, 100)
}
function setInterval (ins) {
var state = ins.getState()
state.touchTimer = ins.setTimeout(function () {
state.touchTime += 10
if ( state.interval ) {
setInterval(ins)
}
}, 10)
}
function clearInterval (ins) {
var state = ins.getState()
state.interval = false
if ( state.touchTimer ) {
ins.clearTimeout(state.touchTimer)
state.touchTimer = null
}
}
function resetShadow (ins, isChange) {
var state = ins.getState()
var direction = state.direction
if ( !direction ) {
return
}
var index = direction == 'next' ? state.currentIndex : state.prevIndex
var translate = state.translate
var rect = ins.getBoundingClientRect()
var size = state.vertical ? rect.height : rect.width;
var draw = function () {
ins.selectComponent('.yingbing-flip-item_' + index).setStyle({
'box-shadow': '',
transform: translate + '(' + (isChange ? (direction == 'next'? -size : 0) : (direction == 'next'? 0 : -size)) + 'px)',
transition: ''
})
if ( state.type == 'real' ) {
ins.selectComponent('.yingbing-flip-item-bg_' + index).setStyle({
'box-shadow': '',
transform: translate + '(' + (isChange ? (direction == 'next' ? 0 : size) : (direction == 'next' ? size : 0)) + 'px)',
transition: ''
})
}
ins.selectComponent('.yingbing-flip-item-shadow_' + index).setStyle({
'box-shadow': '',
transition: ''
})
}
ins.requestAnimationFrame(draw)
}
function resetFlip (ins) {
var state = ins.getState()
state.direction = null
state.isTouch = false
state.disableTouch = false
state.offset = 0
state.touchTime = 0
state.startX = 0
state.startY = 0
}
function animation (offset, duration, ins, noshadow) {
var state = ins.getState()
var rect = ins.getBoundingClientRect()
var size = state.vertical ? rect.height : rect.width
var translate = state.translate
var late = offset
var draw = function () {
if ( state.direction == 'prev' ) {
if ( state.prevIndex >= 0 ) {
ins.selectComponent('.yingbing-flip-item_' + state.prevIndex).setStyle({
transform: translate + '(' + (late - size) + 'px)',
'box-shadow': noshadow ? '' : state.type == 'real' ? '0 0 30px 20px rgba(0,0,0,0.4)' : state.type == 'cover' ? '0 0 10px 5px rgba(0,0,0,0.3)' : '',
transition: duration > 0 ? 'transform ' + duration + 'ms' : ''
})
if ( state.type == 'real' ) {
ins.selectComponent('.yingbing-flip-item-content_' + state.prevIndex).setStyle({
transform: translate + '(' + (size-late) + 'px)',
transition: duration > 0 ? 'transform ' + duration + 'ms' : ''
})
ins.selectComponent('.yingbing-flip-item-bg_' + state.prevIndex).setStyle({
transform: translate + '(' + (late) + 'px)',
'box-shadow': noshadow ? '' : '-5px 0 20px rgba(0,0,0,0.1)',
transition: duration > 0 ? 'transform ' + duration + 'ms, ' + 'boxShadow ' + duration + 'ms' : ''
})
ins.selectComponent('.yingbing-flip-item-shadow_' + state.prevIndex).setStyle({
'box-shadow': noshadow ? '' : '0 0 60px 30px rgba(0,0,0,0.4)',
transition: duration > 0 ? 'boxShadow ' + duration + 'ms' : ''
})
}
}
} else {
if ( state.nextIndex < state.count ) {
ins.selectComponent('.yingbing-flip-item_' + state.nextIndex).setStyle({
transform: translate + '(0)',
transition: ''
})
}
ins.selectComponent('.yingbing-flip-item_' + state.currentIndex).setStyle({
transform: translate + '(' + late + 'px)',
'box-shadow': noshadow ? '' : state.type == 'real' ? '0 0 30px 20px rgba(0,0,0,0.4)' : state.type == 'cover' ? '0 0 10px 5px rgba(0,0,0,0.3)' : '',
transition: duration > 0 ? 'transform ' + duration + 'ms' : ''
})
if ( state.type == 'real' ) {
ins.selectComponent('.yingbing-flip-item-content_' + state.currentIndex).setStyle({
transform: translate + '(' + (-late) + 'px)',
transition: duration > 0 ? 'transform ' + duration + 'ms' : ''
})
ins.selectComponent('.yingbing-flip-item-bg_' + state.currentIndex).setStyle({
transform: translate + '(' + (late + size) + 'px)',
'box-shadow': noshadow ? '' : '-5px 0 20px rgba(0,0,0,0.1)',
transition: duration > 0 ? 'transform ' + duration + 'ms, ' + 'boxShadow ' + duration + 'ms' : ''
})
ins.selectComponent('.yingbing-flip-item-shadow_' + state.currentIndex).setStyle({
'box-shadow': noshadow ? '' : '0 0 60px 30px rgba(0,0,0,0.4)',
transition: duration > 0 ? 'boxShadow ' + duration + 'ms' : ''
})
}
}
}
ins.requestAnimationFrame(draw)
}
function pulling (offset, ins) {
var state = ins.getState()
var loadingType = state.loadingType
var translate = state.translate
var size = loadingType == 'pullup' ? state.pullupHeight : state.pulldownHeight
var late = offset
if ( Math.abs(state.offset) < size ) {
state.loadingState = 'default'
} else {
state.loadingState = 'ready'
}
var draw = function () {
var pullingItems = ins.selectAllComponents('.yingbing-flip-' + loadingType + '-item')
for ( var i = 0; i < pullingItems.length; i++ ) {
if ( pullingItems[i].hasClass('yingbing-flip-' + loadingType + '-' + state.loadingState) ) {
pullingItems[i].setStyle({
visibility: 'visible'
})
} else {
pullingItems[i].setStyle({
visibility: 'hidden'
})
}
}
if ( Math.abs(late) <= size ) {
ins.selectComponent('.yingbing-flip-' + loadingType).setStyle({
transform: translate + '(' + (loadingType == 'pullup' ? late + size : late - size) + 'px)',
transition: ''
})
}
}
ins.requestAnimationFrame(draw)
}
function resetPulling (ins) {
var state = ins.getState()
var loadingType = state.loadingType
var translate = state.translate
var size = loadingType == 'pullup' ? state.pullupHeight : state.pulldownHeight
var draw = function () {
var pullingItems = ins.selectAllComponents('.yingbing-flip-' + loadingType + '-item')
for ( var i = 0; i < pullingItems.length; i++ ) {
if ( pullingItems[i].hasClass('yingbing-flip-' + loadingType + '-' + state.loadingState) ) {
pullingItems[i].setStyle({
visibility: 'visible'
})
} else {
pullingItems[i].setStyle({
visibility: 'hidden'
})
}
}
ins.selectComponent('.yingbing-flip-' + loadingType).setStyle({
transform: translate + '(' + (loadingType == 'pullup' ? size : -size) + 'px)',
transition: 'transform .3s'
})
}
ins.requestAnimationFrame(draw)
if ( state.loadingState ) {
ins.setTimeout( function () {
state.loadingState = ''
resetPulling(ins)
}, 300)
} else {
state.loadingType = ''
resetFlip(ins)
}
}
function pullingRefresh (ins) {
var state = ins.getState()
state.loadingState = 'loading'
var loadingType = state.loadingType
var draw = function () {
var pullingItems = ins.selectAllComponents('.yingbing-flip-' + loadingType + '-item')
for ( var i = 0; i < pullingItems.length; i++ ) {
if ( pullingItems[i].hasClass('yingbing-flip-' + loadingType + '-loading') ) {
pullingItems[i].setStyle({
visibility: 'visible'
})
} else {
pullingItems[i].setStyle({
visibility: 'hidden'
})
}
}
}
ins.requestAnimationFrame(draw)
ins.callMethod('pullingRefresh', state.loadingType)
}
module.exports = {
touchstart: touchstart,
touchmove: touchmove,
touchend: touchend,
touchcancel: touchcancel,
propWatcher: propWatcher
}
\ No newline at end of file
vedio/uni_modules/yingbing-flip/components/modules/flip_bindingx.js
deleted
100644 → 0
View file @
afe8cef8
const
Binding
=
uni
.
requireNativePlugin
(
'bindingx'
)
const
animation
=
uni
.
requireNativePlugin
(
'animation'
)
const
dom
=
uni
.
requireNativePlugin
(
'dom'
)
import
Util
from
'../../js_sdk/util.js'
export
default
{
data
()
{
return
{
disableTouch
:
false
,
isTouch
:
false
,
touchTime
:
0
,
interval
:
false
,
loadingType
:
''
,
direction
:
''
}
},
beforeDestroy
()
{
if
(
this
.
flipBinding
)
{
Binding
.
unbind
({
token
:
this
.
flipBinding
.
token
,
eventType
:
'pan'
})
this
.
sliderBinding
=
null
}
this
.
resetFlipAnimationBinding
()
},
methods
:
{
fliptouchstart
(
event
)
{
if
(
this
.
isTouch
||
this
.
disableTouch
)
{
return
}
this
.
isTouch
=
true
this
.
touchTime
=
0
this
.
interval
=
true
this
.
setInterval
()
let
touch
=
event
.
touches
[
0
]
this
.
startX
=
touch
.
pageX
this
.
startY
=
touch
.
pageY
},
fliptouchmove
(
event
)
{
if
(
this
.
isTouch
&&
!
this
.
disableTouch
)
{
let
touch
=
event
.
touches
[
0
]
let
offset
=
this
.
vertical
?
touch
.
pageY
-
this
.
startY
:
touch
.
pageX
-
this
.
startX
if
(
!
this
.
direction
)
{
if
(
Math
.
abs
(
offset
)
<
this
.
sliderFault
)
return
if
(
offset
<
0
)
{
if
(
this
.
nextIndex
<
this
.
count
&&
this
.
nextIndex
!=
0
)
{
if
(
this
.
type
!=
'none'
)
{
this
.
direction
=
'next'
}
}
else
if
(
this
.
pullupable
&&
this
.
loadingState
!=
'loading'
&&
this
.
loadingState
!=
'success'
&&
this
.
loadingState
!=
'fail'
)
{
this
.
loadingType
=
'pullup'
this
.
disableTouch
=
true
this
.
clearInterval
()
this
.
pulling
()
}
}
else
{
if
(
this
.
prevIndex
>
-
1
&&
this
.
prevIndex
!=
this
.
count
-
1
)
{
if
(
this
.
type
!=
'none'
)
{
this
.
direction
=
'prev'
}
}
else
if
(
this
.
pulldownable
&&
this
.
loadingState
!=
'loading'
&&
this
.
loadingState
!=
'success'
&&
this
.
loadingState
!=
'fail'
)
{
this
.
loadingType
=
'pulldown'
this
.
disableTouch
=
true
this
.
clearInterval
()
this
.
pulling
()
}
}
}
if
(
this
.
direction
)
{
this
.
disableTouch
=
true
this
.
flipTouchAction
()
}
else
{
this
.
resetPageBinding
()
}
}
},
async
fliptouchend
(
e
)
{
if
(
this
.
isTouch
&&
!
this
.
disableTouch
)
{
let
rect
=
await
this
.
getRect
(
this
.
$refs
.
yingbingFlip
)
let
size
=
this
.
vertical
?
rect
.
height
:
rect
.
width
this
.
clearInterval
()
let
start
=
this
.
vertical
?
this
.
startY
:
this
.
startX
if
(
this
.
touchTime
<=
200
&&
(
!
this
.
unableClickPage
||
this
.
type
==
'none'
)
)
{
if
(
start
>
(
size
/
4
)
*
3
&&
this
.
nextIndex
<
this
.
count
&&
this
.
nextIndex
!=
0
)
{
this
.
flipToNextBindingX
()
}
else
if
(
start
<
(
size
/
4
)
&&
this
.
prevIndex
>=
0
&&
this
.
prevIndex
!=
this
.
count
-
1
)
{
this
.
flipToPrevBindingX
()
}
else
{
this
.
resetPageBinding
()
}
}
else
{
this
.
resetPageBinding
()
}
}
},
async
flipTouchAction
()
{
let
props
=
[]
let
rect
=
await
this
.
getRect
(
this
.
$refs
.
yingbingFlip
)
let
size
=
this
.
vertical
?
rect
.
height
:
rect
.
width
let
translate
=
this
.
translate
let
shadowProperty
=
this
.
vertical
?
'height'
:
'width'
let
key
=
this
.
vertical
?
'y'
:
'x'
if
(
this
.
direction
==
'prev'
)
{
if
(
this
.
prevIndex
>
-
1
)
{
props
.
push
({
element
:
this
.
getEl
(
'yingbingFlipItem_'
+
this
.
prevIndex
),
property
:
'transform.'
+
translate
,
expression
:
`
${
key
}
< 0 ?
${
-
size
}
: (
${
key
}
>
${
size
}
? 0 :
${
key
}
-
${
size
}
)`
})
if
(
this
.
type
==
'real'
)
{
props
.
push
({
element
:
this
.
getEl
(
'yingbingFlipItemContent_'
+
this
.
prevIndex
),
property
:
'transform.'
+
translate
,
expression
:
`
${
key
}
< 0 ?
${
size
}
: (
${
key
}
>
${
size
}
? 0 :
${
size
}
-
${
key
}
)`
})
props
.
push
({
element
:
this
.
getEl
(
'yingbingFlipItemBg_'
+
this
.
prevIndex
),
property
:
'transform.'
+
translate
,
expression
:
`
${
key
}
< 0 ? 0 : (
${
key
}
>
${
size
}
?
${
size
}
:
${
key
}
+ 0)`
})
props
.
push
({
element
:
this
.
getEl
(
'yingbingFlipItemShadow_'
+
this
.
prevIndex
),
property
:
shadowProperty
,
expression
:
`
${
size
}
/ 2 - abs(
${
key
}
) / 2'`
})
}
}
}
else
{
if
(
this
.
nextIndex
<
this
.
count
)
{
props
.
push
({
element
:
this
.
getEl
(
'yingbingFlipItem_'
+
this
.
nextIndex
),
property
:
'transform.'
+
translate
,
expression
:
'0+0'
})
}
props
.
push
({
element
:
this
.
getEl
(
'yingbingFlipItem_'
+
this
.
currentIndex
),
property
:
'transform.'
+
translate
,
expression
:
`
${
key
}
> 0 ? 0 : (
${
key
}
<
${
-
size
}
?
${
-
size
}
:
${
key
}
+ 0)`
})
if
(
this
.
type
==
'real'
)
{
props
.
push
({
element
:
this
.
getEl
(
'yingbingFlipItemContent_'
+
this
.
currentIndex
),
property
:
'transform.'
+
translate
,
expression
:
`
${
key
}
> 0 ? 0 : (
${
key
}
<
${
-
size
}
?
${
size
}
: 0 -
${
key
}
)'`
})
props
.
push
({
element
:
this
.
getEl
(
'yingbingFlipItemBg_'
+
this
.
currentIndex
),
property
:
'transform.'
+
translate
,
expression
:
`
${
key
}
> 0 ?
${
size
}
: (
${
key
}
<
${
-
size
}
? 0 :
${
key
}
+
${
size
}
)`
})
props
.
push
({
element
:
this
.
getEl
(
'yingbingFlipItemShadow_'
+
this
.
currentIndex
),
property
:
shadowProperty
,
expression
:
`abs(
${
key
}
)/2+0`
})
}
}
this
.
flipBinding
=
Binding
.
bind
({
anchor
:
this
.
getEl
(
'yingbingFlip'
),
eventType
:
'pan'
,
props
:
props
},
(
e
)
=>
{
if
((
e
.
state
==
'end'
||
e
.
state
==
'cancel'
)
&&
this
.
flipBinding
)
{
this
.
clearInterval
()
Binding
.
unbind
({
token
:
this
.
flipBinding
.
token
,
eventType
:
'pan'
})
this
.
flipBinding
=
null
let
value
=
this
.
direction
==
'next'
?
1
:
-
1
;
if
(
this
.
touchTime
<=
200
)
{
this
.
pageAnimation
(
-
value
*
size
,
size
);
}
else
{
let
index
=
this
.
direction
==
'next'
?
this
.
currentIndex
:
this
.
prevIndex
let
deltaX
=
Binding
.
getComputedStyle
(
this
.
getEl
(
'yingbingFlipItem_'
+
index
))[
translate
]
let
offset
=
this
.
direction
==
'next'
?
Math
.
abs
(
deltaX
)
:
size
-
Math
.
abs
(
deltaX
)
if
(
offset
>=
size
/
4
)
{
this
.
pageAnimation
(
-
value
*
size
,
size
)
}
else
{
this
.
pageAnimation
(
0
,
size
);
}
}
}
})
},
flipToNextBindingX
()
{
if
(
!
this
.
disableTouch
&&
this
.
nextIndex
<
this
.
count
&&
(
this
.
nextIndex
!=
0
||
this
.
circular
)
)
{
this
.
direction
=
'next'
this
.
flipToBindingX
()
}
},
flipToPrevBindingX
()
{
if
(
!
this
.
disableTouch
&&
this
.
prevIndex
>=
0
&&
(
this
.
prevIndex
!=
this
.
count
-
1
||
this
.
circular
)
)
{
this
.
direction
=
'prev'
this
.
flipToBindingX
()
}
},
async
flipToBindingX
()
{
this
.
disableTouch
=
true
let
value
=
this
.
direction
==
'next'
?
1
:
-
1
;
let
rect
=
await
this
.
getRect
(
this
.
$refs
.
yingbingFlip
)
let
size
=
this
.
vertical
?
rect
.
height
:
rect
.
width
this
.
pageAnimation
(
-
value
*
size
,
size
)
},
getRect
(
el
)
{
return
new
Promise
(
resolve
=>
{
dom
.
getComponentRect
(
el
,
res
=>
{
resolve
(
res
.
size
)
})
})
},
setInterval
()
{
this
.
touchTimer
=
setTimeout
(()
=>
{
this
.
touchTime
+=
10
if
(
this
.
interval
)
{
this
.
setInterval
()
}
},
10
)
},
clearInterval
()
{
this
.
interval
=
false
if
(
this
.
touchTimer
)
{
clearTimeout
(
this
.
touchTimer
)
this
.
touchTimer
=
null
}
},
pageAnimation
(
offset
,
size
)
{
let
duration
=
this
.
type
==
'none'
?
0.1
:
this
.
duration
let
late
=
offset
let
translate
=
this
.
translate
let
shadowProperty
=
this
.
vertical
?
'height'
:
'width'
let
props
=
[]
if
(
this
.
direction
==
'prev'
)
{
if
(
this
.
prevIndex
>
-
1
)
{
let
itemTrans
=
Binding
.
getComputedStyle
(
this
.
getEl
(
'yingbingFlipItem_'
+
this
.
prevIndex
))[
translate
]
props
.
push
({
element
:
this
.
getEl
(
'yingbingFlipItem_'
+
this
.
prevIndex
),
property
:
'transform.'
+
translate
,
expression
:
`linear(t,
${
itemTrans
}
,
${
late
-
size
-
itemTrans
}
,
${
duration
}
)`
})
if
(
this
.
type
==
'real'
)
{
let
contentTrans
=
Binding
.
getComputedStyle
(
this
.
getEl
(
'yingbingFlipItemContent_'
+
this
.
prevIndex
))[
translate
]
props
.
push
({
element
:
this
.
getEl
(
'yingbingFlipItemContent_'
+
this
.
prevIndex
),
property
:
'transform.'
+
translate
,
expression
:
`linear(t,
${
contentTrans
}
,
${
-
(
late
-
size
)
-
contentTrans
}
,
${
duration
}
)`
})
let
bgTrans
=
Binding
.
getComputedStyle
(
this
.
getEl
(
'yingbingFlipItemBg_'
+
this
.
prevIndex
))[
translate
]
props
.
push
({
element
:
this
.
getEl
(
'yingbingFlipItemBg_'
+
this
.
prevIndex
),
property
:
'transform.'
+
translate
,
expression
:
`linear(t,
${
bgTrans
}
,
${
late
-
bgTrans
}
,
${
duration
}
)`
})
let
shadowSize
=
Binding
.
getComputedStyle
(
this
.
getEl
(
'yingbingFlipItemShadow_'
+
this
.
prevIndex
))[
shadowProperty
]
||
size
props
.
push
({
element
:
this
.
getEl
(
'yingbingFlipItemShadow_'
+
this
.
prevIndex
),
property
:
shadowProperty
,
expression
:
`linear(t,
${
shadowSize
}
,
${
-
(
late
-
size
)
-
shadowSize
}
,
${
duration
}
)`
})
}
this
.
flipAnimationBinding
=
Binding
.
bind
({
eventType
:
'timing'
,
exitExpression
:
't>'
+
duration
,
props
:
props
},
(
e
)
=>
{
if
(
e
.
state
==
'exit'
&&
this
.
flipAnimationBinding
&&
e
.
t
>
duration
)
{
Binding
.
unbind
({
token
:
this
.
flipAnimationBinding
.
token
,
eventType
:
'timing'
})
this
.
flipAnimationBinding
=
null
if
(
Math
.
abs
(
offset
)
>
0
)
{
this
.
handleFlipChange
(
this
.
direction
==
'next'
?
1
:
-
1
)
this
.
$nextTick
(
function
()
{
this
.
resetPageBinding
()
})
}
else
{
this
.
resetPageBinding
();
}
}
})
}
}
else
{
if
(
this
.
nextIndex
<
this
.
count
)
{
animation
.
transition
(
this
.
getRef
(
'yingbingFlipItem_'
+
this
.
nextIndex
),
{
styles
:
{
transform
:
`
${
translate
}
(0)`
},
duration
:
0
,
timingFunction
:
'linear'
,
needLayout
:
true
})
}
animation
.
transition
(
this
.
getRef
(
'yingbingFlipItem_'
+
this
.
currentIndex
),
{
styles
:
{
transform
:
`
${
translate
}
(
${
late
}
px)`
},
duration
:
duration
,
timingFunction
:
'linear'
,
needLayout
:
true
},
()
=>
{
if
(
Math
.
abs
(
offset
)
>
0
)
{
this
.
handleFlipChange
(
this
.
direction
==
'next'
?
1
:
-
1
)
this
.
$nextTick
(
function
()
{
this
.
resetPageBinding
()
})
}
else
{
this
.
resetPageBinding
();
}
})
if
(
this
.
type
==
'real'
)
{
animation
.
transition
(
this
.
getRef
(
'yingbingFlipItemContent_'
+
this
.
currentIndex
),
{
styles
:
{
transform
:
`
${
translate
}
(
${
-
late
}
px)`
},
duration
:
duration
,
timingFunction
:
'linear'
,
needLayout
:
true
})
animation
.
transition
(
this
.
getRef
(
'yingbingFlipItemBg_'
+
this
.
currentIndex
),
{
styles
:
{
transform
:
`
${
translate
}
(
${
size
+
late
}
px)`
},
duration
:
duration
,
timingFunction
:
'linear'
,
needLayout
:
true
})
let
styles
=
{}
styles
[
shadowProperty
]
=
-
late
+
'px'
animation
.
transition
(
this
.
getRef
(
'yingbingFlipItemShadow_'
+
this
.
currentIndex
),
{
styles
:
styles
,
duration
:
duration
,
timingFunction
:
'linear'
,
needLayout
:
true
})
}
// if ( this.nextIndex < this.count ) {
// props.push({
// element: this.getEl('yingbingFlipItem_' + this.nextIndex),
// property: 'transform.' + translate,
// expression: '0+0'
// })
// }
// let itemTrans = Binding.getComputedStyle(this.getEl('yingbingFlipItem_' + this.currentIndex))[translate]
// props.push({
// element: this.getEl('yingbingFlipItem_' + this.currentIndex),
// property: 'transform.' + translate,
// expression: `linear(t, ${itemTrans}, ${late - itemTrans}, ${duration})`
// })
// if ( this.type == 'real' ) {
// let contentTrans = Binding.getComputedStyle(this.getEl('yingbingFlipItemContent_' + this.currentIndex))[translate]
// props.push({
// element: this.getEl('yingbingFlipItemContent_' + this.currentIndex),
// property: 'transform.' + translate,
// expression: `linear(t, ${contentTrans}, ${-late - contentTrans}, ${duration})`
// })
// let bgTrans = Binding.getComputedStyle(this.getEl('yingbingFlipItemBg_' + this.currentIndex))[translate]
// props.push({
// element: this.getEl('yingbingFlipItemBg_' + this.currentIndex),
// property: 'transform.' + translate,
// expression: `linear(t, ${bgTrans}, ${size + late - bgTrans}, ${duration})`
// })
// let shadowSize = Binding.getComputedStyle(this.getEl('yingbingFlipItemShadow_' + this.currentIndex))[shadowProperty]
// props.push({
// element: this.getEl('yingbingFlipItemShadow_' + this.currentIndex),
// property: shadowProperty,
// expression: `linear(t, ${shadowSize}, ${-late - shadowSize}, ${duration})`
// })
// }
}
},
pulling
()
{
let
loadingType
=
this
.
loadingType
let
size
=
loadingType
==
'pullup'
?
this
.
pullupHeight
:
this
.
pulldownHeight
let
key
=
this
.
vertical
?
'y'
:
'x'
let
translate
=
this
.
translate
let
props
=
[
{
element
:
this
.
getEl
(
'yingbing_flip_'
+
loadingType
),
property
:
'transform.'
+
translate
,
expression
:
loadingType
==
'pullup'
?
`abs(
${
key
}
) >
${
size
}
? 0 :
${
key
}
+
${
size
}
`
:
`abs(
${
key
}
) >
${
size
}
? 0 :
${
key
}
-
${
size
}
`
},
{
element
:
this
.
getEl
(
'yingbing_flip_'
+
loadingType
+
'_default'
),
property
:
'opacity'
,
expression
:
`abs(
${
key
}
) <
${
size
}
? 1 : 0`
},
{
element
:
this
.
getEl
(
'yingbing_flip_'
+
loadingType
+
'_ready'
),
property
:
'opacity'
,
expression
:
`abs(
${
key
}
) <
${
size
}
? 0 : 1`
},
{
element
:
this
.
getEl
(
'yingbing_flip_'
+
loadingType
+
'_loading'
),
property
:
'opacity'
,
expression
:
'0+0'
},
{
element
:
this
.
getEl
(
'yingbing_flip_'
+
loadingType
+
'_success'
),
property
:
'opacity'
,
expression
:
'0+0'
},
{
element
:
this
.
getEl
(
'yingbing_flip_'
+
loadingType
+
'_fail'
),
property
:
'opacity'
,
expression
:
'0+0'
}
]
this
.
flipBinding
=
Binding
.
bind
({
anchor
:
this
.
getEl
(
'yingbingFlip'
),
eventType
:
'pan'
,
props
:
props
},
(
e
)
=>
{
if
((
e
.
state
==
'end'
||
e
.
state
==
'cancel'
)
&&
this
.
flipBinding
)
{
Binding
.
unbind
({
token
:
this
.
flipBinding
.
token
,
eventType
:
'pan'
})
this
.
flipBinding
=
null
let
deltaX
=
Binding
.
getComputedStyle
(
this
.
getEl
(
'yingbing_flip_'
+
loadingType
))[
translate
]
if
(
deltaX
==
0
)
{
this
.
loadingState
=
'ready'
this
.
pullingRefreshBindingx
()
}
else
{
this
.
loadingState
=
'default'
this
.
resetPullingBindingx
()
}
}
})
},
resetPullingBindingx
()
{
let
loadingType
=
this
.
loadingType
let
translate
=
this
.
translate
let
size
=
loadingType
==
'pullup'
?
this
.
pullupHeight
:
this
.
pulldownHeight
let
trans
=
loadingType
==
'pullup'
?
size
:
-
size
let
deltaX
=
Binding
.
getComputedStyle
(
this
.
getEl
(
'yingbing_flip_'
+
loadingType
))[
translate
]
let
duration
=
300
let
props
=
[
{
element
:
this
.
getEl
(
'yingbing_flip_'
+
loadingType
),
property
:
'transform.'
+
translate
,
expression
:
`linear(t,
${
deltaX
}
,
${
trans
}
,
${
duration
}
)`
},
{
element
:
this
.
getEl
(
'yingbing_flip_'
+
loadingType
+
'_default'
),
property
:
'opacity'
,
expression
:
this
.
loadingState
==
'default'
?
'1+0'
:
'0+0'
},
{
element
:
this
.
getEl
(
'yingbing_flip_'
+
loadingType
+
'_ready'
),
property
:
'opacity'
,
expression
:
'0+0'
},
{
element
:
this
.
getEl
(
'yingbing_flip_'
+
loadingType
+
'_loading'
),
property
:
'opacity'
,
expression
:
'0+0'
},
{
element
:
this
.
getEl
(
'yingbing_flip_'
+
loadingType
+
'_success'
),
property
:
'opacity'
,
expression
:
this
.
loadingState
==
'success'
?
'1+0'
:
'0+0'
},
{
element
:
this
.
getEl
(
'yingbing_flip_'
+
loadingType
+
'_fail'
),
property
:
'opacity'
,
expression
:
this
.
loadingState
==
'fail'
?
'1+0'
:
'0+0'
}
]
this
.
flipAnimationBinding
=
Binding
.
bind
({
eventType
:
'timing'
,
exitExpression
:
't>'
+
duration
,
props
:
props
},
(
e
)
=>
{
if
(
e
.
state
==
'exit'
&&
this
.
flipAnimationBinding
&&
e
.
t
>
duration
)
{
this
.
resetFlipAnimationBinding
()
this
.
loadingState
=
''
this
.
resetPageBinding
()
}
})
},
pullingRefreshBindingx
()
{
let
loadingType
=
this
.
loadingType
let
duration
=
1
let
props
=
[
{
element
:
this
.
getEl
(
'yingbing_flip_'
+
loadingType
+
'_default'
),
property
:
'opacity'
,
expression
:
'0+0'
},
{
element
:
this
.
getEl
(
'yingbing_flip_'
+
loadingType
+
'_ready'
),
property
:
'opacity'
,
expression
:
'0+0'
},
{
element
:
this
.
getEl
(
'yingbing_flip_'
+
loadingType
+
'_loading'
),
property
:
'opacity'
,
expression
:
'1+0'
},
{
element
:
this
.
getEl
(
'yingbing_flip_'
+
loadingType
+
'_success'
),
property
:
'opacity'
,
expression
:
'0+0'
},
{
element
:
this
.
getEl
(
'yingbing_flip_'
+
loadingType
+
'_fail'
),
property
:
'opacity'
,
expression
:
'0+0'
}
]
this
.
flipAnimationBinding
=
Binding
.
bind
({
eventType
:
'timing'
,
exitExpression
:
't>'
+
duration
,
props
:
props
},
(
e
)
=>
{
if
(
e
.
state
==
'exit'
&&
this
.
flipAnimationBinding
&&
e
.
t
>
duration
)
{
this
.
resetFlipAnimationBinding
()
this
.
pullingRefresh
(
loadingType
)
}
})
},
resetFlipAnimationBinding
()
{
if
(
this
.
flipAnimationBinding
)
{
Binding
.
unbind
({
token
:
this
.
flipAnimationBinding
.
token
,
eventType
:
'timing'
})
this
.
flipAnimationBinding
=
null
}
},
getEl
(
selector
)
{
return
this
.
$refs
[
selector
]
?
Util
.
getEl
(
this
.
$refs
[
selector
].
length
>
0
?
this
.
$refs
[
selector
][
0
]
:
this
.
$refs
[
selector
])
:
null
},
getRef
(
selector
)
{
return
this
.
$refs
[
selector
]
?
this
.
$refs
[
selector
].
length
>
0
?
this
.
$refs
[
selector
][
0
]
:
this
.
$refs
[
selector
]
:
null
},
resetPageBinding
()
{
this
.
direction
=
''
this
.
touchTime
=
0
this
.
startX
=
0
this
.
startY
=
0
this
.
$nextTick
(
function
()
{
this
.
isTouch
=
false
this
.
disableTouch
=
false
})
}
}
}
\ No newline at end of file
vedio/uni_modules/yingbing-flip/components/yingbing-flip/yingbing-flip.vue
deleted
100644 → 0
View file @
afe8cef8
<
template
>
<!-- #ifndef APP-NVUE -->
<view
class=
"yingbing-flip"
:prop=
"flipProp"
:change:prop=
"flip.propWatcher"
@
touchstart=
"flip.touchstart"
@
touchmove=
"flip.touchmove"
@
touchend=
"flip.touchend"
@
touchcancel=
"flip.touchcancel"
:style=
"
{
background: bgColor
}">
<!-- #endif -->
<!-- #ifdef APP-NVUE -->
<view
class=
"yingbing-flip"
ref=
"yingbingFlip"
@
touchstart=
"fliptouchstart"
@
touchmove=
"fliptouchmove"
@
touchend=
"fliptouchend"
:style=
"
{
background: bgColor
}">
<!-- #endif -->
<view
class=
"yingbing-flip-item"
:class=
"'yingbing-flip-item_' + item"
v-for=
"(item, index) in dataSync"
:ref=
"'yingbingFlipItem_' + item"
:style=
"
{
'background': bgColor,
'transform': item > currentIndex ? translate + '(' + fullSize + ')' : item
<
currentIndex
?
translate
+
'(
-
'
+
fullSize
+
')'
:
'',
'
box-shadow
'
:
vertical
?
'
0
0
15rpx
rgba
(
0
,
0
,
0
,.
2
)'
:
''
}"
:key=
"item"
>
<view
class=
"yingbing-flip-item-content"
:ref=
"'yingbingFlipItemContent_' + item"
:class=
"'yingbing-flip-item-content_' + item"
:style=
"
{
'background': bgColor,
'transform': item
<
currentIndex
?
type =
=
'
real
'
?
translate
+
'('
+
fullSize
+
')'
:
translate
+
'(
0
)'
:
translate
+
'(
0
)'
}"
>
<!-- #ifdef MP -->
<slot
v-if=
"item > -1 && item
<
count
"
:name=
"item"
></slot>
<!-- #endif -->
<!-- #ifndef MP -->
<slot
v-if=
"item > -1 && item
<
count
"
:item=
"data[item]"
:index=
"item"
></slot>
<!-- #endif -->
</view>
<view
class=
"yingbing-flip-item-bg"
:ref=
"'yingbingFlipItemBg_' + item"
:class=
"'yingbing-flip-item-bg_' + item"
:style=
"
{
background: bgColor,
transform: item
<
currentIndex
&&
type =
=
'
real
'
?
translate
+
'(
0
)'
:
translate
+
'('
+
fullSize
+
')',
}"
></view>
<view
class=
"yingbing-flip-item-shadow"
:ref=
"'yingbingFlipItemShadow_' + item"
:class=
"'yingbing-flip-item-shadow_' + item"
:style=
"[shadowStyle]"
></view>
</view>
<view
class=
"yingbing-flip-pulldown"
:style=
"[pulldownStyle]"
v-if=
"pulldownable"
ref=
"yingbing_flip_pulldown"
>
<view
class=
"yingbing-flip-pulldown-item yingbing-flip-pulldown-default"
ref=
"yingbing_flip_pulldown_default"
>
<slot
name=
"pulldownDefault"
></slot>
</view>
<view
class=
"yingbing-flip-pulldown-item yingbing-flip-pulldown-ready"
ref=
"yingbing_flip_pulldown_ready"
>
<slot
name=
"pulldownReady"
></slot>
</view>
<view
class=
"yingbing-flip-pulldown-item yingbing-flip-pulldown-loading"
ref=
"yingbing_flip_pulldown_loading"
>
<slot
name=
"pulldownLoading"
></slot>
</view>
<view
class=
"yingbing-flip-pulldown-item yingbing-flip-pulldown-success"
ref=
"yingbing_flip_pulldown_success"
>
<slot
name=
"pulldownSuccess"
></slot>
</view>
<view
class=
"yingbing-flip-pulldown-item yingbing-flip-pulldown-fail"
ref=
"yingbing_flip_pulldown_fail"
>
<slot
name=
"pulldownFail"
></slot>
</view>
</view>
<view
class=
"yingbing-flip-pullup"
:style=
"[pullupStyle]"
v-if=
"pullupable"
ref=
"yingbing_flip_pullup"
>
<view
class=
"yingbing-flip-pullup-item yingbing-flip-pullup-default"
ref=
"yingbing_flip_pullup_default"
>
<slot
name=
"pullupDefault"
></slot>
</view>
<view
class=
"yingbing-flip-pullup-item yingbing-flip-pullup-ready"
ref=
"yingbing_flip_pullup_ready"
>
<slot
name=
"pullupReady"
></slot>
</view>
<view
class=
"yingbing-flip-pullup-item yingbing-flip-pullup-loading"
ref=
"yingbing_flip_pullup_loading"
>
<slot
name=
"pullupLoading"
></slot>
</view>
<view
class=
"yingbing-flip-pullup-item yingbing-flip-pullup-success"
ref=
"yingbing_flip_pullup_success"
>
<slot
name=
"pullupSuccess"
></slot>
</view>
<view
class=
"yingbing-flip-pullup-item yingbing-flip-pullup-fail"
ref=
"yingbing_flip_pullup_fail"
>
<slot
name=
"pullupFail"
></slot>
</view>
</view>
</view>
</
template
>
<
script
>
// #ifdef APP-NVUE
import
flipBindingx
from
'../modules/flip_bindingx.js'
// #endif
export
default
{
// #ifdef APP-NVUE
mixins
:
[
flipBindingx
],
// #endif
props
:
{
data
:
{
type
:
Array
,
default
()
{
return
new
Array
}
},
vertical
:
{
type
:
Boolean
,
default
:
false
},
current
:
{
type
:
Number
,
default
:
0
},
//翻页方式
type
:
{
type
:
String
,
default
:
'real'
},
//滑动周期
duration
:
{
type
:
Number
,
default
:
100
},
//容错距离
sliderFault
:
{
type
:
Number
,
default
:
20
},
//背景颜色
bgColor
:
{
type
:
String
,
default
:
'#fcd281'
},
//是否关闭点击左右2侧位置翻页
unableClickPage
:
{
type
:
Boolean
,
default
:
false
},
//开启下拉刷新
pulldownable
:
{
type
:
Boolean
,
default
:
false
},
//下拉刷新高度
pulldownHeight
:
{
type
:
Number
,
default
:
80
},
//开启上拉加载
pullupable
:
{
type
:
Boolean
,
default
:
false
},
//上拉加载高度
pullupHeight
:
{
type
:
Number
,
default
:
80
}
},
computed
:
{
dataSync
()
{
let
arr
=
[]
if
(
this
.
prevIndex
>=
0
)
{
arr
.
push
(
this
.
prevIndex
)
}
arr
.
push
(
this
.
currentIndex
)
if
(
this
.
nextIndex
<
this
.
count
)
{
arr
.
push
(
this
.
nextIndex
)
}
return
this
.
refreshing
?
[]
:
arr
.
sort
((
a
,
b
)
=>
b
-
a
)
},
nextIndex
()
{
return
this
.
currentIndex
+
1
>
this
.
count
-
1
&&
this
.
count
>
2
?
0
:
this
.
currentIndex
+
1
},
prevIndex
()
{
return
this
.
currentIndex
-
1
<
0
&&
this
.
count
>
2
?
this
.
count
-
1
:
this
.
currentIndex
-
1
},
count
()
{
return
this
.
data
.
length
},
flipProp
()
{
return
{
vertical
:
this
.
vertical
,
pulldownable
:
this
.
pulldownable
,
pullupable
:
this
.
pullupable
,
pulldownHeight
:
this
.
pulldownHeight
,
pullupHeight
:
this
.
pullupHeight
,
loadingState
:
this
.
loadingState
,
duration
:
this
.
duration
,
unableClickPage
:
this
.
unableClickPage
,
nextIndex
:
this
.
nextIndex
,
prevIndex
:
this
.
prevIndex
,
currentIndex
:
this
.
currentIndex
,
type
:
this
.
type
,
count
:
this
.
count
,
flipTo
:
this
.
flipTo
,
sliderFault
:
this
.
sliderFault
,
translate
:
this
.
translate
}
},
pulldownStyle
()
{
return
this
.
vertical
?
{
left
:
0
,
right
:
0
,
top
:
0
,
height
:
this
.
pulldownHeight
+
'px'
,
transform
:
this
.
translate
+
'(-'
+
this
.
pulldownHeight
+
'px)'
}
:
{
left
:
0
,
top
:
0
,
bottom
:
0
,
width
:
this
.
pulldownHeight
+
'px'
,
transform
:
this
.
translate
+
'(-'
+
this
.
pulldownHeight
+
'px)'
}
},
pullupStyle
()
{
return
this
.
vertical
?
{
left
:
0
,
right
:
0
,
bottom
:
0
,
height
:
this
.
pullupHeight
+
'px'
,
transform
:
this
.
translate
+
'('
+
this
.
pullupHeight
+
'px)'
}
:
{
right
:
0
,
top
:
0
,
bottom
:
0
,
width
:
this
.
pullupHeight
+
'px'
,
transform
:
this
.
translate
+
'('
+
this
.
pullupHeight
+
'px)'
}
},
shadowStyle
()
{
return
this
.
vertical
?
{
bottom
:
0
,
right
:
0
,
left
:
0
,
height
:
0
,
// #ifdef APP-NVUE
'background-image'
:
'linear-gradient(to bottom, rgba(255,255,255, 0), rgba(0,0,0,.5))'
// #endif
}
:
{
top
:
0
,
bottom
:
0
,
right
:
0
,
width
:
0
,
// #ifdef APP-NVUE
'background-image'
:
'linear-gradient(to right, rgba(255,255,255, 0), rgba(0,0,0,.5))'
// #endif
}
},
translate
()
{
return
this
.
vertical
?
'translateY'
:
'translateX'
},
fullSize
()
{
return
this
.
vertical
?
'3050rpx'
:
'750rpx'
}
},
data
()
{
return
{
refreshing
:
false
,
currentIndex
:
0
,
flipTo
:
0
,
loadingState
:
''
,
}
},
created
()
{
this
.
currentIndex
=
this
.
current
},
methods
:
{
handleFlipChange
(
value
)
{
if
(
value
>
0
)
{
this
.
currentIndex
=
this
.
currentIndex
+
value
>
this
.
count
-
1
?
0
:
this
.
currentIndex
+
value
}
else
{
this
.
currentIndex
=
this
.
currentIndex
+
value
<
0
?
this
.
count
-
1
:
this
.
currentIndex
+
value
}
this
.
$emit
(
'change'
,
{
current
:
this
.
currentIndex
,
detail
:
this
.
data
[
this
.
currentIndex
]
})
this
.
$emit
(
'update:current'
,
this
.
currentIndex
)
},
pullingRefresh
(
type
)
{
this
.
$emit
(
type
,
(
state
)
=>
{
this
.
loadingState
=
state
// #ifdef APP-NVUE
this
.
resetPullingBindingx
()
// #endif
})
},
flipToNext
()
{
// #ifdef APP-NVUE
this
.
flipToNextBindingX
()
// #endif
// #ifndef APP-NVUE
this
.
flipTo
=
0
this
.
$nextTick
(
function
()
{
this
.
flipTo
=
1
})
// #endif
},
flipToPrev
()
{
// #ifdef APP-NVUE
this
.
flipToPrevBindingX
()
// #endif
// #ifndef APP-NVUE
this
.
flipTo
=
0
this
.
$nextTick
(
function
()
{
this
.
flipTo
=
-
1
})
// #endif
},
refresh
()
{
this
.
refreshing
=
true
this
.
$nextTick
(
function
()
{
this
.
currentIndex
=
this
.
current
this
.
refreshing
=
false
})
},
resetLoading
()
{
this
.
loadingState
=
''
// #ifdef APP-NVUE
this
.
resetPullingBindingx
()
// #endif
}
},
watch
:
{
current
(
newVal
)
{
this
.
currentIndex
=
newVal
}
}
}
</
script
>
<!-- #ifdef APP-VUE || H5 || MP-QQ || MP-WEIXIN -->
<
script
lang=
"wxs"
module=
"flip"
src=
"../modules/flip.wxs"
></
script
>
<!-- #endif -->
<
style
>
.yingbing-flip
{
/* #ifdef APP-NVUE */
flex
:
1
;
/* #endif */
/* #ifndef APP-NVUE */
height
:
100%
;
/* #endif */
overflow
:
hidden
;
position
:
relative
;
}
.yingbing-flip-item
{
position
:
absolute
;
top
:
0
;
left
:
0
;
right
:
0
;
bottom
:
0
;
/* #ifndef APP-NVUE */
overflow
:
hidden
;
/* #endif */
}
.yingbing-flip-item-content
{
position
:
absolute
;
top
:
0
;
left
:
0
;
right
:
0
;
bottom
:
0
;
}
.yingbing-flip-item-bg
{
position
:
absolute
;
top
:
0
;
left
:
0
;
right
:
0
;
bottom
:
0
;
/* #ifdef APP-NVUE */
box-shadow
:
0
0
20
rpx
rgba
(
0
,
0
,
0
,
0.2
);
/* #endif */
}
.yingbing-flip-item-shadow
{
position
:
absolute
;
/* #ifdef APP-NVUE */
opacity
:
0.5
;
/* #endif */
}
.yingbing-flip-pulldown
,
.yingbing-flip-pullup
{
position
:
absolute
;
}
.yingbing-flip-pulldown-item
,
.yingbing-flip-pullup-item
{
/* #ifndef APP-NVUE */
visibility
:
hidden
;
/* #endif */
/* #ifdef APP-NVUE */
opacity
:
0
;
/* #endif */
position
:
absolute
;
top
:
0
;
left
:
0
;
right
:
0
;
bottom
:
0
;
}
/* #ifdef MP */
/
deep
/
.scoped-ref
{
position
:
absolute
;
top
:
0
;
left
:
0
;
right
:
0
;
bottom
:
0
;
}
yingbing-flip
{
display
:
block
;
}
/* #endif */
</
style
>
vedio/uni_modules/yingbing-flip/js_sdk/util.js
deleted
100644 → 0
View file @
afe8cef8
export
default
{
/**
* 补零
* @param {Number} val 数字
**/
zeroize
(
val
)
{
return
zeroize
(
val
);
},
/**
* 时间格式化
* @param {String} time 时间戳or时间
**/
dateFormat
(
time
,
formats
=
'yyyy-mm-dd hh:mm:ss'
)
{
let
arr
=
formats
.
split
(
' '
)
let
dateFormats
=
''
let
timeFormats
=
''
arr
.
forEach
(
item
=>
{
if
(
item
.
indexOf
(
'yy'
)
>
-
1
)
{
dateFormats
=
item
}
else
{
timeFormats
=
item
}
})
const
d
=
new
Date
(
time
);
let
result
=
''
if
(
dateFormats
.
indexOf
(
'yyyy'
)
>
-
1
)
{
result
+=
d
.
getFullYear
()
+
'-'
}
if
(
dateFormats
.
indexOf
(
'mm'
)
>
-
1
)
{
result
+=
zeroize
(
d
.
getMonth
()
+
1
)
+
'-'
}
if
(
dateFormats
.
indexOf
(
'dd'
)
>
-
1
)
{
result
+=
zeroize
(
d
.
getDate
())
+
' '
}
if
(
timeFormats
.
indexOf
(
'hh'
)
>
-
1
)
{
result
+=
zeroize
(
d
.
getHours
())
+
':'
}
if
(
timeFormats
.
indexOf
(
'mm'
)
>
-
1
)
{
result
+=
zeroize
(
d
.
getMinutes
())
+
':'
}
if
(
timeFormats
.
indexOf
(
'ss'
)
>
-
1
)
{
result
+=
zeroize
(
d
.
getSeconds
())
+
':'
}
return
result
.
substring
(
0
,
result
.
length
-
1
)
},
/**
* 秒数转化为分秒
* @param {String} value 秒数
**/
minutesFormat
(
value
)
{
let
minutes
=
Math
.
floor
(
value
/
60
%
60
)
>=
10
?
Math
.
floor
(
value
/
60
%
60
)
:
'0'
+
Math
.
floor
(
value
/
60
%
60
);
let
seconds
=
Math
.
floor
(
value
%
60
)
>=
10
?
Math
.
floor
(
value
%
60
)
:
'0'
+
Math
.
floor
(
value
%
60
);
return
minutes
+
':'
+
seconds
;
},
/**
* 时间转化为秒数
* @param {String} time 时间(HH:mm:ss)
**/
time2seconds
(
time
){
const
seconds
=
parseInt
(
time
.
split
(
':'
)[
0
])
*
60
+
parseInt
(
time
.
split
(
':'
)[
1
].
split
(
'.'
)[
0
])
+
parseInt
(
time
.
split
(
':'
)[
1
].
split
(
'.'
)[
1
])
/
1000
;
return
seconds
;
},
/**
* 移除url地址域名
* @param {String} str http地址
**/
removeUrl
(
url
)
{
let
str
=
url
.
replace
(
/^http:
\/\/[^/]
+/
,
''
);
return
str
.
substr
(
1
);
},
/**
* 获取文件后缀
* @param {String} name 带后缀的文件名称
**/
suffix
(
name
)
{
//获取图片后缀
let
fileName
=
name
.
lastIndexOf
(
"."
);
let
fileNameLength
=
name
.
length
;
let
fileFormat
=
name
.
substring
(
fileName
+
1
,
fileNameLength
);
return
fileFormat
;
},
/**
* 清除文件后缀
* @param {String} name 带后缀的文件名称
*/
removeSuffix
(
name
)
{
//获取图片后缀
let
fileName
=
name
.
lastIndexOf
(
"."
);
if
(
fileName
>
-
1
)
{
let
fileNameFormat
=
name
.
substring
(
0
,
fileName
);
return
fileNameFormat
;
}
else
{
return
name
}
},
/**
* 数组查找符合条件元素并返回下标
* @param {Array} arr 传入数组
* @param {String} value 条件元素
* @param {String} query 对比key值
*/
indexOf
(
arr
,
query
,
value
)
{
let
len
=
arr
.
length
;
for
(
let
i
=
0
;
i
<
len
;
i
++
)
{
if
(
arr
[
i
][
query
]
==
value
)
{
return
parseInt
(
i
);
}
}
return
-
1
;
},
/**
* 正则匹配
* @param {String} type 匹配类型
* @param {String} value 匹配值
*/
reg
(
type
,
value
)
{
const
regs
=
{
//身份证证则
idcard
:
new
RegExp
(
/^
[
1-9
]\d{7}((
0
\d)
|
(
1
[
0-2
]))(([
0|1|2
]\d)
|3
[
0-1
])\d{3}
$|^
[
1-9
]\d{5}[
1-9
]\d{3}((
0
\d)
|
(
1
[
0-2
]))(([
0|1|2
]\d)
|3
[
0-1
])\d{3}([
0-9
]
|X
)
$/
),
//手机正则
mobile
:
new
RegExp
(
/^1
[
3456789
]\d{9}
$/
),
//固定电话正则
phone
:
new
RegExp
(
/^
(\(\d{3,4}\)
|
\d{3,4}
-|
\s)?\d{7,14}
$/
),
//金额验证
price
:
new
RegExp
(
/^
[
1-9
]\d
*
(
,
\d{3})
*
(\.\d{1,2})?
$|^0.
\d{1,2}
$/
),
//邮箱验证
email
:
new
RegExp
(
/^
\w
+
((
-
\w
+
)
|
(\.\w
+
))
*
\@[
A-Za-z0-9
]
+
((\.
|-
)[
A-Za-z0-9
]
+
)
*
\.[
A-Za-z0-9
]
+$/
),
//银行卡
bankcard
:
new
RegExp
(
/^
([
1-9
]{1})(\d{15}
|
\d{18})
$/
)
}
return
regs
[
type
].
test
(
value
);
},
/**
* 计算2个时间差的分钟数或者秒钟数或时钟数
* @param {datetime} time1 开始时间
* @param {datetime} time2 结束时间
*/
timeMinuse
(
time1
,
time2
,
type
=
'minutes'
)
{
//判断开始时间是否大于结束日期
let
date1
=
new
Date
(
time1
);
let
date2
=
new
Date
(
time2
);
if
(
date1
>
date2
)
{
console
.
log
(
"开始时间不能大于结束时间!"
);
return
false
;
}
let
seconds
=
date2
.
getTime
()
/
1000
-
date1
.
getTime
()
/
1000
;
return
type
==
'minutes'
?
(
seconds
/
60
)
:
type
==
'hours'
?
(
seconds
/
60
/
60
)
:
seconds
;
},
/**
* 判断值类型返回字符
* @param {datetime} value 需要判断类型的值
*/
typeof
(
value
)
{
let
type
=
Object
.
prototype
.
toString
.
call
(
value
);
return
type
.
slice
(
8
,
type
.
length
-
1
)
},
/**
* 生成随机字符串
* @param {Number} len 长度
*/
randomString
(
len
)
{
len
=
len
||
32
;
var
$chars
=
'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678'
;
/****默认去掉了容易混淆的字符oOLl,9gq,Vv,Uu,I1****/
var
maxPos
=
$chars
.
length
;
var
pwd
=
''
;
for
(
let
i
=
0
;
i
<
len
;
i
++
)
{
pwd
+=
$chars
.
charAt
(
Math
.
floor
(
Math
.
random
()
*
maxPos
));
}
return
pwd
;
},
/**
* 生成随机ID
*/
randomID
()
{
let
mydate
=
new
Date
();
return
mydate
.
getMinutes
()
+
mydate
.
getSeconds
()
+
mydate
.
getMilliseconds
()
+
Math
.
round
(
Math
.
random
()
*
10000
);
},
/**
* 生成随机不重复整数
* @param {Number} len 长度
*/
randomSoleNumber
(
len
)
{
let
min
=
0
;
let
max
=
len
-
1
;
let
arr
=
[];
while
(
arr
.
length
<
len
)
{
let
value
=
Math
.
floor
(
Math
.
random
()
*
(
max
-
min
+
1
))
+
min
;
if
(
arr
.
indexOf
(
value
)
==
-
1
)
{
arr
.
push
(
value
)
}
}
return
arr
;
},
/**
* 16进制颜色转化为rgb
* @param {String} hex 16进制颜色
*/
hex2rgb
(
hex
)
{
hex
=
hex
.
length
==
7
?
hex
:
'#'
+
hex
.
slice
(
1
,
4
)
+
hex
.
slice
(
1
,
4
)
let
str
=
"rgb("
const
r
=
parseInt
(
hex
.
slice
(
1
,
3
),
16
).
toString
();
//ff slice不包括end
const
g
=
parseInt
(
hex
.
slice
(
3
,
5
),
16
).
toString
();
//00
const
b
=
parseInt
(
hex
.
slice
(
5
,
7
),
16
).
toString
();
//ff
str
+=
r
+
","
+
g
+
","
+
b
+
")"
;
return
str
},
/**
* 16进制颜色转化为rgba
* @param {String} hex 16进制颜色
*/
hex2rgba
(
hex
,
opacity
)
{
hex
=
hex
.
length
==
7
?
hex
:
'#'
+
hex
.
slice
(
1
,
4
)
+
hex
.
slice
(
1
,
4
)
let
str
=
"rgba("
const
r
=
parseInt
(
hex
.
slice
(
1
,
3
),
16
).
toString
();
//ff slice不包括end
const
g
=
parseInt
(
hex
.
slice
(
3
,
5
),
16
).
toString
();
//00
const
b
=
parseInt
(
hex
.
slice
(
5
,
7
),
16
).
toString
();
//ff
str
+=
r
+
","
+
g
+
","
+
b
+
","
+
opacity
+
")"
;
return
str
},
/**
* byte转化为文件大小
* @param {Number} byte 位
*/
byte2Size
(
byte
)
{
let
sizeString
=
''
if
(
byte
==
0
){
sizeString
=
"0B"
;
}
else
if
(
byte
<
1024
){
sizeString
=
byte
+
"B"
;
}
else
if
(
byte
<
1048576
){
sizeString
=
(
byte
/
1024
).
toFixed
(
2
)
+
"KB"
;
}
else
if
(
byte
<
1073741824
){
sizeString
=
(
byte
/
1048576
).
toFixed
(
2
)
+
"MB"
;
}
else
{
sizeString
=
(
byte
/
1073741824
).
toFixed
(
2
)
+
"GB"
;
}
return
sizeString
;
},
// 深度克隆
deepClone
(
obj
)
{
if
(
typeof
obj
!==
"object"
&&
typeof
obj
!==
'function'
)
{
//原始类型直接返回
return
obj
;
}
var
o
=
isArray
(
obj
)
?
[]
:
{};
for
(
let
i
in
obj
)
{
if
(
obj
.
hasOwnProperty
(
i
)){
o
[
i
]
=
typeof
obj
[
i
]
===
"object"
?
this
.
deepClone
(
obj
[
i
])
:
obj
[
i
];
}
}
return
o
;
},
/**
* 将数字转为带中文单位的字符串
* @param {Number} num 数字
*/
numtounit
(
num
)
{
let
units
=
[{
label
:
'万'
,
value
:
10000
,
min
:
1000
},{
label
:
'亿'
,
value
:
100000000
,
min
:
100000000
},{
label
:
'兆'
,
value
:
10000000000000000
,
min
:
100000000000000000
}]
let
value
=
num
units
.
forEach
(
unit
=>
{
if
(
num
>=
unit
.
min
)
{
value
=
(
num
/
unit
.
value
).
toFixed
(
2
)
+
unit
.
label
}
})
return
value
},
/**
* 判断像素单位,没有则加上rpx
* @param {String} value 像素
*/
pixelunit
(
value
)
{
if
(
value
.
toString
().
indexOf
(
'px'
)
>
-
1
||
value
.
toString
().
indexOf
(
'em'
)
>
-
1
||
value
.
toString
().
indexOf
(
'auto'
)
>
-
1
||
value
.
toString
().
indexOf
(
'%'
)
>
-
1
)
{
return
value
}
else
{
return
value
+
'rpx'
}
},
/**
* 判断像素单位,全部转为px
* @param {String} value 像素
*/
unitpixel
(
value
)
{
if
(
value
.
toString
().
indexOf
(
'rpx'
)
>
-
1
)
{
return
uni
.
upx2px
(
value
.
replace
(
'rpx'
,
''
))
}
else
if
(
value
.
toString
().
indexOf
(
'px'
)
>
-
1
)
{
return
parseFloat
(
value
.
replace
(
'px'
,
''
))
}
else
if
(
value
.
toString
().
indexOf
(
'em'
)
>
-
1
||
value
.
toString
().
indexOf
(
'auto'
)
>
-
1
||
value
.
toString
().
indexOf
(
'%'
)
>
-
1
)
{
return
value
}
else
{
return
parseFloat
(
uni
.
upx2px
(
value
))
}
},
/**
* 判断像素单位,转化为rpx
* @param {String} value 值
* @param {String} unit 返回结果是否带上单位
*/
anytorpx
(
value
,
unit
=
true
)
{
if
(
value
.
toString
().
indexOf
(
'rpx'
)
>
-
1
)
{
return
unit
?
value
:
parseFloat
(
value
.
replace
(
'rpx'
,
''
))
}
else
if
(
value
.
toString
().
indexOf
(
'px'
)
>
-
1
)
{
return
parseFloat
(
value
.
replace
(
'px'
,
''
)
*
(
750
/
uni
.
getSystemInfoSync
().
windowWidth
))
+
(
unit
?
'rpx'
:
0
)
}
else
if
(
value
.
toString
().
indexOf
(
'auto'
)
>
-
1
)
{
return
'auto'
}
else
if
(
value
.
toString
().
indexOf
(
'%'
)
>
-
1
)
{
return
parseFloat
((
value
.
replace
(
'%'
,
''
)
/
100
)
*
750
)
+
(
unit
?
'rpx'
:
0
)
}
else
if
(
value
.
toString
().
indexOf
(
'em'
)
>
-
1
||
value
.
toString
().
indexOf
(
'rem'
)
>
-
1
)
{
return
parseFloat
(
value
.
replace
(
'em'
,
''
).
replace
(
'rem'
,
''
)
*
32
)
+
(
unit
?
'rpx'
:
0
)
}
else
if
(
/^
\d
+$/
.
test
(
value
)
)
{
return
parseFloat
(
value
)
+
(
unit
?
'rpx'
:
0
)
}
},
/**
* 判断像素单位,转化为px
* @param {String} value 值
* @param {String} unit 返回结果是否带上单位
*/
anytopx
(
value
,
unit
=
false
)
{
if
(
value
.
toString
().
indexOf
(
'rpx'
)
>
-
1
)
{
return
uni
.
upx2px
(
value
.
replace
(
'rpx'
,
''
))
+
(
unit
?
'px'
:
0
)
}
else
if
(
value
.
toString
().
indexOf
(
'px'
)
>
-
1
)
{
return
parseFloat
(
value
.
replace
(
'px'
,
''
))
+
(
unit
?
'px'
:
0
)
}
else
if
(
value
.
toString
().
indexOf
(
'auto'
)
>
-
1
)
{
return
'auto'
}
else
if
(
value
.
toString
().
indexOf
(
'%'
)
>
-
1
)
{
return
parseFloat
((
value
.
replace
(
'%'
,
''
)
/
100
)
*
uni
.
getSystemInfoSync
().
windowWidth
)
+
(
unit
?
'px'
:
0
)
}
else
if
(
value
.
toString
().
indexOf
(
'em'
)
>
-
1
||
value
.
toString
().
indexOf
(
'rem'
)
>
-
1
)
{
return
parseFloat
(
value
.
replace
(
'em'
,
''
).
replace
(
'rem'
,
''
)
*
uni
.
getSystemInfoSync
().
windowWidth
)
+
(
unit
?
'px'
:
0
)
}
else
if
(
/^
\d
+$/
.
test
(
value
)
)
{
return
parseFloat
(
value
)
+
(
unit
?
'px'
:
0
)
}
},
getRefs
(
components
,
name
,
current
)
{
// #ifndef MP
return
current
>=
0
?
components
.
$refs
[
name
][
current
]
:
components
.
$refs
[
name
]
// #endif
// #ifdef MP
return
{}
// #endif
},
//获取节点
getEl
(
el
)
{
if
(
typeof
el
===
'string'
||
typeof
el
===
'number'
)
return
el
;
if
(
WXEnvironment
)
{
return
el
.
ref
;
}
else
{
return
el
instanceof
HTMLElement
?
el
:
el
.
$el
;
}
},
/**
* 获取指定父节点
* @param {String} components 当前实例
* @param {String} name 父节点名称
*/
getParent
(
name
,
components
)
{
let
parent
=
components
.
$parent
if
(
parent
)
{
let
parentName
=
parent
.
$options
.
name
while
(
parentName
!==
name
)
{
parent
=
parent
.
$parent
if
(
parent
)
{
parentName
=
parent
.
$options
.
name
}
else
{
return
null
}
}
return
parent
}
return
null
},
/**
* 获取指定子节点
* @param {String} components 当前实例
* @param {String} name 父节点名称
*/
getChildrens
(
names
,
components
)
{
let
arr
=
[]
let
childs
=
names
.
split
(
','
)
const
dowhile
=
(
children
)
=>
{
if
(
this
.
typeof
(
children
)
==
'Array'
)
{
children
.
forEach
(
child
=>
{
if
(
childs
.
indexOf
(
child
.
$options
.
name
)
>
-
1
)
{
arr
.
push
(
child
)
}
if
(
child
.
$children
&&
child
.
$children
.
length
>
0
)
{
dowhile
(
child
.
$children
)
}
})
}
}
dowhile
(
components
.
$children
)
return
arr
;
},
/**
* 获取指定子节点
* @param {String} selector 节点class或者id
* @param {String} el 节点
* @param {String} components 当前实例
*/
getRect
(
selector
,
el
,
components
)
{
return
new
Promise
(
resolve
=>
{
// #ifdef APP-NVUE
uni
.
requireNativePlugin
(
'dom'
).
getComponentRect
(
el
,
res
=>
{
resolve
(
res
.
size
)
})
// #endif
// #ifndef APP-NVUE
uni
.
createSelectorQuery
().
in
(
components
).
select
(
selector
).
boundingClientRect
(
data
=>
{
resolve
(
data
)
}).
exec
();
// #endif
})
}
}
// 判断arr是否为一个数组,返回一个bool值
function
isArray
(
arr
)
{
return
Object
.
prototype
.
toString
.
call
(
arr
)
===
'[object Array]'
;
}
function
zeroize
(
val
)
{
return
val
>=
10
?
val
:
'0'
+
val
;
}
vedio/utils/utils.js
View file @
64d49eb9
export
const
PAKEAGE_NAME
=
'com.duben.dybookhm'
export
function
trim
(
str
)
{
return
str
?
str
.
replace
(
/
(
^
\s
*
)
|
(\s
*$
)
/g
,
""
)
:
''
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment