Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
H
hls-webapp-cli
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
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
heasy
hls-webapp-cli
Commits
bbc0de27
Commit
bbc0de27
authored
Apr 22, 2021
by
nature
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
vw替换rem
parent
13ea2bd3
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
9 additions
and
544 deletions
+9
-544
dev.env.js
template/config/dev.env.js
+0
-4
prod.env.js
template/config/prod.env.js
+0
-4
uat.env.js
template/config/uat.env.js
+0
-4
package.json
template/package.json
+1
-0
hlsHttp.js
template/src/scripts/hlsHttp.js
+6
-3
hlsUtil.js
template/src/scripts/hlsUtil.js
+2
-529
No files found.
template/config/dev.env.js
View file @
bbc0de27
...
...
@@ -7,11 +7,7 @@ module.exports = merge(prodEnv, {
CONFIG_ENV
:
JSON
.
stringify
(
process
.
env
.
CONFIG_ENV
),
debug
:
true
,
isMobilePlatform
:
false
,
hmapUrl
:
'"http://hippius.hand-china.com/hmap220"'
,
loginPath
:
'"http://hlsapp.hand-china.com/core/oauth/token?client_id=hQGCtxTItRa34PUOgxaD0r7oSPeuEaIB&client_secret=7ee8338c-4a06-44a1-87cc-afa63f8e1bc3&grant_type=password&username=app&password=" '
,
basePath
:
'"http://hlsapp.hand-china.com/core/r/api?sysName=HLS_APP&apiName="'
,
rootPath
:
'"http://hlsapp.hand-china.com/core/r/api"'
,
file_url
:
'"http://hlsapp.hand-china.com/file/"'
,
appId
:
'"com.hls.easy.car"'
,
currentVersion
:
'"1.0.0"'
});
template/config/prod.env.js
View file @
bbc0de27
...
...
@@ -4,11 +4,7 @@ module.exports = {
CONFIG_ENV
:
JSON
.
stringify
(
process
.
env
.
CONFIG_ENV
),
debug
:
false
,
isMobilePlatform
:
true
,
hmapUrl
:
'"http://hippius.hand-china.com/hmap220"'
,
loginPath
:
'"http://hlsapp.hand-china.com/core/oauth/token?client_id=hQGCtxTItRa34PUOgxaD0r7oSPeuEaIB&client_secret=7ee8338c-4a06-44a1-87cc-afa63f8e1bc3&grant_type=password&username=app&password=" '
,
basePath
:
'"http://hlsapp.hand-china.com/core/r/api?sysName=HLS_APP&apiName="'
,
rootPath
:
'"http://hlsapp.hand-china.com/core/r/api"'
,
file_url
:
'"http://hlsapp.hand-china.com/file/"'
,
appId
:
'"com.hls.easy.car"'
,
currentVersion
:
'"1.0.0"'
}
template/config/uat.env.js
View file @
bbc0de27
...
...
@@ -4,11 +4,7 @@ module.exports = {
CONFIG_ENV
:
JSON
.
stringify
(
process
.
env
.
CONFIG_ENV
),
debug
:
true
,
isMobilePlatform
:
true
,
hmapUrl
:
'"http://hippius.hand-china.com/hmap220"'
,
loginPath
:
'"http://hlsapp.hand-china.com/core/oauth/token?client_id=hQGCtxTItRa34PUOgxaD0r7oSPeuEaIB&client_secret=7ee8338c-4a06-44a1-87cc-afa63f8e1bc3&grant_type=password&username=app&password=" '
,
basePath
:
'"http://hlsapp.hand-china.com/core/r/api?sysName=HLS_APP&apiName="'
,
rootPath
:
'"http://hlsapp.hand-china.com/core/r/api"'
,
file_url
:
'"http://hlsapp.hand-china.com/file/"'
,
appId
:
'"com.hls.easy.car"'
,
currentVersion
:
'"1.0.0"'
}
template/package.json
View file @
bbc0de27
...
...
@@ -17,6 +17,7 @@
"vue"
:
"^2.5.2"
,
"vue-router"
:
"^3.0.1"
,
"vux"
:
"^2.9.2"
,
"axios"
:
"^0.21.1"
,
"hls-easy-ui"
:
"https://hel.hand-china.com/easyUI/hls-easy-ui.git"
},
"devDependencies"
:
{
...
...
template/src/scripts/hlsHttp.js
View file @
bbc0de27
// 引入axios
import
axios
from
'axios'
import
{
hlsPopup
}
from
'hls-easy-ui'
import
{
hlsPopup
}
from
'hls-easy-ui'
import
qs
from
'qs'
import
router
from
'../router/index'
let
promiseArr
=
{}
let
cancel
=
{}
...
...
@@ -99,9 +100,11 @@ axios.interceptors.response.use(response => {
})
axios
.
defaults
.
baseURL
=
''
axios
.
defaults
.
timeout
=
100000
axios
.
defaults
.
paramsSerializer
=
(
params
)
=>
{
return
qs
.
stringify
(
params
,
{
arrayFormat
:
'repeat'
})
}
// get请求
export
function
get
(
url
)
{
let
param
=
{}
export
function
get
(
url
,
param
=
{})
{
let
headers
=
{}
if
(
window
.
localStorage
.
access_token
)
{
headers
=
{
...
...
template/src/scripts/hlsUtil.js
View file @
bbc0de27
import
axios
from
'axios'
export
default
{
city
:
{
11
:
'北京'
,
12
:
'天津'
,
13
:
'河北'
,
14
:
'山西'
,
15
:
'内蒙古'
,
21
:
'辽宁'
,
22
:
'吉林'
,
23
:
'黑龙江'
,
31
:
'上海'
,
32
:
'江苏'
,
33
:
'浙江'
,
34
:
'安徽'
,
35
:
'福建'
,
36
:
'江西'
,
37
:
'山东'
,
41
:
'河南'
,
42
:
'湖北'
,
43
:
'湖南'
,
44
:
'广东'
,
45
:
'广西'
,
46
:
'海南'
,
50
:
'重庆'
,
51
:
'四川'
,
52
:
'贵州'
,
53
:
'云南'
,
54
:
'西藏'
,
61
:
'陕西'
,
62
:
'甘肃'
,
63
:
'青海'
,
64
:
'宁夏'
,
65
:
'新疆'
,
71
:
'台湾'
,
81
:
'香港'
,
82
:
'澳门'
,
91
:
'国外'
,
},
// 检查号码是否符合规范,包括长度,类型
isCardNo
(
card
)
{
// 身份证号码为15位或者18位,15位时全为数字,18位前17位为数字,最后一位是校验位,可能为数字或字符X
card
=
card
.
toUpperCase
()
let
reg
=
/
(
^
\d{15}
$
)
|
(
^
\d{18}
$
)
|
(
^
\d{17}(\d
|X|x
)
$
)
/
return
reg
.
test
(
card
)
},
// 取身份证前两位,校验省份
checkProvince
:
function
(
card
)
{
card
=
card
.
toUpperCase
()
let
province
=
card
.
substr
(
0
,
2
)
if
(
this
.
city
[
province
]
===
undefined
)
{
return
false
}
return
true
},
// 检查生日是否正确
checkBirthday
:
function
(
card
)
{
card
=
card
.
toUpperCase
()
let
len
=
card
.
length
let
arrData
let
year
let
month
let
day
let
birthday
// 身份证15位时,次序为省(3位)市(3位)年(2位)月(2位)日(2位)校验位(3位),皆为数字
if
(
len
===
15
)
{
let
reFifteen
=
/^
(\d{6})(\d{2})(\d{2})(\d{2})(\d{3})
$/
arrData
=
card
.
match
(
reFifteen
)
year
=
arrData
[
2
]
month
=
arrData
[
3
]
day
=
arrData
[
4
]
birthday
=
new
Date
(
'19'
+
year
+
'/'
+
month
+
'/'
+
day
)
return
this
.
verifyBirthday
(
'19'
+
year
,
month
,
day
,
birthday
)
}
// 身份证18位时,次序为省(3位)市(3位)年(4位)月(2位)日(2位)校验位(4位),校验位末尾可能为X
if
(
len
===
18
)
{
let
reEighteen
=
/^
(\d{6})(\d{4})(\d{2})(\d{2})(\d{3})([
0-9
]
|X
)
$/
arrData
=
card
.
match
(
reEighteen
)
year
=
arrData
[
2
]
month
=
arrData
[
3
]
day
=
arrData
[
4
]
birthday
=
new
Date
(
year
+
'/'
+
month
+
'/'
+
day
)
return
this
.
verifyBirthday
(
year
,
month
,
day
,
birthday
)
}
return
false
},
// 校验日期
verifyBirthday
:
function
(
year
,
month
,
day
,
birthday
)
{
// 年月日是否合理
return
(
birthday
.
getFullYear
().
toString
()
===
year
&&
((
birthday
.
getMonth
()
+
1
)
<
10
?
'0'
+
(
birthday
.
getMonth
()
+
1
)
:
(
birthday
.
getMonth
()
+
1
).
toString
())
===
month
&&
((
birthday
.
getDate
())
<
10
?
'0'
+
(
birthday
.
getDate
()).
toString
()
:
birthday
.
getDate
().
toString
())
===
day
)
},
// 校验位的检测
checkParity
(
card
)
{
// 15位转18位
card
=
this
.
changeFivteenToEighteen
(
card
)
var
len
=
card
.
length
if
(
len
===
18
)
{
let
arrInt
=
new
Array
(
7
,
9
,
10
,
5
,
8
,
4
,
2
,
1
,
6
,
3
,
7
,
9
,
10
,
5
,
8
,
4
,
2
)
let
arrCh
=
new
Array
(
'1'
,
'0'
,
'X'
,
'9'
,
'8'
,
'7'
,
'6'
,
'5'
,
'4'
,
'3'
,
'2'
)
let
cardTemp
=
0
for
(
let
i
=
0
;
i
<
17
;
i
++
)
{
cardTemp
+=
card
.
substr
(
i
,
1
)
*
arrInt
[
i
]
}
let
valnum
=
arrCh
[
cardTemp
%
11
]
if
(
valnum
===
card
.
substr
(
17
,
1
))
{
return
true
}
return
false
}
return
false
},
// 15位转18位身份证号
changeFivteenToEighteen
(
card
)
{
if
(
card
.
length
===
15
)
{
let
arrInt
=
new
Array
(
7
,
9
,
10
,
5
,
8
,
4
,
2
,
1
,
6
,
3
,
7
,
9
,
10
,
5
,
8
,
4
,
2
)
let
arrCh
=
new
Array
(
'1'
,
'0'
,
'X'
,
'9'
,
'8'
,
'7'
,
'6'
,
'5'
,
'4'
,
'3'
,
'2'
)
let
cardTemp
=
0
card
=
card
.
substr
(
0
,
6
)
+
'19'
+
card
.
substr
(
6
,
card
.
length
-
6
)
for
(
let
i
=
0
;
i
<
17
;
i
++
)
{
cardTemp
+=
card
.
substr
(
i
,
1
)
*
arrInt
[
i
]
}
card
+=
arrCh
[
cardTemp
%
11
]
return
card
}
return
card
},
/**
* 检验身份证号码
*/
isCardID
(
card
)
{
card
=
card
.
toUpperCase
()
if
(
this
.
isCardNo
(
card
)
===
false
)
{
return
'你输入的身份证长度或格式错误'
}
// 检查省份
if
(
this
.
checkProvince
(
card
)
===
false
)
{
return
'你的身份证地区非法'
}
// 校验生日
if
(
this
.
checkBirthday
(
card
)
===
false
)
{
return
'身份证上的出生日期非法'
}
// 检验位的检测
if
(
this
.
checkParity
(
card
)
===
false
)
{
return
'你输入的身份证号非法'
}
return
''
},
// 银行卡号校验
isBankAccount
:
function
(
bankno
)
{
if
(
bankno
.
length
<
16
||
bankno
.
length
>
19
)
{
/* 银行卡号长度必须在16到19之间 */
return
'银行卡号长度必须在16到19之间'
}
let
num
=
/^
\d
*$/
// 全数字
if
(
!
num
.
exec
(
bankno
))
{
/* 银行卡号必须全为数字 */
return
'银行卡号必须全为数字'
}
var
strBin
=
'10,18,30,35,37,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,58,60,62,65,68,69,84,87,88,94,95,98,99'
if
(
strBin
.
indexOf
(
bankno
.
substring
(
0
,
2
))
===
-
1
)
{
/* 银行卡号开头6位不符合规范 */
return
'银行卡号开头6位不符合规范'
}
// Luhn校验
if
(
!
this
.
luhnCheck
(
bankno
))
{
return
'银行卡号有误,请从新输入'
}
// return true;
},
luhnCheck
:
function
(
bankno
)
{
let
lastNum
=
Number
(
bankno
.
substr
(
bankno
.
length
-
1
,
1
))
// 取出最后一位(与luhn进行比较)
let
first15Num
=
bankno
.
substr
(
0
,
bankno
.
length
-
1
)
// 前15或18位
let
newArr
=
[]
for
(
let
i
=
first15Num
.
length
-
1
;
i
>
-
1
;
i
--
)
{
// 前15或18位倒序存进数组
newArr
.
push
(
first15Num
.
substr
(
i
,
1
))
}
let
arrJiShu
=
[]
// 奇数位*2的积 <9
let
arrJiShu2
=
[]
// 奇数位*2的积 >9
let
arrOuShu
=
[]
// 偶数位数组
for
(
let
j
=
0
;
j
<
newArr
.
length
;
j
++
)
{
if
((
j
+
1
)
%
2
===
1
)
{
// 奇数位
if
(
parseInt
(
newArr
[
j
])
*
2
<
9
)
{
arrJiShu
.
push
(
parseInt
(
newArr
[
j
])
*
2
)
}
else
{
arrJiShu2
.
push
(
parseInt
(
newArr
[
j
])
*
2
)
}
}
else
{
arrOuShu
.
push
(
newArr
[
j
])
}
}
let
jishuChild1
=
[]
// 奇数位*2 >9 的分割之后的数组个位数
let
jishuChild2
=
[]
// 奇数位*2 >9 的分割之后的数组十位数
for
(
let
h
=
0
;
h
<
arrJiShu2
.
length
;
h
++
)
{
jishuChild1
.
push
(
parseInt
(
arrJiShu2
[
h
])
%
10
)
jishuChild2
.
push
(
parseInt
(
arrJiShu2
[
h
])
/
10
)
}
let
sumJiShu
=
0
// 奇数位*2 < 9 的数组之和
let
sumOuShu
=
0
// 偶数位数组之和
let
sumJiShuChild1
=
0
// 奇数位*2 >9 的分割之后的数组个位数之和
let
sumJiShuChild2
=
0
// 奇数位*2 >9 的分割之后的数组十位数之和
for
(
let
m
=
0
;
m
<
arrJiShu
.
length
;
m
++
)
{
sumJiShu
=
sumJiShu
+
parseInt
(
arrJiShu
[
m
])
}
for
(
let
n
=
0
;
n
<
arrOuShu
.
length
;
n
++
)
{
sumOuShu
=
sumOuShu
+
parseInt
(
arrOuShu
[
n
])
}
for
(
let
p
=
0
;
p
<
jishuChild1
.
length
;
p
++
)
{
sumJiShuChild1
=
sumJiShuChild1
+
parseInt
(
jishuChild1
[
p
])
sumJiShuChild2
=
sumJiShuChild2
+
parseInt
(
jishuChild2
[
p
])
}
// 计算总和
let
sumTotal
=
parseInt
(
sumJiShu
)
+
parseInt
(
sumOuShu
)
+
parseInt
(
sumJiShuChild1
)
+
parseInt
(
sumJiShuChild2
)
// 计算luhn值
let
k
=
parseInt
(
sumTotal
)
%
10
===
0
?
10
:
parseInt
(
sumTotal
)
%
10
let
luhn
=
10
-
k
if
(
lastNum
===
luhn
)
{
return
true
}
else
{
/* 银行卡号必须符合luhn校验 */
return
false
}
},
/**
* 判断输入是否为十一位电话号码
* @param str 字符串
...
...
@@ -237,7 +7,7 @@ export default {
phoneNumber
:
function
(
str
)
{
// ^((13[0-9])|(14[5,7])|(15[0-3,5-9])|(17[0,3,5-8])|(18[0-9])|166|198|199|(147))\\d{8}$
let
reg
=
/^
(
(
13
[
0-9
]{1})
|
(
14
[
0-9
]{1})
|
(
15
[
0-9
]{1})
|
(
17
[
0-9
]{1})
|
(
18
[
0-9
]{1})
|166|198|199|
(
147
))
+
\d{8
}
$/
let
reg
=
/^
(
1
)
+
\d{10
}
$/
return
reg
.
test
(
str
)
},
/**
...
...
@@ -246,7 +16,7 @@ export default {
* @returns {boolean}
*/
phoneNumber86
:
function
(
str
)
{
let
reg
=
/^
(\+
86|
\+
86+
\s)
+
(
((
13
[
0-9
]{1})
|
(
14
[
0-9
]{1})
|
(
15
[
0-9
]{1})
|
(
17
[
0-9
]{1})
|
(
18
[
0-9
]{1})
|166|198|199|
(
147
))
+
\d{8})
$/
let
reg
=
/^
(\+
86|
\+
86+
\s)
+
(
1
)
+
\d{10}
$/
return
reg
.
test
(
str
)
},
/**
...
...
@@ -273,30 +43,6 @@ export default {
callEmail
:
function
(
email
)
{
window
.
open
(
'mailto:'
+
email
)
},
/**
* formData的文件上传
* @param file File对象
* @param params 请求额外参数
* @param url 请求url地址
*/
fileUpload
:
function
(
file
,
params
,
url
)
{
url
=
encodeURI
(
url
)
let
param
=
new
FormData
()
for
(
let
key
in
params
)
{
param
.
append
(
key
,
params
[
key
])
}
param
.
append
(
'fileName'
,
file
.
name
)
param
.
append
(
'file'
,
file
)
return
axios
.
post
(
url
,
param
,
{
headers
:
{
'Content-Type'
:
'application/x-www-form-urlencoded'
,
'Authorization'
:
'Bearer '
+
window
.
localStorage
.
access_token
,
},
}).
then
(
function
(
result
)
{
})
},
/**
*
* @param x 输入的数字
...
...
@@ -317,279 +63,6 @@ export default {
return
parseInt
(
f
*
m
,
100000
)
/
m
},
/**
*
* @param ir interest rate per month
* @param np number of periods (months)
* @param pv present value
* @param fv future value (residual value)
* @returns {number} 计算结果;
* @constructor
*/
PMT
:
function
(
ir
,
np
,
pv
,
fv
,
type
)
{
/*
ir - interest rate per month
np - number of periods (months)
pv - present value
fv - future value (residual value)
type - 0 or 1 need to implement that
*/
if
(
!
type
)
{
type
=
0
}
if
(
ir
===
0
)
{
return
-
pv
/
np
}
let
r1
=
1
+
ir
// let pmt = -( ir * ( pv * Math.pow((ir + 1), np) + fv ) ) / ( ( ir + 1 ) * ( Math.pow((ir + 1), np) - 1 ) );
let
pmt
=
-
(
pv
*
Math
.
pow
(
r1
,
np
)
+
fv
)
*
ir
/
((
1
+
ir
*
type
)
*
(
Math
.
pow
(
r1
,
np
)
-
1
))
return
this
.
toDecimal
(
pmt
)
},
/**
*
* @param rate
* @param per
* @param nper
* @param pv
* @param fv
* @param type
* @returns {*}
* @constructor
*/
IPMT
:
function
(
rate
,
per
,
nper
,
pv
,
fv
,
type
)
{
let
ipmt
=
0
let
r
=
rate
let
R1
=
1
+
r
let
t
=
per
let
n
=
nper
let
ct
if
(
rate
===
0
)
{
return
0
}
if
(
fv
)
{
fv
=
-
fv
}
else
{
fv
=
0
}
if
(
type
)
{
ct
=
type
}
else
{
ct
=
0
}
if
(
type
===
1
&&
per
===
1
)
{
return
ipmt
}
else
{
ipmt
=
-
(
pv
*
Math
.
pow
(
R1
,
n
)
+
fv
)
*
r
/
((
1
+
r
*
ct
)
*
(
Math
.
pow
(
R1
,
n
)
-
1
))
-
(
pv
/
(
1
+
r
*
ct
)
-
(
pv
*
Math
.
pow
(
R1
,
n
)
+
fv
)
/
((
1
+
r
*
ct
)
*
(
Math
.
pow
(
R1
,
n
)
-
1
)))
*
(
Math
.
pow
(
R1
,
t
)
-
Math
.
pow
(
R1
,
(
t
-
1
)))
return
this
.
toDecimal
(
ipmt
)
}
},
/**
*
* @param p_rate
* @param p_nper
* @param p_pmt
* @param p_fv
* @param p_type
* @returns {number|*}
* @constructor
*/
PV
:
function
(
pRate
,
pNper
,
pPmt
,
pFv
,
pType
)
{
let
pv
let
r
let
R1
let
n
let
pmt
let
fv
let
ct
r
=
pRate
R1
=
1
+
r
n
=
pNper
if
(
pPmt
)
{
pmt
=
pPmt
}
else
{
pmt
=
0
}
if
(
pFv
)
{
fv
=
pFv
}
else
{
fv
=
0
}
if
(
pType
)
{
ct
=
pType
}
else
{
ct
=
0
}
pv
=
-
(
fv
+
pmt
*
(
1
+
r
*
ct
)
*
(
Math
.
pow
(
R1
,
n
)
-
1
)
/
r
)
/
Math
.
pow
(
R1
,
n
)
return
this
.
toDecimal
(
pv
)
},
/**
*
* @param p_rate
* @param p_nper
* @param p_pmt
* @param p_pv
* @param p_type
* @returns {number|*}
* @constructor
*/
FV
:
function
(
pRate
,
pNper
,
pPmt
,
pPv
,
pType
)
{
let
fv
let
r
let
R1
let
n
let
pmt
let
pv
let
ct
r
=
pRate
R1
=
1
+
r
n
=
pNper
if
(
pPmt
)
{
pmt
=
pPmt
}
else
{
pmt
=
0
}
if
(
pPv
)
{
pv
=
pPv
}
else
{
pv
=
0
}
if
(
pType
)
{
ct
=
pType
}
else
{
ct
=
0
}
fv
=
-
pv
*
Math
.
pow
(
R1
,
n
)
-
pmt
*
(
1
+
r
*
ct
)
*
(
Math
.
pow
(
R1
,
n
)
-
1
)
/
r
return
this
.
toDecimal
(
fv
)
},
/**
*
* @param args
* @param rate
* @returns {*}
* @constructor
*/
NPV
:
function
(
args
,
rate
)
{
let
rrate
=
(
1
+
rate
/
100
)
let
npv
=
args
[
0
]
for
(
let
i
=
1
;
i
<
args
.
length
;
i
++
)
{
npv
+=
(
args
[
i
]
/
Math
.
pow
(
rrate
,
i
))
}
return
npv
},
/**
*
* @param fn
* @returns {number}
*/
seekZero
:
function
(
fn
)
{
let
x
=
1
while
(
fn
(
x
)
>
0
)
{
x
+=
1
}
while
(
fn
(
x
)
<
0
)
{
x
-=
0.01
}
return
x
+
0.01
},
/**
*
* @param array
* @returns {number}
* @constructor
*/
IRR
:
function
(
array
)
{
let
args
=
array
let
numberOfTries
=
1
// Cash flow values must contain at least one positive value and one negative value
let
positive
,
negative
Array
.
prototype
.
slice
.
call
(
args
).
forEach
(
function
(
value
)
{
if
(
value
>
0
)
positive
=
true
if
(
value
<
0
)
negative
=
true
})
if
(
!
positive
||
!
negative
)
throw
new
Error
(
'IRR requires at least one positive value and one negative value'
)
function
npv
(
rate
)
{
numberOfTries
++
if
(
numberOfTries
>
1000
)
{
throw
new
Error
(
'IRR can
\'
t find a result'
)
}
let
rrate
=
(
1
+
rate
/
100
)
let
npv
=
args
[
0
]
for
(
let
i
=
1
;
i
<
args
.
length
;
i
++
)
{
npv
+=
(
args
[
i
]
/
Math
.
pow
(
rrate
,
i
))
}
return
npv
}
return
this
.
seekZero
(
npv
)
},
// Returns Sum of f(x)/f'(x)
sumEq
:
function
(
cfs
,
durs
,
guess
)
{
let
sumFx
=
0
let
sumFdx
=
0
for
(
let
i
=
0
;
i
<
cfs
.
length
;
i
++
)
{
sumFx
=
sumFx
+
(
cfs
[
i
]
/
Math
.
pow
(
1
+
guess
,
durs
[
i
]))
}
for
(
let
i
=
0
;
i
<
cfs
.
length
;
i
++
)
{
sumFdx
=
sumFdx
+
(
-
cfs
[
i
]
*
durs
[
i
]
*
Math
.
pow
(
1
+
guess
,
-
1
-
durs
[
i
]))
}
return
sumFx
/
sumFdx
},
durYear
:
function
(
first
,
last
)
{
return
(
Math
.
abs
(
last
.
getTime
()
-
first
.
getTime
())
/
(
1000
*
3600
*
24
*
365
))
},
/**
*
* @param cfs
* @param dts
* @param guess
* @returns {number}
* @constructor
*/
XIRR
:
function
(
cfs
,
dts
,
guess
)
{
if
(
cfs
.
length
!==
dts
.
length
)
throw
new
Error
(
'Number of cash flows and dates should match'
)
let
positive
,
negative
Array
.
prototype
.
slice
.
call
(
cfs
).
forEach
(
function
(
value
)
{
if
(
value
>
0
)
positive
=
true
if
(
value
<
0
)
negative
=
true
})
if
(
!
positive
||
!
negative
)
throw
new
Error
(
'XIRR requires at least one positive value and one negative value'
)
guess
=
guess
||
0
let
limit
=
100
// loop limit
let
guessLast
let
durs
=
[]
durs
.
push
(
0
)
// Create Array of durations from First date
for
(
let
i
=
1
;
i
<
dts
.
length
;
i
++
)
{
durs
.
push
(
this
.
durYear
(
dts
[
0
],
dts
[
i
]))
}
do
{
guessLast
=
guess
guess
=
guessLast
-
this
.
sumEq
(
cfs
,
durs
,
guessLast
)
limit
--
}
while
(
guessLast
.
toFixed
(
5
)
!==
guess
.
toFixed
(
5
)
&&
limit
>
0
)
let
xirr
=
guessLast
.
toFixed
(
5
)
!==
guess
.
toFixed
(
5
)
?
null
:
guess
*
100
return
Math
.
round
(
xirr
*
100
)
/
100
},
/**
* 判断平台
* @return {String} 平台
...
...
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