Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
B
bill-manager-ui
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
赵啸非
bill-manager-ui
Commits
6f2cf656
Commit
6f2cf656
authored
Dec 09, 2024
by
“yiyousong”
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
perf: 优化新增菜单
parent
3918c5c4
Changes
24
Hide whitespace changes
Inline
Side-by-side
Showing
24 changed files
with
5456 additions
and
19 deletions
+5456
-19
admin_2/src/components/IconSelect/IconSelect.vue
admin_2/src/components/IconSelect/IconSelect.vue
+1
-1
admin_2/src/components/IconSelect/icon.json
admin_2/src/components/IconSelect/icon.json
+0
-0
admin_2/src/components/YDatePickerTab/YDatePickerTab.vue
admin_2/src/components/YDatePickerTab/YDatePickerTab.vue
+205
-0
admin_2/src/components/YDatePickerTab/date-picker/index.js
admin_2/src/components/YDatePickerTab/date-picker/index.js
+8
-0
admin_2/src/components/YDatePickerTab/date-picker/src/basic/date-table.vue
...nents/YDatePickerTab/date-picker/src/basic/date-table.vue
+518
-0
admin_2/src/components/YDatePickerTab/date-picker/src/basic/month-table.vue
...ents/YDatePickerTab/date-picker/src/basic/month-table.vue
+339
-0
admin_2/src/components/YDatePickerTab/date-picker/src/basic/time-spinner.vue
...nts/YDatePickerTab/date-picker/src/basic/time-spinner.vue
+377
-0
admin_2/src/components/YDatePickerTab/date-picker/src/basic/year-table.vue
...nents/YDatePickerTab/date-picker/src/basic/year-table.vue
+130
-0
admin_2/src/components/YDatePickerTab/date-picker/src/panel/date-range.vue
...nents/YDatePickerTab/date-picker/src/panel/date-range.vue
+815
-0
admin_2/src/components/YDatePickerTab/date-picker/src/panel/date.vue
.../components/YDatePickerTab/date-picker/src/panel/date.vue
+742
-0
admin_2/src/components/YDatePickerTab/date-picker/src/panel/month-range.vue
...ents/YDatePickerTab/date-picker/src/panel/month-range.vue
+325
-0
admin_2/src/components/YDatePickerTab/date-picker/src/panel/time-range.vue
...nents/YDatePickerTab/date-picker/src/panel/time-range.vue
+295
-0
admin_2/src/components/YDatePickerTab/date-picker/src/panel/time-select.vue
...ents/YDatePickerTab/date-picker/src/panel/time-select.vue
+207
-0
admin_2/src/components/YDatePickerTab/date-picker/src/panel/time.vue
.../components/YDatePickerTab/date-picker/src/panel/time.vue
+203
-0
admin_2/src/components/YDatePickerTab/date-picker/src/picker.vue
.../src/components/YDatePickerTab/date-picker/src/picker.vue
+961
-0
admin_2/src/components/YDatePickerTab/date-picker/src/picker/date-picker.js
...ents/YDatePickerTab/date-picker/src/picker/date-picker.js
+43
-0
admin_2/src/components/YDatePickerTab/date-picker/src/picker/time-picker.js
...ents/YDatePickerTab/date-picker/src/picker/time-picker.js
+39
-0
admin_2/src/components/YDatePickerTab/date-picker/src/picker/time-select.js
...ents/YDatePickerTab/date-picker/src/picker/time-select.js
+21
-0
admin_2/src/main.js
admin_2/src/main.js
+2
-2
admin_2/src/pages/engineSearch/components/Search.vue
admin_2/src/pages/engineSearch/components/Search.vue
+4
-1
admin_2/src/pages/system/menu/components/AddMenu.vue
admin_2/src/pages/system/menu/components/AddMenu.vue
+127
-14
admin_2/src/pages/system/menu/components/SelectRes.vue
admin_2/src/pages/system/menu/components/SelectRes.vue
+92
-0
admin_2/src/pages/system/resourceManage/components/AddResource.vue
...rc/pages/system/resourceManage/components/AddResource.vue
+1
-0
admin_2/src/utils/request.js
admin_2/src/utils/request.js
+1
-1
No files found.
admin_2/src/
pages/system/menu/components
/IconSelect.vue
→
admin_2/src/
components/IconSelect
/IconSelect.vue
View file @
6f2cf656
...
@@ -26,7 +26,7 @@
...
@@ -26,7 +26,7 @@
</
template
>
</
template
>
<
script
>
<
script
>
import
iconJson
from
'
@/assets
/icon.json
'
;
import
iconJson
from
'
.
/icon.json
'
;
export
default
{
export
default
{
model
:
{
model
:
{
prop
:
'
value
'
,
prop
:
'
value
'
,
...
...
admin_2/src/
assets
/icon.json
→
admin_2/src/
components/IconSelect
/icon.json
View file @
6f2cf656
File moved
admin_2/src/components/YDatePickerTab/YDatePickerTab.vue
0 → 100644
View file @
6f2cf656
<
template
>
<el-popover
ref=
"popover"
trigger=
"click"
:placement=
"placement"
popper-class=
"y-date-popover"
>
<div
class=
"flex flex-col items-center"
>
<div
class=
"tab-box"
>
<div
:class=
"['tab-item',
{ active: type == 'year' }]" @click="changeTab('year')">按年
</div>
<div
:class=
"['tab-item',
{ active: type == 'month' }]" @click="changeTab('month')">
按月
</div>
<div
:class=
"['tab-item',
{ active: type == 'date' }]" @click="changeTab('date')">按日
</div>
</div>
<div
class=
"tab-content w-ull"
>
<date-picker
v-if=
"type == 'year'"
:value=
"value"
type=
"year"
:format=
"Format.year"
:value-format=
"ValueFormat.year"
@
input=
"handleChange"
>
</date-picker>
<date-picker
v-if=
"type == 'month'"
:value=
"value"
type=
"month"
:format=
"Format.month"
:value-format=
"ValueFormat.month"
@
input=
"handleChange"
>
</date-picker>
<date-picker
v-if=
"type == 'date'"
:value=
"value"
type=
"date"
:format=
"Format.date"
:value-format=
"ValueFormat.date"
@
input=
"handleChange"
>
</date-picker>
</div>
</div>
<el-input
:size=
"size"
:placeholder=
"placeholder"
:value=
"dateInputVal"
slot=
"reference"
:clearable=
"clearable"
@
clear=
"handleClearDate"
></el-input>
</el-popover>
</
template
>
<
script
>
import
DatePicker
from
'
./date-picker/src/picker/date-picker
'
;
export
default
{
model
:
{
value
:
'
value
'
,
event
:
'
change
'
},
components
:
{
DatePicker
},
props
:
{
value
:
{
type
:
String
,
default
:
''
},
size
:
{
type
:
String
,
default
:
''
},
placement
:
{
type
:
String
,
default
:
'
bottom-start
'
},
placeholder
:
{
type
:
String
,
default
:
'
请选择
'
},
clearable
:
{
type
:
Boolean
,
default
:
true
},
format
:
{
type
:
Object
,
default
:
()
=>
{}
},
valueFormat
:
{
type
:
Object
,
default
:
()
=>
{}
}
},
data
()
{
return
{
type
:
'
year
'
};
},
computed
:
{
dateInputVal
()
{
return
this
.
value
;
},
Format
()
{
return
{
year
:
'
yyyy
'
,
month
:
'
MM
'
,
date
:
'
yyyy-MM-dd
'
,
...
this
.
format
};
},
ValueFormat
()
{
return
{
year
:
'
yyyy
'
,
month
:
'
yyyy-MM
'
,
date
:
'
yyyy-MM-dd
'
,
...
this
.
valueFormat
};
}
},
watch
:
{
value
:
{
handler
(
val
)
{
let
format
=
this
.
getDateType
(
val
);
if
(
format
===
'
YYYY-MM-DD
'
)
{
this
.
type
=
'
date
'
;
}
else
if
(
format
===
'
YYYY-MM
'
)
{
this
.
type
=
'
month
'
;
}
else
if
(
format
===
'
YYYY
'
)
{
this
.
type
=
'
year
'
;
}
},
immediate
:
true
}
},
methods
:
{
changeTab
(
key
)
{
this
.
$emit
(
'
change
'
,
''
);
this
.
type
=
key
;
// 更新popover定位
this
.
$nextTick
(()
=>
{
if
(
this
.
$refs
.
popover
)
{
this
.
$refs
.
popover
.
updatePopper
();
}
});
},
handleClearDate
()
{
this
.
$emit
(
'
change
'
,
''
);
},
handleChange
(
val
)
{
this
.
$emit
(
'
change
'
,
val
);
},
getDateType
(
dateStr
)
{
if
(
dateStr
)
{
// 替换中文的年、月、日为标准分隔符
const
cleanedDateStr
=
dateStr
.
replace
(
'
年
'
,
'
-
'
).
replace
(
'
月
'
,
'
-
'
).
replace
(
'
日
'
,
''
);
const
formats
=
[
'
YYYY-MM-DD
'
,
'
YYYY-MM
'
,
'
YYYY
'
];
// 尝试用不同的格式解析
for
(
const
format
of
formats
)
{
const
date
=
this
.
$moment
(
cleanedDateStr
,
format
,
true
);
// 严格模式解析
if
(
date
.
isValid
())
{
return
format
;
}
}
return
'
Invalid Date
'
;
// 如果都无法解析,则认为是无效日期
}
}
}
};
</
script
>
<
style
lang=
"less"
scoped
>
.tab-box {
width: 300px;
height: 40px;
background-color: #ebebeb;
border-radius: 20px;
display: flex;
position: relative;
.tab-item {
width: 100px;
height: 100%;
border-radius: 20px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
}
.active {
background-color: #fff;
border: 2px solid var(--primary);
}
}
:deep(.el-picker-panel) {
border: none;
box-shadow: none;
border-radius: 0px;
}
:global(.y-date-popover) {
width: 348px;
min-height: 330px;
display: flex;
}
</
style
>
admin_2/src/components/YDatePickerTab/date-picker/index.js
0 → 100644
View file @
6f2cf656
import
DatePicker
from
'
./src/picker/date-picker
'
;
/* istanbul ignore next */
DatePicker
.
install
=
function
install
(
Vue
)
{
Vue
.
component
(
DatePicker
.
name
,
DatePicker
);
};
export
default
DatePicker
;
admin_2/src/components/YDatePickerTab/date-picker/src/basic/date-table.vue
0 → 100644
View file @
6f2cf656
<
template
>
<table
cellspacing=
"0"
cellpadding=
"0"
class=
"el-date-table"
@
click=
"handleClick"
@
mousemove=
"handleMouseMove"
:class=
"
{ 'is-week-mode': selectionMode === 'week' }"
>
<tbody>
<tr>
<th
v-if=
"showWeekNumber"
>
{{
t
(
"
el.datepicker.week
"
)
}}
</th>
<th
v-for=
"(week, key) in WEEKS"
:key=
"key"
>
{{
t
(
"
el.datepicker.weeks.
"
+
week
)
}}
</th>
</tr>
<tr
class=
"el-date-table__row"
v-for=
"(row, key) in rows"
:class=
"
{ current: isWeekActive(row[1]) }"
:key="key"
>
<td
v-for=
"(cell, key) in row"
:class=
"getCellClasses(cell)"
:key=
"key"
>
<div>
<span>
{{
cell
.
text
}}
</span>
</div>
</td>
</tr>
</tbody>
</table>
</
template
>
<
script
>
/* eslint-disable */
import
{
getFirstDayOfMonth
,
getDayCountOfMonth
,
getWeekNumber
,
getStartDateOfMonth
,
prevDate
,
nextDate
,
isDate
,
clearTime
as
_clearTime
,
}
from
"
element-ui/src/utils/date-util
"
;
import
Locale
from
"
element-ui/src/mixins/locale
"
;
import
{
arrayFindIndex
,
arrayFind
,
coerceTruthyValueToArray
,
}
from
"
element-ui/src/utils/util
"
;
const
WEEKS
=
[
"
sun
"
,
"
mon
"
,
"
tue
"
,
"
wed
"
,
"
thu
"
,
"
fri
"
,
"
sat
"
];
const
getDateTimestamp
=
function
(
time
)
{
if
(
typeof
time
===
"
number
"
||
typeof
time
===
"
string
"
)
{
return
_clearTime
(
new
Date
(
time
)).
getTime
();
}
else
if
(
time
instanceof
Date
)
{
return
_clearTime
(
time
).
getTime
();
}
else
{
return
NaN
;
}
};
// remove the first element that satisfies `pred` from arr
// return a new array if modification occurs
// return the original array otherwise
const
removeFromArray
=
function
(
arr
,
pred
)
{
const
idx
=
typeof
pred
===
"
function
"
?
arrayFindIndex
(
arr
,
pred
)
:
arr
.
indexOf
(
pred
);
return
idx
>=
0
?
[...
arr
.
slice
(
0
,
idx
),
...
arr
.
slice
(
idx
+
1
)]
:
arr
;
};
export
default
{
mixins
:
[
Locale
],
props
:
{
firstDayOfWeek
:
{
default
:
7
,
type
:
Number
,
validator
:
(
val
)
=>
val
>=
1
&&
val
<=
7
,
},
value
:
{},
defaultValue
:
{
validator
(
val
)
{
// either: null, valid Date object, Array of valid Date objects
return
(
val
===
null
||
isDate
(
val
)
||
(
Array
.
isArray
(
val
)
&&
val
.
every
(
isDate
))
);
},
},
date
:
{},
selectionMode
:
{
default
:
"
day
"
,
},
showWeekNumber
:
{
type
:
Boolean
,
default
:
false
,
},
disabledDate
:
{},
cellClassName
:
{},
minDate
:
{},
maxDate
:
{},
rangeState
:
{
default
()
{
return
{
endDate
:
null
,
selecting
:
false
,
};
},
},
},
computed
:
{
offsetDay
()
{
const
week
=
this
.
firstDayOfWeek
;
// 周日为界限,左右偏移的天数,3217654 例如周一就是 -1,目的是调整前两行日期的位置
return
week
>
3
?
7
-
week
:
-
week
;
},
WEEKS
()
{
const
week
=
this
.
firstDayOfWeek
;
return
WEEKS
.
concat
(
WEEKS
).
slice
(
week
,
week
+
7
);
},
year
()
{
return
this
.
date
.
getFullYear
();
},
month
()
{
return
this
.
date
.
getMonth
();
},
startDate
()
{
return
getStartDateOfMonth
(
this
.
year
,
this
.
month
);
},
rows
()
{
// TODO: refactory rows / getCellClasses
const
date
=
new
Date
(
this
.
year
,
this
.
month
,
1
);
let
day
=
getFirstDayOfMonth
(
date
);
// day of first day
const
dateCountOfMonth
=
getDayCountOfMonth
(
date
.
getFullYear
(),
date
.
getMonth
()
);
const
dateCountOfLastMonth
=
getDayCountOfMonth
(
date
.
getFullYear
(),
date
.
getMonth
()
===
0
?
11
:
date
.
getMonth
()
-
1
);
day
=
day
===
0
?
7
:
day
;
const
offset
=
this
.
offsetDay
;
const
rows
=
this
.
tableRows
;
let
count
=
1
;
const
startDate
=
this
.
startDate
;
const
disabledDate
=
this
.
disabledDate
;
const
cellClassName
=
this
.
cellClassName
;
const
selectedDate
=
this
.
selectionMode
===
"
dates
"
?
coerceTruthyValueToArray
(
this
.
value
)
:
[];
const
now
=
getDateTimestamp
(
new
Date
());
for
(
let
i
=
0
;
i
<
6
;
i
++
)
{
const
row
=
rows
[
i
];
if
(
this
.
showWeekNumber
)
{
if
(
!
row
[
0
])
{
row
[
0
]
=
{
type
:
"
week
"
,
text
:
getWeekNumber
(
nextDate
(
startDate
,
i
*
7
+
1
)),
};
}
}
for
(
let
j
=
0
;
j
<
7
;
j
++
)
{
let
cell
=
row
[
this
.
showWeekNumber
?
j
+
1
:
j
];
if
(
!
cell
)
{
cell
=
{
row
:
i
,
column
:
j
,
type
:
"
normal
"
,
inRange
:
false
,
start
:
false
,
end
:
false
,
};
}
cell
.
type
=
"
normal
"
;
const
index
=
i
*
7
+
j
;
const
time
=
nextDate
(
startDate
,
index
-
offset
).
getTime
();
cell
.
inRange
=
time
>=
getDateTimestamp
(
this
.
minDate
)
&&
time
<=
getDateTimestamp
(
this
.
maxDate
);
cell
.
start
=
this
.
minDate
&&
time
===
getDateTimestamp
(
this
.
minDate
);
cell
.
end
=
this
.
maxDate
&&
time
===
getDateTimestamp
(
this
.
maxDate
);
const
isToday
=
time
===
now
;
if
(
isToday
)
{
cell
.
type
=
"
today
"
;
}
if
(
i
>=
0
&&
i
<=
1
)
{
const
numberOfDaysFromPreviousMonth
=
day
+
offset
<
0
?
7
+
day
+
offset
:
day
+
offset
;
if
(
j
+
i
*
7
>=
numberOfDaysFromPreviousMonth
)
{
cell
.
text
=
count
++
;
}
else
{
cell
.
text
=
dateCountOfLastMonth
-
(
numberOfDaysFromPreviousMonth
-
(
j
%
7
))
+
1
+
i
*
7
;
cell
.
type
=
"
prev-month
"
;
}
}
else
{
if
(
count
<=
dateCountOfMonth
)
{
cell
.
text
=
count
++
;
}
else
{
cell
.
text
=
count
++
-
dateCountOfMonth
;
cell
.
type
=
"
next-month
"
;
}
}
let
cellDate
=
new
Date
(
time
);
cell
.
disabled
=
typeof
disabledDate
===
"
function
"
&&
disabledDate
(
cellDate
);
cell
.
selected
=
arrayFind
(
selectedDate
,
(
date
)
=>
date
.
getTime
()
===
cellDate
.
getTime
()
);
cell
.
customClass
=
typeof
cellClassName
===
"
function
"
&&
cellClassName
(
cellDate
);
this
.
$set
(
row
,
this
.
showWeekNumber
?
j
+
1
:
j
,
cell
);
}
if
(
this
.
selectionMode
===
"
week
"
)
{
const
start
=
this
.
showWeekNumber
?
1
:
0
;
const
end
=
this
.
showWeekNumber
?
7
:
6
;
const
isWeekActive
=
this
.
isWeekActive
(
row
[
start
+
1
]);
row
[
start
].
inRange
=
isWeekActive
;
row
[
start
].
start
=
isWeekActive
;
row
[
end
].
inRange
=
isWeekActive
;
row
[
end
].
end
=
isWeekActive
;
}
}
return
rows
;
},
},
watch
:
{
"
rangeState.endDate
"
(
newVal
)
{
this
.
markRange
(
this
.
minDate
,
newVal
);
},
minDate
(
newVal
,
oldVal
)
{
if
(
getDateTimestamp
(
newVal
)
!==
getDateTimestamp
(
oldVal
))
{
this
.
markRange
(
this
.
minDate
,
this
.
maxDate
);
}
},
maxDate
(
newVal
,
oldVal
)
{
if
(
getDateTimestamp
(
newVal
)
!==
getDateTimestamp
(
oldVal
))
{
this
.
markRange
(
this
.
minDate
,
this
.
maxDate
);
}
},
},
data
()
{
return
{
tableRows
:
[[],
[],
[],
[],
[],
[]],
lastRow
:
null
,
lastColumn
:
null
,
};
},
methods
:
{
cellMatchesDate
(
cell
,
date
)
{
const
value
=
new
Date
(
date
);
return
(
this
.
year
===
value
.
getFullYear
()
&&
this
.
month
===
value
.
getMonth
()
&&
Number
(
cell
.
text
)
===
value
.
getDate
()
);
},
getCellClasses
(
cell
)
{
const
selectionMode
=
this
.
selectionMode
;
const
defaultValue
=
this
.
defaultValue
?
Array
.
isArray
(
this
.
defaultValue
)
?
this
.
defaultValue
:
[
this
.
defaultValue
]
:
[];
let
classes
=
[];
if
((
cell
.
type
===
"
normal
"
||
cell
.
type
===
"
today
"
)
&&
!
cell
.
disabled
)
{
classes
.
push
(
"
available
"
);
if
(
cell
.
type
===
"
today
"
)
{
classes
.
push
(
"
today
"
);
}
}
else
{
classes
.
push
(
cell
.
type
);
}
if
(
cell
.
type
===
"
normal
"
&&
defaultValue
.
some
((
date
)
=>
this
.
cellMatchesDate
(
cell
,
date
))
)
{
classes
.
push
(
"
default
"
);
}
if
(
selectionMode
===
"
day
"
&&
(
cell
.
type
===
"
normal
"
||
cell
.
type
===
"
today
"
)
&&
this
.
cellMatchesDate
(
cell
,
this
.
value
)
)
{
classes
.
push
(
"
current
"
);
}
if
(
cell
.
inRange
&&
(
cell
.
type
===
"
normal
"
||
cell
.
type
===
"
today
"
||
this
.
selectionMode
===
"
week
"
)
)
{
classes
.
push
(
"
in-range
"
);
if
(
cell
.
start
)
{
classes
.
push
(
"
start-date
"
);
}
if
(
cell
.
end
)
{
classes
.
push
(
"
end-date
"
);
}
}
if
(
cell
.
disabled
)
{
classes
.
push
(
"
disabled
"
);
}
if
(
cell
.
selected
)
{
classes
.
push
(
"
selected
"
);
}
if
(
cell
.
customClass
)
{
classes
.
push
(
cell
.
customClass
);
}
return
classes
.
join
(
"
"
);
},
getDateOfCell
(
row
,
column
)
{
const
offsetFromStart
=
row
*
7
+
(
column
-
(
this
.
showWeekNumber
?
1
:
0
))
-
this
.
offsetDay
;
return
nextDate
(
this
.
startDate
,
offsetFromStart
);
},
isWeekActive
(
cell
)
{
if
(
this
.
selectionMode
!==
"
week
"
)
return
false
;
const
newDate
=
new
Date
(
this
.
year
,
this
.
month
,
1
);
const
year
=
newDate
.
getFullYear
();
const
month
=
newDate
.
getMonth
();
if
(
cell
.
type
===
"
prev-month
"
)
{
newDate
.
setMonth
(
month
===
0
?
11
:
month
-
1
);
newDate
.
setFullYear
(
month
===
0
?
year
-
1
:
year
);
}
if
(
cell
.
type
===
"
next-month
"
)
{
newDate
.
setMonth
(
month
===
11
?
0
:
month
+
1
);
newDate
.
setFullYear
(
month
===
11
?
year
+
1
:
year
);
}
newDate
.
setDate
(
parseInt
(
cell
.
text
,
10
));
if
(
isDate
(
this
.
value
))
{
const
dayOffset
=
((
this
.
value
.
getDay
()
-
this
.
firstDayOfWeek
+
7
)
%
7
)
-
1
;
const
weekDate
=
prevDate
(
this
.
value
,
dayOffset
);
return
weekDate
.
getTime
()
===
newDate
.
getTime
();
}
return
false
;
},
markRange
(
minDate
,
maxDate
)
{
minDate
=
getDateTimestamp
(
minDate
);
maxDate
=
getDateTimestamp
(
maxDate
)
||
minDate
;
[
minDate
,
maxDate
]
=
[
Math
.
min
(
minDate
,
maxDate
),
Math
.
max
(
minDate
,
maxDate
),
];
const
startDate
=
this
.
startDate
;
const
rows
=
this
.
rows
;
for
(
let
i
=
0
,
k
=
rows
.
length
;
i
<
k
;
i
++
)
{
const
row
=
rows
[
i
];
for
(
let
j
=
0
,
l
=
row
.
length
;
j
<
l
;
j
++
)
{
if
(
this
.
showWeekNumber
&&
j
===
0
)
continue
;
const
cell
=
row
[
j
];
const
index
=
i
*
7
+
j
+
(
this
.
showWeekNumber
?
-
1
:
0
);
const
time
=
nextDate
(
startDate
,
index
-
this
.
offsetDay
).
getTime
();
cell
.
inRange
=
minDate
&&
time
>=
minDate
&&
time
<=
maxDate
;
cell
.
start
=
minDate
&&
time
===
minDate
;
cell
.
end
=
maxDate
&&
time
===
maxDate
;
}
}
},
handleMouseMove
(
event
)
{
if
(
!
this
.
rangeState
.
selecting
)
return
;
let
target
=
event
.
target
;
if
(
target
.
tagName
===
"
SPAN
"
)
{
target
=
target
.
parentNode
.
parentNode
;
}
if
(
target
.
tagName
===
"
DIV
"
)
{
target
=
target
.
parentNode
;
}
if
(
target
.
tagName
!==
"
TD
"
)
return
;
const
row
=
target
.
parentNode
.
rowIndex
-
1
;
const
column
=
target
.
cellIndex
;
// can not select disabled date
if
(
this
.
rows
[
row
][
column
].
disabled
)
return
;
// only update rangeState when mouse moves to a new cell
// this avoids frequent Date object creation and improves performance
if
(
row
!==
this
.
lastRow
||
column
!==
this
.
lastColumn
)
{
this
.
lastRow
=
row
;
this
.
lastColumn
=
column
;
this
.
$emit
(
"
changerange
"
,
{
minDate
:
this
.
minDate
,
maxDate
:
this
.
maxDate
,
rangeState
:
{
selecting
:
true
,
endDate
:
this
.
getDateOfCell
(
row
,
column
),
},
});
}
},
handleClick
(
event
)
{
let
target
=
event
.
target
;
if
(
target
.
tagName
===
"
SPAN
"
)
{
target
=
target
.
parentNode
.
parentNode
;
}
if
(
target
.
tagName
===
"
DIV
"
)
{
target
=
target
.
parentNode
;
}
if
(
target
.
tagName
!==
"
TD
"
)
return
;
const
row
=
target
.
parentNode
.
rowIndex
-
1
;
const
column
=
this
.
selectionMode
===
"
week
"
?
1
:
target
.
cellIndex
;
const
cell
=
this
.
rows
[
row
][
column
];
if
(
cell
.
disabled
||
cell
.
type
===
"
week
"
)
return
;
const
newDate
=
this
.
getDateOfCell
(
row
,
column
);
if
(
this
.
selectionMode
===
"
range
"
)
{
if
(
!
this
.
rangeState
.
selecting
)
{
this
.
$emit
(
"
pick
"
,
{
minDate
:
newDate
,
maxDate
:
null
});
this
.
rangeState
.
selecting
=
true
;
}
else
{
if
(
newDate
>=
this
.
minDate
)
{
this
.
$emit
(
"
pick
"
,
{
minDate
:
this
.
minDate
,
maxDate
:
newDate
});
}
else
{
this
.
$emit
(
"
pick
"
,
{
minDate
:
newDate
,
maxDate
:
this
.
minDate
});
}
this
.
rangeState
.
selecting
=
false
;
}
}
else
if
(
this
.
selectionMode
===
"
day
"
)
{
this
.
$emit
(
"
pick
"
,
newDate
);
}
else
if
(
this
.
selectionMode
===
"
week
"
)
{
const
weekNumber
=
getWeekNumber
(
newDate
);
const
value
=
newDate
.
getFullYear
()
+
"
w
"
+
weekNumber
;
this
.
$emit
(
"
pick
"
,
{
year
:
newDate
.
getFullYear
(),
week
:
weekNumber
,
value
:
value
,
date
:
newDate
,
});
}
else
if
(
this
.
selectionMode
===
"
dates
"
)
{
const
value
=
this
.
value
||
[];
const
newValue
=
cell
.
selected
?
removeFromArray
(
value
,
(
date
)
=>
date
.
getTime
()
===
newDate
.
getTime
()
)
:
[...
value
,
newDate
];
this
.
$emit
(
"
pick
"
,
newValue
);
}
},
},
};
</
script
>
admin_2/src/components/YDatePickerTab/date-picker/src/basic/month-table.vue
0 → 100644
View file @
6f2cf656
<
template
>
<table
@
click=
"handleMonthTableClick"
@
mousemove=
"handleMouseMove"
class=
"el-month-table"
>
<tbody>
<tr
v-for=
"(row, key) in rows"
:key=
"key"
>
<td
:class=
"getCellStyle(cell)"
v-for=
"(cell, key) in row"
:key=
"key"
>
<div>
<a
class=
"cell"
>
{{
t
(
"
el.datepicker.months.
"
+
months
[
cell
.
text
])
}}
</a>
</div>
</td>
</tr>
</tbody>
</table>
</
template
>
<
script
type=
"text/babel"
>
/* eslint-disable */
import
Locale
from
"
element-ui/src/mixins/locale
"
;
import
{
isDate
,
range
,
getDayCountOfMonth
,
nextDate
,
}
from
"
element-ui/src/utils/date-util
"
;
import
{
hasClass
}
from
"
element-ui/src/utils/dom
"
;
import
{
arrayFindIndex
,
coerceTruthyValueToArray
,
arrayFind
,
}
from
"
element-ui/src/utils/util
"
;
const
datesInMonth
=
(
year
,
month
)
=>
{
const
numOfDays
=
getDayCountOfMonth
(
year
,
month
);
const
firstDay
=
new
Date
(
year
,
month
,
1
);
return
range
(
numOfDays
).
map
((
n
)
=>
nextDate
(
firstDay
,
n
));
};
const
clearDate
=
(
date
)
=>
{
return
new
Date
(
date
.
getFullYear
(),
date
.
getMonth
());
};
const
getMonthTimestamp
=
function
(
time
)
{
if
(
typeof
time
===
"
number
"
||
typeof
time
===
"
string
"
)
{
return
clearDate
(
new
Date
(
time
)).
getTime
();
}
else
if
(
time
instanceof
Date
)
{
return
clearDate
(
time
).
getTime
();
}
else
{
return
NaN
;
}
};
// remove the first element that satisfies `pred` from arr
// return a new array if modification occurs
// return the original array otherwise
const
removeFromArray
=
function
(
arr
,
pred
)
{
const
idx
=
typeof
pred
===
"
function
"
?
arrayFindIndex
(
arr
,
pred
)
:
arr
.
indexOf
(
pred
);
return
idx
>=
0
?
[...
arr
.
slice
(
0
,
idx
),
...
arr
.
slice
(
idx
+
1
)]
:
arr
;
};
export
default
{
props
:
{
disabledDate
:
{},
value
:
{},
selectionMode
:
{
default
:
"
month
"
,
},
minDate
:
{},
maxDate
:
{},
defaultValue
:
{
validator
(
val
)
{
// null or valid Date Object
return
(
val
===
null
||
isDate
(
val
)
||
(
Array
.
isArray
(
val
)
&&
val
.
every
(
isDate
))
);
},
},
date
:
{},
rangeState
:
{
default
()
{
return
{
endDate
:
null
,
selecting
:
false
,
};
},
},
},
mixins
:
[
Locale
],
watch
:
{
"
rangeState.endDate
"
(
newVal
)
{
this
.
markRange
(
this
.
minDate
,
newVal
);
},
minDate
(
newVal
,
oldVal
)
{
if
(
getMonthTimestamp
(
newVal
)
!==
getMonthTimestamp
(
oldVal
))
{
this
.
markRange
(
this
.
minDate
,
this
.
maxDate
);
}
},
maxDate
(
newVal
,
oldVal
)
{
if
(
getMonthTimestamp
(
newVal
)
!==
getMonthTimestamp
(
oldVal
))
{
this
.
markRange
(
this
.
minDate
,
this
.
maxDate
);
}
},
},
data
()
{
return
{
months
:
[
"
jan
"
,
"
feb
"
,
"
mar
"
,
"
apr
"
,
"
may
"
,
"
jun
"
,
"
jul
"
,
"
aug
"
,
"
sep
"
,
"
oct
"
,
"
nov
"
,
"
dec
"
,
],
tableRows
:
[[],
[],
[]],
lastRow
:
null
,
lastColumn
:
null
,
};
},
methods
:
{
cellMatchesDate
(
cell
,
date
)
{
const
value
=
new
Date
(
date
);
return
(
this
.
date
.
getFullYear
()
===
value
.
getFullYear
()
&&
Number
(
cell
.
text
)
===
value
.
getMonth
()
);
},
getCellStyle
(
cell
)
{
const
style
=
{};
const
year
=
this
.
date
.
getFullYear
();
const
today
=
new
Date
();
const
month
=
cell
.
text
;
const
defaultValue
=
this
.
defaultValue
?
Array
.
isArray
(
this
.
defaultValue
)
?
this
.
defaultValue
:
[
this
.
defaultValue
]
:
[];
style
.
disabled
=
typeof
this
.
disabledDate
===
"
function
"
?
datesInMonth
(
year
,
month
).
every
(
this
.
disabledDate
)
:
false
;
style
.
current
=
arrayFindIndex
(
coerceTruthyValueToArray
(
this
.
value
),
(
date
)
=>
date
.
getFullYear
()
===
year
&&
date
.
getMonth
()
===
month
)
>=
0
;
style
.
today
=
today
.
getFullYear
()
===
year
&&
today
.
getMonth
()
===
month
;
style
.
default
=
defaultValue
.
some
((
date
)
=>
this
.
cellMatchesDate
(
cell
,
date
)
);
if
(
cell
.
inRange
)
{
style
[
"
in-range
"
]
=
true
;
if
(
cell
.
start
)
{
style
[
"
start-date
"
]
=
true
;
}
if
(
cell
.
end
)
{
style
[
"
end-date
"
]
=
true
;
}
}
return
style
;
},
getMonthOfCell
(
month
)
{
const
year
=
this
.
date
.
getFullYear
();
return
new
Date
(
year
,
month
,
1
);
},
markRange
(
minDate
,
maxDate
)
{
minDate
=
getMonthTimestamp
(
minDate
);
maxDate
=
getMonthTimestamp
(
maxDate
)
||
minDate
;
[
minDate
,
maxDate
]
=
[
Math
.
min
(
minDate
,
maxDate
),
Math
.
max
(
minDate
,
maxDate
),
];
const
rows
=
this
.
rows
;
for
(
let
i
=
0
,
k
=
rows
.
length
;
i
<
k
;
i
++
)
{
const
row
=
rows
[
i
];
for
(
let
j
=
0
,
l
=
row
.
length
;
j
<
l
;
j
++
)
{
const
cell
=
row
[
j
];
const
index
=
i
*
4
+
j
;
const
time
=
new
Date
(
this
.
date
.
getFullYear
(),
index
).
getTime
();
cell
.
inRange
=
minDate
&&
time
>=
minDate
&&
time
<=
maxDate
;
cell
.
start
=
minDate
&&
time
===
minDate
;
cell
.
end
=
maxDate
&&
time
===
maxDate
;
}
}
},
handleMouseMove
(
event
)
{
if
(
!
this
.
rangeState
.
selecting
)
return
;
let
target
=
event
.
target
;
if
(
target
.
tagName
===
"
A
"
)
{
target
=
target
.
parentNode
.
parentNode
;
}
if
(
target
.
tagName
===
"
DIV
"
)
{
target
=
target
.
parentNode
;
}
if
(
target
.
tagName
!==
"
TD
"
)
return
;
const
row
=
target
.
parentNode
.
rowIndex
;
const
column
=
target
.
cellIndex
;
// can not select disabled date
if
(
this
.
rows
[
row
][
column
].
disabled
)
return
;
// only update rangeState when mouse moves to a new cell
// this avoids frequent Date object creation and improves performance
if
(
row
!==
this
.
lastRow
||
column
!==
this
.
lastColumn
)
{
this
.
lastRow
=
row
;
this
.
lastColumn
=
column
;
this
.
$emit
(
"
changerange
"
,
{
minDate
:
this
.
minDate
,
maxDate
:
this
.
maxDate
,
rangeState
:
{
selecting
:
true
,
endDate
:
this
.
getMonthOfCell
(
row
*
4
+
column
),
},
});
}
},
handleMonthTableClick
(
event
)
{
let
target
=
event
.
target
;
if
(
target
.
tagName
===
"
A
"
)
{
target
=
target
.
parentNode
.
parentNode
;
}
if
(
target
.
tagName
===
"
DIV
"
)
{
target
=
target
.
parentNode
;
}
if
(
target
.
tagName
!==
"
TD
"
)
return
;
if
(
hasClass
(
target
,
"
disabled
"
))
return
;
const
column
=
target
.
cellIndex
;
const
row
=
target
.
parentNode
.
rowIndex
;
const
month
=
row
*
4
+
column
;
const
newDate
=
this
.
getMonthOfCell
(
month
);
if
(
this
.
selectionMode
===
"
range
"
)
{
if
(
!
this
.
rangeState
.
selecting
)
{
this
.
$emit
(
"
pick
"
,
{
minDate
:
newDate
,
maxDate
:
null
});
this
.
rangeState
.
selecting
=
true
;
}
else
{
if
(
newDate
>=
this
.
minDate
)
{
this
.
$emit
(
"
pick
"
,
{
minDate
:
this
.
minDate
,
maxDate
:
newDate
});
}
else
{
this
.
$emit
(
"
pick
"
,
{
minDate
:
newDate
,
maxDate
:
this
.
minDate
});
}
this
.
rangeState
.
selecting
=
false
;
}
}
else
if
(
this
.
selectionMode
===
"
months
"
)
{
const
value
=
this
.
value
||
[];
const
year
=
this
.
date
.
getFullYear
();
const
newValue
=
arrayFindIndex
(
value
,
(
date
)
=>
date
.
getFullYear
()
===
year
&&
date
.
getMonth
()
===
month
)
>=
0
?
removeFromArray
(
value
,
(
date
)
=>
date
.
getTime
()
===
newDate
.
getTime
()
)
:
[...
value
,
newDate
];
this
.
$emit
(
"
pick
"
,
newValue
);
}
else
{
this
.
$emit
(
"
pick
"
,
month
);
}
},
},
computed
:
{
rows
()
{
// TODO: refactory rows / getCellClasses
const
rows
=
this
.
tableRows
;
const
disabledDate
=
this
.
disabledDate
;
const
selectedDate
=
[];
const
now
=
getMonthTimestamp
(
new
Date
());
for
(
let
i
=
0
;
i
<
3
;
i
++
)
{
const
row
=
rows
[
i
];
for
(
let
j
=
0
;
j
<
4
;
j
++
)
{
let
cell
=
row
[
j
];
if
(
!
cell
)
{
cell
=
{
row
:
i
,
column
:
j
,
type
:
"
normal
"
,
inRange
:
false
,
start
:
false
,
end
:
false
,
};
}
cell
.
type
=
"
normal
"
;
const
index
=
i
*
4
+
j
;
const
time
=
new
Date
(
this
.
date
.
getFullYear
(),
index
).
getTime
();
cell
.
inRange
=
time
>=
getMonthTimestamp
(
this
.
minDate
)
&&
time
<=
getMonthTimestamp
(
this
.
maxDate
);
cell
.
start
=
this
.
minDate
&&
time
===
getMonthTimestamp
(
this
.
minDate
);
cell
.
end
=
this
.
maxDate
&&
time
===
getMonthTimestamp
(
this
.
maxDate
);
const
isToday
=
time
===
now
;
if
(
isToday
)
{
cell
.
type
=
"
today
"
;
}
cell
.
text
=
index
;
let
cellDate
=
new
Date
(
time
);
cell
.
disabled
=
typeof
disabledDate
===
"
function
"
&&
disabledDate
(
cellDate
);
cell
.
selected
=
arrayFind
(
selectedDate
,
(
date
)
=>
date
.
getTime
()
===
cellDate
.
getTime
()
);
this
.
$set
(
row
,
j
,
cell
);
}
}
return
rows
;
},
},
};
</
script
>
admin_2/src/components/YDatePickerTab/date-picker/src/basic/time-spinner.vue
0 → 100644
View file @
6f2cf656
<
template
>
<div
class=
"el-time-spinner"
:class=
"
{ 'has-seconds': showSeconds }">
<template
v-if=
"!arrowControl"
>
<el-scrollbar
@
mouseenter.native=
"emitSelectRange('hours')"
@
mousemove.native=
"adjustCurrentSpinner('hours')"
class=
"el-time-spinner__wrapper"
wrap-style=
"max-height: inherit;"
view-class=
"el-time-spinner__list"
noresize
tag=
"ul"
ref=
"hours"
>
<li
@
click=
"handleClick('hours',
{ value: hour, disabled: disabled })"
v-for="(disabled, hour) in hoursList"
class="el-time-spinner__item"
:key="hour"
:class="{ active: hour === hours, disabled: disabled }"
>
{{
(
"
0
"
+
(
amPmMode
?
hour
%
12
||
12
:
hour
)).
slice
(
-
2
)
}}{{
amPm
(
hour
)
}}
</li>
</el-scrollbar>
<el-scrollbar
@
mouseenter.native=
"emitSelectRange('minutes')"
@
mousemove.native=
"adjustCurrentSpinner('minutes')"
class=
"el-time-spinner__wrapper"
wrap-style=
"max-height: inherit;"
view-class=
"el-time-spinner__list"
noresize
tag=
"ul"
ref=
"minutes"
>
<li
@
click=
"handleClick('minutes',
{ value: key, disabled: false })"
v-for="(enabled, key) in minutesList"
:key="key"
class="el-time-spinner__item"
:class="{ active: key === minutes, disabled: !enabled }"
>
{{
(
"
0
"
+
key
).
slice
(
-
2
)
}}
</li>
</el-scrollbar>
<el-scrollbar
v-show=
"showSeconds"
@
mouseenter.native=
"emitSelectRange('seconds')"
@
mousemove.native=
"adjustCurrentSpinner('seconds')"
class=
"el-time-spinner__wrapper"
wrap-style=
"max-height: inherit;"
view-class=
"el-time-spinner__list"
noresize
tag=
"ul"
ref=
"seconds"
>
<li
@
click=
"handleClick('seconds',
{ value: key, disabled: false })"
v-for="(second, key) in 60"
class="el-time-spinner__item"
:class="{ active: key === seconds }"
:key="key"
>
{{
(
"
0
"
+
key
).
slice
(
-
2
)
}}
</li>
</el-scrollbar>
</
template
>
<
template
v-if=
"arrowControl"
>
<div
@
mouseenter=
"emitSelectRange('hours')"
class=
"el-time-spinner__wrapper is-arrow"
>
<i
v-repeat-click=
"decrease"
class=
"el-time-spinner__arrow el-icon-arrow-up"
></i>
<i
v-repeat-click=
"increase"
class=
"el-time-spinner__arrow el-icon-arrow-down"
></i>
<ul
class=
"el-time-spinner__list"
ref=
"hours"
>
<li
class=
"el-time-spinner__item"
:class=
"
{ active: hour === hours, disabled: hoursList[hour] }"
v-for="(hour, key) in arrowHourList"
:key="key"
>
{{
hour
===
undefined
?
""
:
(
"
0
"
+
(
amPmMode
?
hour
%
12
||
12
:
hour
)).
slice
(
-
2
)
+
amPm
(
hour
)
}}
</li>
</ul>
</div>
<div
@
mouseenter=
"emitSelectRange('minutes')"
class=
"el-time-spinner__wrapper is-arrow"
>
<i
v-repeat-click=
"decrease"
class=
"el-time-spinner__arrow el-icon-arrow-up"
></i>
<i
v-repeat-click=
"increase"
class=
"el-time-spinner__arrow el-icon-arrow-down"
></i>
<ul
class=
"el-time-spinner__list"
ref=
"minutes"
>
<li
class=
"el-time-spinner__item"
:class=
"
{ active: minute === minutes }"
v-for="(minute, key) in arrowMinuteList"
:key="key"
>
{{
minute
===
undefined
?
""
:
(
"
0
"
+
minute
).
slice
(
-
2
)
}}
</li>
</ul>
</div>
<div
@
mouseenter=
"emitSelectRange('seconds')"
class=
"el-time-spinner__wrapper is-arrow"
v-if=
"showSeconds"
>
<i
v-repeat-click=
"decrease"
class=
"el-time-spinner__arrow el-icon-arrow-up"
></i>
<i
v-repeat-click=
"increase"
class=
"el-time-spinner__arrow el-icon-arrow-down"
></i>
<ul
class=
"el-time-spinner__list"
ref=
"seconds"
>
<li
v-for=
"(second, key) in arrowSecondList"
class=
"el-time-spinner__item"
:class=
"
{ active: second === seconds }"
:key="key"
>
{{
second
===
undefined
?
""
:
(
"
0
"
+
second
).
slice
(
-
2
)
}}
</li>
</ul>
</div>
</
template
>
</div>
</template>
<
script
type=
"text/babel"
>
/* eslint-disable */
import
{
getRangeHours
,
getRangeMinutes
,
modifyTime
,
}
from
"
element-ui/src/utils/date-util
"
;
import
ElScrollbar
from
"
element-ui/packages/scrollbar
"
;
import
RepeatClick
from
"
element-ui/src/directives/repeat-click
"
;
export
default
{
components
:
{
ElScrollbar
},
directives
:
{
repeatClick
:
RepeatClick
,
},
props
:
{
date
:
{},
defaultValue
:
{},
// reserved for future use
showSeconds
:
{
type
:
Boolean
,
default
:
true
,
},
arrowControl
:
Boolean
,
amPmMode
:
{
type
:
String
,
default
:
""
,
// 'a': am/pm; 'A': AM/PM
},
},
computed
:
{
hours
()
{
return
this
.
date
.
getHours
();
},
minutes
()
{
return
this
.
date
.
getMinutes
();
},
seconds
()
{
return
this
.
date
.
getSeconds
();
},
hoursList
()
{
return
getRangeHours
(
this
.
selectableRange
);
},
minutesList
()
{
return
getRangeMinutes
(
this
.
selectableRange
,
this
.
hours
);
},
arrowHourList
()
{
const
hours
=
this
.
hours
;
return
[
hours
>
0
?
hours
-
1
:
undefined
,
hours
,
hours
<
23
?
hours
+
1
:
undefined
,
];
},
arrowMinuteList
()
{
const
minutes
=
this
.
minutes
;
return
[
minutes
>
0
?
minutes
-
1
:
undefined
,
minutes
,
minutes
<
59
?
minutes
+
1
:
undefined
,
];
},
arrowSecondList
()
{
const
seconds
=
this
.
seconds
;
return
[
seconds
>
0
?
seconds
-
1
:
undefined
,
seconds
,
seconds
<
59
?
seconds
+
1
:
undefined
,
];
},
},
data
()
{
return
{
selectableRange
:
[],
currentScrollbar
:
null
,
};
},
mounted
()
{
this
.
$nextTick
(()
=>
{
!
this
.
arrowControl
&&
this
.
bindScrollEvent
();
});
},
methods
:
{
increase
()
{
this
.
scrollDown
(
1
);
},
decrease
()
{
this
.
scrollDown
(
-
1
);
},
modifyDateField
(
type
,
value
)
{
switch
(
type
)
{
case
"
hours
"
:
this
.
$emit
(
"
change
"
,
modifyTime
(
this
.
date
,
value
,
this
.
minutes
,
this
.
seconds
)
);
break
;
case
"
minutes
"
:
this
.
$emit
(
"
change
"
,
modifyTime
(
this
.
date
,
this
.
hours
,
value
,
this
.
seconds
)
);
break
;
case
"
seconds
"
:
this
.
$emit
(
"
change
"
,
modifyTime
(
this
.
date
,
this
.
hours
,
this
.
minutes
,
value
)
);
break
;
}
},
handleClick
(
type
,
{
value
,
disabled
})
{
if
(
!
disabled
)
{
this
.
modifyDateField
(
type
,
value
);
this
.
emitSelectRange
(
type
);
this
.
adjustSpinner
(
type
,
value
);
}
},
emitSelectRange
(
type
)
{
if
(
type
===
"
hours
"
)
{
this
.
$emit
(
"
select-range
"
,
0
,
2
);
}
else
if
(
type
===
"
minutes
"
)
{
this
.
$emit
(
"
select-range
"
,
3
,
5
);
}
else
if
(
type
===
"
seconds
"
)
{
this
.
$emit
(
"
select-range
"
,
6
,
8
);
}
this
.
currentScrollbar
=
type
;
},
bindScrollEvent
()
{
const
bindFunction
=
(
type
)
=>
{
this
.
$refs
[
type
].
wrap
.
onscroll
=
(
e
)
=>
{
// TODO: scroll is emitted when set scrollTop programatically
// should find better solutions in the future!
this
.
handleScroll
(
type
,
e
);
};
};
bindFunction
(
"
hours
"
);
bindFunction
(
"
minutes
"
);
bindFunction
(
"
seconds
"
);
},
handleScroll
(
type
)
{
const
value
=
Math
.
min
(
Math
.
round
(
(
this
.
$refs
[
type
].
wrap
.
scrollTop
-
(
this
.
scrollBarHeight
(
type
)
*
0.5
-
10
)
/
this
.
typeItemHeight
(
type
)
+
3
)
/
this
.
typeItemHeight
(
type
)
),
type
===
"
hours
"
?
23
:
59
);
this
.
modifyDateField
(
type
,
value
);
},
// NOTE: used by datetime / date-range panel
// renamed from adjustScrollTop
// should try to refactory it
adjustSpinners
()
{
this
.
adjustSpinner
(
"
hours
"
,
this
.
hours
);
this
.
adjustSpinner
(
"
minutes
"
,
this
.
minutes
);
this
.
adjustSpinner
(
"
seconds
"
,
this
.
seconds
);
},
adjustCurrentSpinner
(
type
)
{
this
.
adjustSpinner
(
type
,
this
[
type
]);
},
adjustSpinner
(
type
,
value
)
{
if
(
this
.
arrowControl
)
return
;
const
el
=
this
.
$refs
[
type
].
wrap
;
if
(
el
)
{
el
.
scrollTop
=
Math
.
max
(
0
,
value
*
this
.
typeItemHeight
(
type
));
}
},
scrollDown
(
step
)
{
if
(
!
this
.
currentScrollbar
)
{
this
.
emitSelectRange
(
"
hours
"
);
}
const
label
=
this
.
currentScrollbar
;
const
hoursList
=
this
.
hoursList
;
let
now
=
this
[
label
];
if
(
this
.
currentScrollbar
===
"
hours
"
)
{
let
total
=
Math
.
abs
(
step
);
step
=
step
>
0
?
1
:
-
1
;
let
length
=
hoursList
.
length
;
while
(
length
--
&&
total
)
{
now
=
(
now
+
step
+
hoursList
.
length
)
%
hoursList
.
length
;
if
(
hoursList
[
now
])
{
continue
;
}
total
--
;
}
if
(
hoursList
[
now
])
return
;
}
else
{
now
=
(
now
+
step
+
60
)
%
60
;
}
this
.
modifyDateField
(
label
,
now
);
this
.
adjustSpinner
(
label
,
now
);
this
.
$nextTick
(()
=>
this
.
emitSelectRange
(
this
.
currentScrollbar
));
},
amPm
(
hour
)
{
let
shouldShowAmPm
=
this
.
amPmMode
.
toLowerCase
()
===
"
a
"
;
if
(
!
shouldShowAmPm
)
return
""
;
let
isCapital
=
this
.
amPmMode
===
"
A
"
;
let
content
=
hour
<
12
?
"
am
"
:
"
pm
"
;
if
(
isCapital
)
content
=
content
.
toUpperCase
();
return
content
;
},
typeItemHeight
(
type
)
{
return
this
.
$refs
[
type
].
$el
.
querySelector
(
"
li
"
).
offsetHeight
;
},
scrollBarHeight
(
type
)
{
return
this
.
$refs
[
type
].
$el
.
offsetHeight
;
},
},
};
</
script
>
admin_2/src/components/YDatePickerTab/date-picker/src/basic/year-table.vue
0 → 100644
View file @
6f2cf656
<
template
>
<table
@
click=
"handleYearTableClick"
class=
"el-year-table"
>
<tbody>
<tr>
<td
class=
"available"
:class=
"getCellStyle(startYear + 0)"
>
<a
class=
"cell"
>
{{
startYear
}}
</a>
</td>
<td
class=
"available"
:class=
"getCellStyle(startYear + 1)"
>
<a
class=
"cell"
>
{{
startYear
+
1
}}
</a>
</td>
<td
class=
"available"
:class=
"getCellStyle(startYear + 2)"
>
<a
class=
"cell"
>
{{
startYear
+
2
}}
</a>
</td>
<td
class=
"available"
:class=
"getCellStyle(startYear + 3)"
>
<a
class=
"cell"
>
{{
startYear
+
3
}}
</a>
</td>
</tr>
<tr>
<td
class=
"available"
:class=
"getCellStyle(startYear + 4)"
>
<a
class=
"cell"
>
{{
startYear
+
4
}}
</a>
</td>
<td
class=
"available"
:class=
"getCellStyle(startYear + 5)"
>
<a
class=
"cell"
>
{{
startYear
+
5
}}
</a>
</td>
<td
class=
"available"
:class=
"getCellStyle(startYear + 6)"
>
<a
class=
"cell"
>
{{
startYear
+
6
}}
</a>
</td>
<td
class=
"available"
:class=
"getCellStyle(startYear + 7)"
>
<a
class=
"cell"
>
{{
startYear
+
7
}}
</a>
</td>
</tr>
<tr>
<td
class=
"available"
:class=
"getCellStyle(startYear + 8)"
>
<a
class=
"cell"
>
{{
startYear
+
8
}}
</a>
</td>
<td
class=
"available"
:class=
"getCellStyle(startYear + 9)"
>
<a
class=
"cell"
>
{{
startYear
+
9
}}
</a>
</td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
</
template
>
<
script
type=
"text/babel"
>
/* eslint-disable */
import
{
hasClass
}
from
"
element-ui/src/utils/dom
"
;
import
{
isDate
,
range
,
nextDate
,
getDayCountOfYear
,
}
from
"
element-ui/src/utils/date-util
"
;
import
{
arrayFindIndex
,
coerceTruthyValueToArray
,
}
from
"
element-ui/src/utils/util
"
;
const
datesInYear
=
(
year
)
=>
{
const
numOfDays
=
getDayCountOfYear
(
year
);
const
firstDay
=
new
Date
(
year
,
0
,
1
);
return
range
(
numOfDays
).
map
((
n
)
=>
nextDate
(
firstDay
,
n
));
};
export
default
{
props
:
{
disabledDate
:
{},
value
:
{},
defaultValue
:
{
validator
(
val
)
{
// null or valid Date Object
return
val
===
null
||
(
val
instanceof
Date
&&
isDate
(
val
));
},
},
date
:
{},
selectionMode
:
{},
},
computed
:
{
startYear
()
{
return
Math
.
floor
(
this
.
date
.
getFullYear
()
/
10
)
*
10
;
},
},
methods
:
{
getCellStyle
(
year
)
{
const
style
=
{};
const
today
=
new
Date
();
style
.
disabled
=
typeof
this
.
disabledDate
===
"
function
"
?
datesInYear
(
year
).
every
(
this
.
disabledDate
)
:
false
;
style
.
current
=
arrayFindIndex
(
coerceTruthyValueToArray
(
this
.
value
),
(
date
)
=>
date
.
getFullYear
()
===
year
)
>=
0
;
style
.
today
=
today
.
getFullYear
()
===
year
;
style
.
default
=
this
.
defaultValue
&&
this
.
defaultValue
.
getFullYear
()
===
year
;
return
style
;
},
handleYearTableClick
(
event
)
{
const
target
=
event
.
target
;
if
(
target
.
tagName
===
"
A
"
)
{
if
(
hasClass
(
target
.
parentNode
,
"
disabled
"
))
return
;
const
year
=
target
.
textContent
||
target
.
innerText
;
if
(
this
.
selectionMode
===
"
years
"
)
{
const
value
=
this
.
value
||
[];
const
idx
=
arrayFindIndex
(
value
,
(
date
)
=>
date
.
getFullYear
()
===
Number
(
year
)
);
const
newValue
=
idx
>
-
1
?
[...
value
.
slice
(
0
,
idx
),
...
value
.
slice
(
idx
+
1
)]
:
[...
value
,
new
Date
(
year
)];
this
.
$emit
(
"
pick
"
,
newValue
);
}
else
{
this
.
$emit
(
"
pick
"
,
Number
(
year
));
}
}
},
},
};
</
script
>
admin_2/src/components/YDatePickerTab/date-picker/src/panel/date-range.vue
0 → 100644
View file @
6f2cf656
<
template
>
<transition
name=
"el-zoom-in-top"
@
after-leave=
"$emit('dodestroy')"
>
<div
v-show=
"visible"
class=
"el-picker-panel el-date-range-picker el-popper"
:class=
"[
{
'has-sidebar': $slots.sidebar || shortcuts,
'has-time': showTime,
},
popperClass,
]"
>
<div
class=
"el-picker-panel__body-wrapper"
>
<slot
name=
"sidebar"
class=
"el-picker-panel__sidebar"
></slot>
<div
class=
"el-picker-panel__sidebar"
v-if=
"shortcuts"
>
<button
type=
"button"
class=
"el-picker-panel__shortcut"
v-for=
"(shortcut, key) in shortcuts"
:key=
"key"
@
click=
"handleShortcutClick(shortcut)"
>
{{
shortcut
.
text
}}
</button>
</div>
<div
class=
"el-picker-panel__body"
>
<div
class=
"el-date-range-picker__time-header"
v-if=
"showTime"
>
<span
class=
"el-date-range-picker__editors-wrap"
>
<span
class=
"el-date-range-picker__time-picker-wrap"
>
<el-input
size=
"small"
:disabled=
"rangeState.selecting"
ref=
"minInput"
:placeholder=
"t('el.datepicker.startDate')"
class=
"el-date-range-picker__editor"
:value=
"minVisibleDate"
@
input=
"(val) => handleDateInput(val, 'min')"
@
change=
"(val) => handleDateChange(val, 'min')"
/>
</span>
<span
class=
"el-date-range-picker__time-picker-wrap"
v-clickoutside=
"handleMinTimeClose"
>
<el-input
size=
"small"
class=
"el-date-range-picker__editor"
:disabled=
"rangeState.selecting"
:placeholder=
"t('el.datepicker.startTime')"
:value=
"minVisibleTime"
@
focus=
"minTimePickerVisible = true"
@
input=
"(val) => handleTimeInput(val, 'min')"
@
change=
"(val) => handleTimeChange(val, 'min')"
/>
<time-picker
ref=
"minTimePicker"
@
pick=
"handleMinTimePick"
:time-arrow-control=
"arrowControl"
:visible=
"minTimePickerVisible"
@
mounted=
"$refs.minTimePicker.format = timeFormat"
>
</time-picker>
</span>
</span>
<span
class=
"el-icon-arrow-right"
></span>
<span
class=
"el-date-range-picker__editors-wrap is-right"
>
<span
class=
"el-date-range-picker__time-picker-wrap"
>
<el-input
size=
"small"
class=
"el-date-range-picker__editor"
:disabled=
"rangeState.selecting"
:placeholder=
"t('el.datepicker.endDate')"
:value=
"maxVisibleDate"
:readonly=
"!minDate"
@
input=
"(val) => handleDateInput(val, 'max')"
@
change=
"(val) => handleDateChange(val, 'max')"
/>
</span>
<span
class=
"el-date-range-picker__time-picker-wrap"
v-clickoutside=
"handleMaxTimeClose"
>
<el-input
size=
"small"
class=
"el-date-range-picker__editor"
:disabled=
"rangeState.selecting"
:placeholder=
"t('el.datepicker.endTime')"
:value=
"maxVisibleTime"
:readonly=
"!minDate"
@
focus=
"minDate && (maxTimePickerVisible = true)"
@
input=
"(val) => handleTimeInput(val, 'max')"
@
change=
"(val) => handleTimeChange(val, 'max')"
/>
<time-picker
ref=
"maxTimePicker"
@
pick=
"handleMaxTimePick"
:time-arrow-control=
"arrowControl"
:visible=
"maxTimePickerVisible"
@
mounted=
"$refs.maxTimePicker.format = timeFormat"
>
</time-picker>
</span>
</span>
</div>
<div
class=
"el-picker-panel__content el-date-range-picker__content is-left"
>
<div
class=
"el-date-range-picker__header"
>
<button
type=
"button"
@
click=
"leftPrevYear"
class=
"el-picker-panel__icon-btn el-icon-d-arrow-left"
></button>
<button
type=
"button"
@
click=
"leftPrevMonth"
class=
"el-picker-panel__icon-btn el-icon-arrow-left"
></button>
<button
type=
"button"
@
click=
"leftNextYear"
v-if=
"unlinkPanels"
:disabled=
"!enableYearArrow"
:class=
"
{ 'is-disabled': !enableYearArrow }"
class="el-picker-panel__icon-btn el-icon-d-arrow-right"
>
</button>
<button
type=
"button"
@
click=
"leftNextMonth"
v-if=
"unlinkPanels"
:disabled=
"!enableMonthArrow"
:class=
"
{ 'is-disabled': !enableMonthArrow }"
class="el-picker-panel__icon-btn el-icon-arrow-right"
>
</button>
<div>
{{
leftLabel
}}
</div>
</div>
<date-table
selection-mode=
"range"
:date=
"leftDate"
:default-value=
"defaultValue"
:min-date=
"minDate"
:max-date=
"maxDate"
:range-state=
"rangeState"
:disabled-date=
"disabledDate"
:cell-class-name=
"cellClassName"
@
changerange=
"handleChangeRange"
:first-day-of-week=
"firstDayOfWeek"
@
pick=
"handleRangePick"
>
</date-table>
</div>
<div
class=
"el-picker-panel__content el-date-range-picker__content is-right"
>
<div
class=
"el-date-range-picker__header"
>
<button
type=
"button"
@
click=
"rightPrevYear"
v-if=
"unlinkPanels"
:disabled=
"!enableYearArrow"
:class=
"
{ 'is-disabled': !enableYearArrow }"
class="el-picker-panel__icon-btn el-icon-d-arrow-left"
>
</button>
<button
type=
"button"
@
click=
"rightPrevMonth"
v-if=
"unlinkPanels"
:disabled=
"!enableMonthArrow"
:class=
"
{ 'is-disabled': !enableMonthArrow }"
class="el-picker-panel__icon-btn el-icon-arrow-left"
>
</button>
<button
type=
"button"
@
click=
"rightNextYear"
class=
"el-picker-panel__icon-btn el-icon-d-arrow-right"
></button>
<button
type=
"button"
@
click=
"rightNextMonth"
class=
"el-picker-panel__icon-btn el-icon-arrow-right"
></button>
<div>
{{
rightLabel
}}
</div>
</div>
<date-table
selection-mode=
"range"
:date=
"rightDate"
:default-value=
"defaultValue"
:min-date=
"minDate"
:max-date=
"maxDate"
:range-state=
"rangeState"
:disabled-date=
"disabledDate"
:cell-class-name=
"cellClassName"
@
changerange=
"handleChangeRange"
:first-day-of-week=
"firstDayOfWeek"
@
pick=
"handleRangePick"
>
</date-table>
</div>
</div>
</div>
<div
class=
"el-picker-panel__footer"
v-if=
"showTime"
>
<el-button
size=
"mini"
type=
"text"
class=
"el-picker-panel__link-btn"
@
click=
"handleClear"
>
{{
t
(
"
el.datepicker.clear
"
)
}}
</el-button>
<el-button
plain
size=
"mini"
class=
"el-picker-panel__link-btn"
:disabled=
"btnDisabled"
@
click=
"handleConfirm(false)"
>
{{
t
(
"
el.datepicker.confirm
"
)
}}
</el-button>
</div>
</div>
</transition>
</
template
>
<
script
type=
"text/babel"
>
/* eslint-disable */
import
{
formatDate
,
parseDate
,
isDate
,
modifyDate
,
modifyTime
,
modifyWithTimeString
,
prevYear
,
nextYear
,
prevMonth
,
nextMonth
,
nextDate
,
extractDateFormat
,
extractTimeFormat
,
}
from
"
element-ui/src/utils/date-util
"
;
import
Clickoutside
from
"
element-ui/src/utils/clickoutside
"
;
import
Locale
from
"
element-ui/src/mixins/locale
"
;
import
TimePicker
from
"
./time
"
;
import
DateTable
from
"
../basic/date-table
"
;
import
ElInput
from
"
element-ui/packages/input
"
;
import
ElButton
from
"
element-ui/packages/button
"
;
const
calcDefaultValue
=
(
defaultValue
)
=>
{
if
(
Array
.
isArray
(
defaultValue
))
{
return
[
new
Date
(
defaultValue
[
0
]),
new
Date
(
defaultValue
[
1
])];
}
else
if
(
defaultValue
)
{
return
[
new
Date
(
defaultValue
),
nextDate
(
new
Date
(
defaultValue
),
1
)];
}
else
{
return
[
new
Date
(),
nextDate
(
new
Date
(),
1
)];
}
};
export
default
{
mixins
:
[
Locale
],
directives
:
{
Clickoutside
},
computed
:
{
btnDisabled
()
{
return
!
(
this
.
minDate
&&
this
.
maxDate
&&
!
this
.
selecting
&&
this
.
isValidValue
([
this
.
minDate
,
this
.
maxDate
])
);
},
leftLabel
()
{
return
(
this
.
leftDate
.
getFullYear
()
+
"
"
+
this
.
t
(
"
el.datepicker.year
"
)
+
"
"
+
this
.
t
(
`el.datepicker.month
${
this
.
leftDate
.
getMonth
()
+
1
}
`
)
);
},
rightLabel
()
{
return
(
this
.
rightDate
.
getFullYear
()
+
"
"
+
this
.
t
(
"
el.datepicker.year
"
)
+
"
"
+
this
.
t
(
`el.datepicker.month
${
this
.
rightDate
.
getMonth
()
+
1
}
`
)
);
},
leftYear
()
{
return
this
.
leftDate
.
getFullYear
();
},
leftMonth
()
{
return
this
.
leftDate
.
getMonth
();
},
leftMonthDate
()
{
return
this
.
leftDate
.
getDate
();
},
rightYear
()
{
return
this
.
rightDate
.
getFullYear
();
},
rightMonth
()
{
return
this
.
rightDate
.
getMonth
();
},
rightMonthDate
()
{
return
this
.
rightDate
.
getDate
();
},
minVisibleDate
()
{
if
(
this
.
dateUserInput
.
min
!==
null
)
return
this
.
dateUserInput
.
min
;
if
(
this
.
minDate
)
return
formatDate
(
this
.
minDate
,
this
.
dateFormat
);
return
""
;
},
maxVisibleDate
()
{
if
(
this
.
dateUserInput
.
max
!==
null
)
return
this
.
dateUserInput
.
max
;
if
(
this
.
maxDate
||
this
.
minDate
)
return
formatDate
(
this
.
maxDate
||
this
.
minDate
,
this
.
dateFormat
);
return
""
;
},
minVisibleTime
()
{
if
(
this
.
timeUserInput
.
min
!==
null
)
return
this
.
timeUserInput
.
min
;
if
(
this
.
minDate
)
return
formatDate
(
this
.
minDate
,
this
.
timeFormat
);
return
""
;
},
maxVisibleTime
()
{
if
(
this
.
timeUserInput
.
max
!==
null
)
return
this
.
timeUserInput
.
max
;
if
(
this
.
maxDate
||
this
.
minDate
)
return
formatDate
(
this
.
maxDate
||
this
.
minDate
,
this
.
timeFormat
);
return
""
;
},
timeFormat
()
{
if
(
this
.
format
)
{
return
extractTimeFormat
(
this
.
format
);
}
else
{
return
"
HH:mm:ss
"
;
}
},
dateFormat
()
{
if
(
this
.
format
)
{
return
extractDateFormat
(
this
.
format
);
}
else
{
return
"
yyyy-MM-dd
"
;
}
},
enableMonthArrow
()
{
const
nextMonth
=
(
this
.
leftMonth
+
1
)
%
12
;
const
yearOffset
=
this
.
leftMonth
+
1
>=
12
?
1
:
0
;
return
(
this
.
unlinkPanels
&&
new
Date
(
this
.
leftYear
+
yearOffset
,
nextMonth
)
<
new
Date
(
this
.
rightYear
,
this
.
rightMonth
)
);
},
enableYearArrow
()
{
return
(
this
.
unlinkPanels
&&
this
.
rightYear
*
12
+
this
.
rightMonth
-
(
this
.
leftYear
*
12
+
this
.
leftMonth
+
1
)
>=
12
);
},
},
data
()
{
return
{
popperClass
:
""
,
value
:
[],
defaultValue
:
null
,
defaultTime
:
null
,
minDate
:
""
,
maxDate
:
""
,
leftDate
:
new
Date
(),
rightDate
:
nextMonth
(
new
Date
()),
rangeState
:
{
endDate
:
null
,
selecting
:
false
,
row
:
null
,
column
:
null
,
},
showTime
:
false
,
shortcuts
:
""
,
visible
:
""
,
disabledDate
:
""
,
cellClassName
:
""
,
firstDayOfWeek
:
7
,
minTimePickerVisible
:
false
,
maxTimePickerVisible
:
false
,
format
:
""
,
arrowControl
:
false
,
unlinkPanels
:
false
,
dateUserInput
:
{
min
:
null
,
max
:
null
,
},
timeUserInput
:
{
min
:
null
,
max
:
null
,
},
};
},
watch
:
{
minDate
(
val
)
{
this
.
dateUserInput
.
min
=
null
;
this
.
timeUserInput
.
min
=
null
;
this
.
$nextTick
(()
=>
{
if
(
this
.
$refs
.
maxTimePicker
&&
this
.
maxDate
&&
this
.
maxDate
<
this
.
minDate
)
{
const
format
=
"
HH:mm:ss
"
;
this
.
$refs
.
maxTimePicker
.
selectableRange
=
[
[
parseDate
(
formatDate
(
this
.
minDate
,
format
),
format
),
parseDate
(
"
23:59:59
"
,
format
),
],
];
}
});
if
(
val
&&
this
.
$refs
.
minTimePicker
)
{
this
.
$refs
.
minTimePicker
.
date
=
val
;
this
.
$refs
.
minTimePicker
.
value
=
val
;
}
},
maxDate
(
val
)
{
this
.
dateUserInput
.
max
=
null
;
this
.
timeUserInput
.
max
=
null
;
if
(
val
&&
this
.
$refs
.
maxTimePicker
)
{
this
.
$refs
.
maxTimePicker
.
date
=
val
;
this
.
$refs
.
maxTimePicker
.
value
=
val
;
}
},
minTimePickerVisible
(
val
)
{
if
(
val
)
{
this
.
$nextTick
(()
=>
{
this
.
$refs
.
minTimePicker
.
date
=
this
.
minDate
;
this
.
$refs
.
minTimePicker
.
value
=
this
.
minDate
;
this
.
$refs
.
minTimePicker
.
adjustSpinners
();
});
}
},
maxTimePickerVisible
(
val
)
{
if
(
val
)
{
this
.
$nextTick
(()
=>
{
this
.
$refs
.
maxTimePicker
.
date
=
this
.
maxDate
;
this
.
$refs
.
maxTimePicker
.
value
=
this
.
maxDate
;
this
.
$refs
.
maxTimePicker
.
adjustSpinners
();
});
}
},
value
(
newVal
)
{
if
(
!
newVal
)
{
this
.
minDate
=
null
;
this
.
maxDate
=
null
;
}
else
if
(
Array
.
isArray
(
newVal
))
{
this
.
minDate
=
isDate
(
newVal
[
0
])
?
new
Date
(
newVal
[
0
])
:
null
;
this
.
maxDate
=
isDate
(
newVal
[
1
])
?
new
Date
(
newVal
[
1
])
:
null
;
if
(
this
.
minDate
)
{
this
.
leftDate
=
this
.
minDate
;
if
(
this
.
unlinkPanels
&&
this
.
maxDate
)
{
const
minDateYear
=
this
.
minDate
.
getFullYear
();
const
minDateMonth
=
this
.
minDate
.
getMonth
();
const
maxDateYear
=
this
.
maxDate
.
getFullYear
();
const
maxDateMonth
=
this
.
maxDate
.
getMonth
();
this
.
rightDate
=
minDateYear
===
maxDateYear
&&
minDateMonth
===
maxDateMonth
?
nextMonth
(
this
.
maxDate
)
:
this
.
maxDate
;
}
else
{
this
.
rightDate
=
nextMonth
(
this
.
leftDate
);
}
}
else
{
this
.
leftDate
=
calcDefaultValue
(
this
.
defaultValue
)[
0
];
this
.
rightDate
=
nextMonth
(
this
.
leftDate
);
}
}
},
defaultValue
(
val
)
{
if
(
!
Array
.
isArray
(
this
.
value
))
{
const
[
left
,
right
]
=
calcDefaultValue
(
val
);
this
.
leftDate
=
left
;
this
.
rightDate
=
val
&&
val
[
1
]
&&
this
.
unlinkPanels
?
right
:
nextMonth
(
this
.
leftDate
);
}
},
},
methods
:
{
handleClear
()
{
this
.
minDate
=
null
;
this
.
maxDate
=
null
;
this
.
leftDate
=
calcDefaultValue
(
this
.
defaultValue
)[
0
];
this
.
rightDate
=
nextMonth
(
this
.
leftDate
);
this
.
$emit
(
"
pick
"
,
null
);
},
handleChangeRange
(
val
)
{
this
.
minDate
=
val
.
minDate
;
this
.
maxDate
=
val
.
maxDate
;
this
.
rangeState
=
val
.
rangeState
;
},
handleDateInput
(
value
,
type
)
{
this
.
dateUserInput
[
type
]
=
value
;
if
(
value
.
length
!==
this
.
dateFormat
.
length
)
return
;
const
parsedValue
=
parseDate
(
value
,
this
.
dateFormat
);
if
(
parsedValue
)
{
if
(
typeof
this
.
disabledDate
===
"
function
"
&&
this
.
disabledDate
(
new
Date
(
parsedValue
))
)
{
return
;
}
if
(
type
===
"
min
"
)
{
this
.
minDate
=
modifyDate
(
this
.
minDate
||
new
Date
(),
parsedValue
.
getFullYear
(),
parsedValue
.
getMonth
(),
parsedValue
.
getDate
()
);
this
.
leftDate
=
new
Date
(
parsedValue
);
if
(
!
this
.
unlinkPanels
)
{
this
.
rightDate
=
nextMonth
(
this
.
leftDate
);
}
}
else
{
this
.
maxDate
=
modifyDate
(
this
.
maxDate
||
new
Date
(),
parsedValue
.
getFullYear
(),
parsedValue
.
getMonth
(),
parsedValue
.
getDate
()
);
this
.
rightDate
=
new
Date
(
parsedValue
);
if
(
!
this
.
unlinkPanels
)
{
this
.
leftDate
=
prevMonth
(
parsedValue
);
}
}
}
},
handleDateChange
(
value
,
type
)
{
const
parsedValue
=
parseDate
(
value
,
this
.
dateFormat
);
if
(
parsedValue
)
{
if
(
type
===
"
min
"
)
{
this
.
minDate
=
modifyDate
(
this
.
minDate
,
parsedValue
.
getFullYear
(),
parsedValue
.
getMonth
(),
parsedValue
.
getDate
()
);
if
(
this
.
minDate
>
this
.
maxDate
)
{
this
.
maxDate
=
this
.
minDate
;
}
}
else
{
this
.
maxDate
=
modifyDate
(
this
.
maxDate
,
parsedValue
.
getFullYear
(),
parsedValue
.
getMonth
(),
parsedValue
.
getDate
()
);
if
(
this
.
maxDate
<
this
.
minDate
)
{
this
.
minDate
=
this
.
maxDate
;
}
}
}
},
handleTimeInput
(
value
,
type
)
{
this
.
timeUserInput
[
type
]
=
value
;
if
(
value
.
length
!==
this
.
timeFormat
.
length
)
return
;
const
parsedValue
=
parseDate
(
value
,
this
.
timeFormat
);
if
(
parsedValue
)
{
if
(
type
===
"
min
"
)
{
this
.
minDate
=
modifyTime
(
this
.
minDate
,
parsedValue
.
getHours
(),
parsedValue
.
getMinutes
(),
parsedValue
.
getSeconds
()
);
this
.
$nextTick
((
_
)
=>
this
.
$refs
.
minTimePicker
.
adjustSpinners
());
}
else
{
this
.
maxDate
=
modifyTime
(
this
.
maxDate
,
parsedValue
.
getHours
(),
parsedValue
.
getMinutes
(),
parsedValue
.
getSeconds
()
);
this
.
$nextTick
((
_
)
=>
this
.
$refs
.
maxTimePicker
.
adjustSpinners
());
}
}
},
handleTimeChange
(
value
,
type
)
{
const
parsedValue
=
parseDate
(
value
,
this
.
timeFormat
);
if
(
parsedValue
)
{
if
(
type
===
"
min
"
)
{
this
.
minDate
=
modifyTime
(
this
.
minDate
,
parsedValue
.
getHours
(),
parsedValue
.
getMinutes
(),
parsedValue
.
getSeconds
()
);
if
(
this
.
minDate
>
this
.
maxDate
)
{
this
.
maxDate
=
this
.
minDate
;
}
this
.
$refs
.
minTimePicker
.
value
=
this
.
minDate
;
this
.
minTimePickerVisible
=
false
;
}
else
{
this
.
maxDate
=
modifyTime
(
this
.
maxDate
,
parsedValue
.
getHours
(),
parsedValue
.
getMinutes
(),
parsedValue
.
getSeconds
()
);
if
(
this
.
maxDate
<
this
.
minDate
)
{
this
.
minDate
=
this
.
maxDate
;
}
this
.
$refs
.
maxTimePicker
.
value
=
this
.
minDate
;
this
.
maxTimePickerVisible
=
false
;
}
}
},
handleRangePick
(
val
,
close
=
true
)
{
const
defaultTime
=
this
.
defaultTime
||
[];
const
minDate
=
modifyWithTimeString
(
val
.
minDate
,
defaultTime
[
0
]);
const
maxDate
=
modifyWithTimeString
(
val
.
maxDate
,
defaultTime
[
1
]);
if
(
this
.
maxDate
===
maxDate
&&
this
.
minDate
===
minDate
)
{
return
;
}
this
.
onPick
&&
this
.
onPick
(
val
);
this
.
maxDate
=
maxDate
;
this
.
minDate
=
minDate
;
// workaround for https://github.com/ElemeFE/element/issues/7539, should remove this block when we don't have to care about Chromium 55 - 57
setTimeout
(()
=>
{
this
.
maxDate
=
maxDate
;
this
.
minDate
=
minDate
;
},
10
);
if
(
!
close
||
this
.
showTime
)
return
;
this
.
handleConfirm
();
},
handleShortcutClick
(
shortcut
)
{
if
(
shortcut
.
onClick
)
{
shortcut
.
onClick
(
this
);
}
},
handleMinTimePick
(
value
,
visible
,
first
)
{
this
.
minDate
=
this
.
minDate
||
new
Date
();
if
(
value
)
{
this
.
minDate
=
modifyTime
(
this
.
minDate
,
value
.
getHours
(),
value
.
getMinutes
(),
value
.
getSeconds
()
);
}
if
(
!
first
)
{
this
.
minTimePickerVisible
=
visible
;
}
if
(
!
this
.
maxDate
||
(
this
.
maxDate
&&
this
.
maxDate
.
getTime
()
<
this
.
minDate
.
getTime
())
)
{
this
.
maxDate
=
new
Date
(
this
.
minDate
);
}
},
handleMinTimeClose
()
{
this
.
minTimePickerVisible
=
false
;
},
handleMaxTimePick
(
value
,
visible
,
first
)
{
if
(
this
.
maxDate
&&
value
)
{
this
.
maxDate
=
modifyTime
(
this
.
maxDate
,
value
.
getHours
(),
value
.
getMinutes
(),
value
.
getSeconds
()
);
}
if
(
!
first
)
{
this
.
maxTimePickerVisible
=
visible
;
}
if
(
this
.
maxDate
&&
this
.
minDate
&&
this
.
minDate
.
getTime
()
>
this
.
maxDate
.
getTime
()
)
{
this
.
minDate
=
new
Date
(
this
.
maxDate
);
}
},
handleMaxTimeClose
()
{
this
.
maxTimePickerVisible
=
false
;
},
// leftPrev*, rightNext* need to take care of `unlinkPanels`
leftPrevYear
()
{
this
.
leftDate
=
prevYear
(
this
.
leftDate
);
if
(
!
this
.
unlinkPanels
)
{
this
.
rightDate
=
nextMonth
(
this
.
leftDate
);
}
},
leftPrevMonth
()
{
this
.
leftDate
=
prevMonth
(
this
.
leftDate
);
if
(
!
this
.
unlinkPanels
)
{
this
.
rightDate
=
nextMonth
(
this
.
leftDate
);
}
},
rightNextYear
()
{
if
(
!
this
.
unlinkPanels
)
{
this
.
leftDate
=
nextYear
(
this
.
leftDate
);
this
.
rightDate
=
nextMonth
(
this
.
leftDate
);
}
else
{
this
.
rightDate
=
nextYear
(
this
.
rightDate
);
}
},
rightNextMonth
()
{
if
(
!
this
.
unlinkPanels
)
{
this
.
leftDate
=
nextMonth
(
this
.
leftDate
);
this
.
rightDate
=
nextMonth
(
this
.
leftDate
);
}
else
{
this
.
rightDate
=
nextMonth
(
this
.
rightDate
);
}
},
// leftNext*, rightPrev* are called when `unlinkPanels` is true
leftNextYear
()
{
this
.
leftDate
=
nextYear
(
this
.
leftDate
);
},
leftNextMonth
()
{
this
.
leftDate
=
nextMonth
(
this
.
leftDate
);
},
rightPrevYear
()
{
this
.
rightDate
=
prevYear
(
this
.
rightDate
);
},
rightPrevMonth
()
{
this
.
rightDate
=
prevMonth
(
this
.
rightDate
);
},
handleConfirm
(
visible
=
false
)
{
if
(
this
.
isValidValue
([
this
.
minDate
,
this
.
maxDate
]))
{
this
.
$emit
(
"
pick
"
,
[
this
.
minDate
,
this
.
maxDate
],
visible
);
}
},
isValidValue
(
value
)
{
return
(
Array
.
isArray
(
value
)
&&
value
&&
value
[
0
]
&&
value
[
1
]
&&
isDate
(
value
[
0
])
&&
isDate
(
value
[
1
])
&&
value
[
0
].
getTime
()
<=
value
[
1
].
getTime
()
&&
(
typeof
this
.
disabledDate
===
"
function
"
?
!
this
.
disabledDate
(
value
[
0
])
&&
!
this
.
disabledDate
(
value
[
1
])
:
true
)
);
},
resetView
()
{
// NOTE: this is a hack to reset {min, max}Date on picker open.
// TODO: correct way of doing so is to refactor {min, max}Date to be dependent on value and internal selection state
// an alternative would be resetView whenever picker becomes visible, should also investigate date-panel's resetView
if
(
this
.
minDate
&&
this
.
maxDate
==
null
)
this
.
rangeState
.
selecting
=
false
;
this
.
minDate
=
this
.
value
&&
isDate
(
this
.
value
[
0
])
?
new
Date
(
this
.
value
[
0
])
:
null
;
this
.
maxDate
=
this
.
value
&&
isDate
(
this
.
value
[
0
])
?
new
Date
(
this
.
value
[
1
])
:
null
;
},
},
components
:
{
TimePicker
,
DateTable
,
ElInput
,
ElButton
},
};
</
script
>
admin_2/src/components/YDatePickerTab/date-picker/src/panel/date.vue
0 → 100644
View file @
6f2cf656
<
template
>
<transition
name=
"el-zoom-in-top"
@
after-enter=
"handleEnter"
@
after-leave=
"handleLeave"
>
<div
v-show=
"visible"
class=
"el-picker-panel el-date-picker el-popper"
:class=
"[
{
'has-sidebar': $slots.sidebar || shortcuts,
'has-time': showTime,
},
popperClass,
]"
>
<div
class=
"el-picker-panel__body-wrapper"
>
<slot
name=
"sidebar"
class=
"el-picker-panel__sidebar"
></slot>
<div
class=
"el-picker-panel__sidebar"
v-if=
"shortcuts"
>
<button
type=
"button"
class=
"el-picker-panel__shortcut"
v-for=
"(shortcut, key) in shortcuts"
:key=
"key"
@
click=
"handleShortcutClick(shortcut)"
>
{{
shortcut
.
text
}}
</button>
</div>
<div
class=
"el-picker-panel__body"
>
<div
class=
"el-date-picker__time-header"
v-if=
"showTime"
>
<span
class=
"el-date-picker__editor-wrap"
>
<el-input
:placeholder=
"t('el.datepicker.selectDate')"
:value=
"visibleDate"
size=
"small"
@
input=
"(val) => (userInputDate = val)"
@
change=
"handleVisibleDateChange"
/>
</span>
<span
class=
"el-date-picker__editor-wrap"
v-clickoutside=
"handleTimePickClose"
>
<el-input
ref=
"input"
@
focus=
"timePickerVisible = true"
:placeholder=
"t('el.datepicker.selectTime')"
:value=
"visibleTime"
size=
"small"
@
input=
"(val) => (userInputTime = val)"
@
change=
"handleVisibleTimeChange"
/>
<time-picker
ref=
"timepicker"
:time-arrow-control=
"arrowControl"
@
pick=
"handleTimePick"
:visible=
"timePickerVisible"
@
mounted=
"proxyTimePickerDataProperties"
>
</time-picker>
</span>
</div>
<div
class=
"el-date-picker__header"
:class=
"
{
'el-date-picker__header--bordered':
currentView === 'year' || currentView === 'month',
}"
v-show="currentView !== 'time'"
>
<button
type=
"button"
@
click=
"prevYear"
:aria-label=
"t(`el.datepicker.prevYear`)"
class=
"el-picker-panel__icon-btn el-date-picker__prev-btn el-icon-d-arrow-left"
></button>
<button
type=
"button"
@
click=
"prevMonth"
v-show=
"currentView === 'date'"
:aria-label=
"t(`el.datepicker.prevMonth`)"
class=
"el-picker-panel__icon-btn el-date-picker__prev-btn el-icon-arrow-left"
></button>
<span
@
click=
"showYearPicker"
role=
"button"
class=
"el-date-picker__header-label"
>
{{
yearLabel
}}
</span
>
<span
@
click=
"showMonthPicker"
v-show=
"currentView === 'date'"
role=
"button"
class=
"el-date-picker__header-label"
:class=
"
{ active: currentView === 'month' }"
>
{{
t
(
`el.datepicker.month${month + 1
}
`
)
}}
<
/spa
n
>
<
button
type
=
"
button
"
@
click
=
"
nextYear
"
:
aria
-
label
=
"
t(`el.datepicker.nextYear`)
"
class
=
"
el-picker-panel__icon-btn el-date-picker__next-btn el-icon-d-arrow-right
"
><
/button
>
<
button
type
=
"
button
"
@
click
=
"
nextMonth
"
v
-
show
=
"
currentView === 'date'
"
:
aria
-
label
=
"
t(`el.datepicker.nextMonth`)
"
class
=
"
el-picker-panel__icon-btn el-date-picker__next-btn el-icon-arrow-right
"
><
/button
>
<
/div
>
<
div
class
=
"
el-picker-panel__content
"
>
<
date
-
table
v
-
show
=
"
currentView === 'date'
"
@
pick
=
"
handleDatePick
"
:
selection
-
mode
=
"
selectionMode
"
:
first
-
day
-
of
-
week
=
"
firstDayOfWeek
"
:
value
=
"
value
"
:
default
-
value
=
"
defaultValue ? new Date(defaultValue) : null
"
:
date
=
"
date
"
:
cell
-
class
-
name
=
"
cellClassName
"
:
disabled
-
date
=
"
disabledDate
"
>
<
/date-table
>
<
year
-
table
v
-
show
=
"
currentView === 'year'
"
@
pick
=
"
handleYearPick
"
:
selection
-
mode
=
"
selectionMode
"
:
value
=
"
value
"
:
default
-
value
=
"
defaultValue ? new Date(defaultValue) : null
"
:
date
=
"
date
"
:
disabled
-
date
=
"
disabledDate
"
>
<
/year-table
>
<
month
-
table
v
-
show
=
"
currentView === 'month'
"
@
pick
=
"
handleMonthPick
"
:
selection
-
mode
=
"
selectionMode
"
:
value
=
"
value
"
:
default
-
value
=
"
defaultValue ? new Date(defaultValue) : null
"
:
date
=
"
date
"
:
disabled
-
date
=
"
disabledDate
"
>
<
/month-table
>
<
/div
>
<
/div
>
<
/div
>
<
div
class
=
"
el-picker-panel__footer
"
v
-
show
=
"
footerVisible &&
(currentView === 'date' ||
currentView === 'month' ||
currentView === 'year')
"
>
<
el
-
button
size
=
"
mini
"
type
=
"
text
"
class
=
"
el-picker-panel__link-btn
"
@
click
=
"
changeToNow
"
v
-
show
=
"
selectionMode !== 'dates' &&
selectionMode !== 'months' &&
selectionMode !== 'years'
"
>
{{
t
(
"
el.datepicker.now
"
)
}}
<
/el-button
>
<
el
-
button
plain
size
=
"
mini
"
class
=
"
el-picker-panel__link-btn
"
@
click
=
"
confirm
"
>
{{
t
(
"
el.datepicker.confirm
"
)
}}
<
/el-button
>
<
/div
>
<
/div
>
<
/transition
>
<
/template
>
<
script
type
=
"
text/babel
"
>
/* eslint-disable */
import
{
formatDate
,
parseDate
,
getWeekNumber
,
isDate
,
modifyDate
,
modifyTime
,
modifyWithTimeString
,
clearMilliseconds
,
clearTime
,
prevYear
,
nextYear
,
prevMonth
,
nextMonth
,
changeYearMonthAndClampDate
,
extractDateFormat
,
extractTimeFormat
,
timeWithinRange
,
}
from
"
element-ui/src/utils/date-util
"
;
import
Clickoutside
from
"
element-ui/src/utils/clickoutside
"
;
import
Locale
from
"
element-ui/src/mixins/locale
"
;
import
ElInput
from
"
element-ui/packages/input
"
;
import
ElButton
from
"
element-ui/packages/button
"
;
import
TimePicker
from
"
./time
"
;
import
YearTable
from
"
../basic/year-table
"
;
import
MonthTable
from
"
../basic/month-table
"
;
import
DateTable
from
"
../basic/date-table
"
;
export
default
{
mixins
:
[
Locale
],
directives
:
{
Clickoutside
}
,
watch
:
{
showTime
(
val
)
{
/* istanbul ignore if */
if
(
!
val
)
return
;
this
.
$nextTick
((
_
)
=>
{
const
inputElm
=
this
.
$refs
.
input
.
$el
;
if
(
inputElm
)
{
this
.
pickerWidth
=
inputElm
.
getBoundingClientRect
().
width
+
10
;
}
}
);
}
,
value
(
val
)
{
if
(
this
.
selectionMode
===
"
dates
"
&&
this
.
value
)
return
;
if
(
this
.
selectionMode
===
"
months
"
&&
this
.
value
)
return
;
if
(
this
.
selectionMode
===
"
years
"
&&
this
.
value
)
return
;
if
(
isDate
(
val
))
{
this
.
date
=
new
Date
(
val
);
}
else
{
this
.
date
=
this
.
getDefaultValue
();
}
}
,
defaultValue
(
val
)
{
if
(
!
isDate
(
this
.
value
))
{
this
.
date
=
val
?
new
Date
(
val
)
:
new
Date
();
}
}
,
timePickerVisible
(
val
)
{
if
(
val
)
this
.
$nextTick
(()
=>
this
.
$refs
.
timepicker
.
adjustSpinners
());
}
,
selectionMode
(
newVal
)
{
if
(
newVal
===
"
month
"
)
{
/* istanbul ignore next */
if
(
this
.
currentView
!==
"
year
"
||
this
.
currentView
!==
"
month
"
)
{
this
.
currentView
=
"
month
"
;
}
}
else
if
(
newVal
===
"
dates
"
)
{
this
.
currentView
=
"
date
"
;
}
else
if
(
newVal
===
"
years
"
)
{
this
.
currentView
=
"
year
"
;
}
else
if
(
newVal
===
"
months
"
)
{
this
.
currentView
=
"
month
"
;
}
}
,
}
,
methods
:
{
proxyTimePickerDataProperties
()
{
const
format
=
(
timeFormat
)
=>
{
this
.
$refs
.
timepicker
.
format
=
timeFormat
;
}
;
const
value
=
(
value
)
=>
{
this
.
$refs
.
timepicker
.
value
=
value
;
}
;
const
date
=
(
date
)
=>
{
this
.
$refs
.
timepicker
.
date
=
date
;
}
;
const
selectableRange
=
(
selectableRange
)
=>
{
this
.
$refs
.
timepicker
.
selectableRange
=
selectableRange
;
}
;
this
.
$watch
(
"
value
"
,
value
);
this
.
$watch
(
"
date
"
,
date
);
this
.
$watch
(
"
selectableRange
"
,
selectableRange
);
format
(
this
.
timeFormat
);
value
(
this
.
value
);
date
(
this
.
date
);
selectableRange
(
this
.
selectableRange
);
}
,
handleClear
()
{
this
.
date
=
this
.
getDefaultValue
();
this
.
$emit
(
"
pick
"
,
null
);
}
,
emit
(
value
,
...
args
)
{
if
(
!
value
)
{
this
.
$emit
(
"
pick
"
,
value
,
...
args
);
}
else
if
(
Array
.
isArray
(
value
))
{
const
dates
=
value
.
map
((
date
)
=>
this
.
showTime
?
clearMilliseconds
(
date
)
:
clearTime
(
date
)
);
this
.
$emit
(
"
pick
"
,
dates
,
...
args
);
}
else
{
this
.
$emit
(
"
pick
"
,
this
.
showTime
?
clearMilliseconds
(
value
)
:
clearTime
(
value
),
...
args
);
}
this
.
userInputDate
=
null
;
this
.
userInputTime
=
null
;
}
,
// resetDate()
{
// this.date = new Date(this.date);
//
}
,
showMonthPicker
()
{
this
.
currentView
=
"
month
"
;
}
,
showYearPicker
()
{
this
.
currentView
=
"
year
"
;
}
,
// XXX: 没用到
// handleLabelClick()
{
// if (this.currentView === 'date')
{
// this.showMonthPicker();
//
}
else
if
(
this
.
currentView
===
'
month
'
)
{
// this.showYearPicker();
//
}
//
}
,
prevMonth
()
{
this
.
date
=
prevMonth
(
this
.
date
);
}
,
nextMonth
()
{
this
.
date
=
nextMonth
(
this
.
date
);
}
,
prevYear
()
{
if
(
this
.
currentView
===
"
year
"
)
{
this
.
date
=
prevYear
(
this
.
date
,
10
);
}
else
{
this
.
date
=
prevYear
(
this
.
date
);
}
}
,
nextYear
()
{
if
(
this
.
currentView
===
"
year
"
)
{
this
.
date
=
nextYear
(
this
.
date
,
10
);
}
else
{
this
.
date
=
nextYear
(
this
.
date
);
}
}
,
handleShortcutClick
(
shortcut
)
{
if
(
shortcut
.
onClick
)
{
shortcut
.
onClick
(
this
);
}
}
,
handleTimePick
(
value
,
visible
,
first
)
{
if
(
isDate
(
value
))
{
const
newDate
=
this
.
value
?
modifyTime
(
this
.
value
,
value
.
getHours
(),
value
.
getMinutes
(),
value
.
getSeconds
()
)
:
modifyWithTimeString
(
this
.
getDefaultValue
(),
this
.
defaultTime
);
this
.
date
=
newDate
;
this
.
emit
(
this
.
date
,
true
);
}
else
{
this
.
emit
(
value
,
true
);
}
if
(
!
first
)
{
this
.
timePickerVisible
=
visible
;
}
}
,
handleTimePickClose
()
{
this
.
timePickerVisible
=
false
;
}
,
handleMonthPick
(
month
)
{
if
(
this
.
selectionMode
===
"
month
"
)
{
this
.
date
=
modifyDate
(
this
.
date
,
this
.
year
,
month
,
1
);
this
.
emit
(
this
.
date
);
}
else
if
(
this
.
selectionMode
===
"
months
"
)
{
this
.
emit
(
month
,
true
);
}
else
{
this
.
date
=
changeYearMonthAndClampDate
(
this
.
date
,
this
.
year
,
month
);
// TODO: should emit intermediate value ??
// this.emit(this.date);
this
.
currentView
=
"
date
"
;
}
}
,
handleDatePick
(
value
)
{
if
(
this
.
selectionMode
===
"
day
"
)
{
let
newDate
=
this
.
value
?
modifyDate
(
this
.
value
,
value
.
getFullYear
(),
value
.
getMonth
(),
value
.
getDate
()
)
:
modifyWithTimeString
(
value
,
this
.
defaultTime
);
// change default time while out of selectableRange
if
(
!
this
.
checkDateWithinRange
(
newDate
))
{
newDate
=
modifyDate
(
this
.
selectableRange
[
0
][
0
],
value
.
getFullYear
(),
value
.
getMonth
(),
value
.
getDate
()
);
}
this
.
date
=
newDate
;
this
.
emit
(
this
.
date
,
this
.
showTime
);
}
else
if
(
this
.
selectionMode
===
"
week
"
)
{
this
.
emit
(
value
.
date
);
}
else
if
(
this
.
selectionMode
===
"
dates
"
)
{
this
.
emit
(
value
,
true
);
// set false to keep panel open
}
}
,
handleYearPick
(
year
)
{
if
(
this
.
selectionMode
===
"
year
"
)
{
this
.
date
=
modifyDate
(
this
.
date
,
year
,
0
,
1
);
this
.
emit
(
this
.
date
);
}
else
if
(
this
.
selectionMode
===
"
years
"
)
{
this
.
emit
(
year
,
true
);
}
else
{
this
.
date
=
changeYearMonthAndClampDate
(
this
.
date
,
year
,
this
.
month
);
// TODO: should emit intermediate value ??
// this.emit(this.date, true);
this
.
currentView
=
"
month
"
;
}
}
,
changeToNow
()
{
// NOTE: not a permanent solution
// consider disable "now" button in the future
if
(
(
!
this
.
disabledDate
||
!
this
.
disabledDate
(
new
Date
()))
&&
this
.
checkDateWithinRange
(
new
Date
())
)
{
this
.
date
=
new
Date
();
this
.
emit
(
this
.
date
);
}
}
,
confirm
()
{
if
(
this
.
selectionMode
===
"
dates
"
||
this
.
selectionMode
===
"
months
"
||
this
.
selectionMode
===
"
years
"
)
{
this
.
emit
(
this
.
value
);
}
else
{
// value were emitted in handle
{
Date
,
Time
}
Pick
,
nothing
to
update
here
// deal with the scenario where: user opens the picker, then confirm without doing anything
const
value
=
this
.
value
?
this
.
value
:
modifyWithTimeString
(
this
.
getDefaultValue
(),
this
.
defaultTime
);
this
.
date
=
new
Date
(
value
);
// refresh date
this
.
emit
(
value
);
}
}
,
resetView
()
{
if
(
this
.
selectionMode
===
"
month
"
||
this
.
selectionMode
===
"
months
"
)
{
this
.
currentView
=
"
month
"
;
}
else
if
(
this
.
selectionMode
===
"
year
"
||
this
.
selectionMode
===
"
years
"
)
{
this
.
currentView
=
"
year
"
;
}
else
{
this
.
currentView
=
"
date
"
;
}
}
,
handleEnter
()
{
document
.
body
.
addEventListener
(
"
keydown
"
,
this
.
handleKeydown
);
}
,
handleLeave
()
{
this
.
$emit
(
"
dodestroy
"
);
document
.
body
.
removeEventListener
(
"
keydown
"
,
this
.
handleKeydown
);
}
,
handleKeydown
(
event
)
{
const
keyCode
=
event
.
keyCode
;
const
list
=
[
38
,
40
,
37
,
39
];
if
(
this
.
visible
&&
!
this
.
timePickerVisible
)
{
if
(
list
.
indexOf
(
keyCode
)
!==
-
1
)
{
this
.
handleKeyControl
(
keyCode
);
event
.
stopPropagation
();
event
.
preventDefault
();
}
if
(
keyCode
===
13
&&
this
.
userInputDate
===
null
&&
this
.
userInputTime
===
null
)
{
// Enter
this
.
emit
(
this
.
date
,
false
);
}
}
}
,
handleKeyControl
(
keyCode
)
{
const
mapping
=
{
year
:
{
38
:
-
4
,
40
:
4
,
37
:
-
1
,
39
:
1
,
offset
:
(
date
,
step
)
=>
date
.
setFullYear
(
date
.
getFullYear
()
+
step
),
}
,
month
:
{
38
:
-
4
,
40
:
4
,
37
:
-
1
,
39
:
1
,
offset
:
(
date
,
step
)
=>
date
.
setMonth
(
date
.
getMonth
()
+
step
),
}
,
week
:
{
38
:
-
1
,
40
:
1
,
37
:
-
1
,
39
:
1
,
offset
:
(
date
,
step
)
=>
date
.
setDate
(
date
.
getDate
()
+
step
*
7
),
}
,
day
:
{
38
:
-
7
,
40
:
7
,
37
:
-
1
,
39
:
1
,
offset
:
(
date
,
step
)
=>
date
.
setDate
(
date
.
getDate
()
+
step
),
}
,
}
;
const
mode
=
this
.
selectionMode
;
const
year
=
3.1536e10
;
const
now
=
this
.
date
.
getTime
();
const
newDate
=
new
Date
(
this
.
date
.
getTime
());
while
(
Math
.
abs
(
now
-
newDate
.
getTime
())
<=
year
)
{
const
map
=
mapping
[
mode
];
map
.
offset
(
newDate
,
map
[
keyCode
]);
if
(
typeof
this
.
disabledDate
===
"
function
"
&&
this
.
disabledDate
(
newDate
)
)
{
continue
;
}
this
.
date
=
newDate
;
this
.
$emit
(
"
pick
"
,
newDate
,
true
);
break
;
}
}
,
handleVisibleTimeChange
(
value
)
{
const
time
=
parseDate
(
value
,
this
.
timeFormat
);
if
(
time
&&
this
.
checkDateWithinRange
(
time
))
{
this
.
date
=
modifyDate
(
time
,
this
.
year
,
this
.
month
,
this
.
monthDate
);
this
.
userInputTime
=
null
;
this
.
$refs
.
timepicker
.
value
=
this
.
date
;
this
.
timePickerVisible
=
false
;
this
.
emit
(
this
.
date
,
true
);
}
}
,
handleVisibleDateChange
(
value
)
{
const
date
=
parseDate
(
value
,
this
.
dateFormat
);
if
(
date
)
{
if
(
typeof
this
.
disabledDate
===
"
function
"
&&
this
.
disabledDate
(
date
)
)
{
return
;
}
this
.
date
=
modifyTime
(
date
,
this
.
date
.
getHours
(),
this
.
date
.
getMinutes
(),
this
.
date
.
getSeconds
()
);
this
.
userInputDate
=
null
;
this
.
resetView
();
this
.
emit
(
this
.
date
,
true
);
}
}
,
isValidValue
(
value
)
{
return
(
value
&&
!
isNaN
(
value
)
&&
(
typeof
this
.
disabledDate
===
"
function
"
?
!
this
.
disabledDate
(
value
)
:
true
)
&&
this
.
checkDateWithinRange
(
value
)
);
}
,
getDefaultValue
()
{
// if default-value is set, return it
// otherwise, return now (the moment this method gets called)
return
this
.
defaultValue
?
new
Date
(
this
.
defaultValue
)
:
new
Date
();
}
,
checkDateWithinRange
(
date
)
{
return
this
.
selectableRange
.
length
>
0
?
timeWithinRange
(
date
,
this
.
selectableRange
,
this
.
format
||
"
HH:mm:ss
"
)
:
true
;
}
,
}
,
components
:
{
TimePicker
,
YearTable
,
MonthTable
,
DateTable
,
ElInput
,
ElButton
,
}
,
data
()
{
return
{
popperClass
:
""
,
date
:
new
Date
(),
value
:
""
,
defaultValue
:
null
,
// use getDefaultValue() for time computation
defaultTime
:
null
,
showTime
:
false
,
selectionMode
:
"
day
"
,
shortcuts
:
""
,
visible
:
true
,
currentView
:
"
date
"
,
disabledDate
:
""
,
cellClassName
:
""
,
selectableRange
:
[],
firstDayOfWeek
:
7
,
showWeekNumber
:
false
,
timePickerVisible
:
false
,
format
:
""
,
arrowControl
:
false
,
userInputDate
:
null
,
userInputTime
:
null
,
}
;
}
,
computed
:
{
year
()
{
return
this
.
date
.
getFullYear
();
}
,
month
()
{
return
this
.
date
.
getMonth
();
}
,
week
()
{
return
getWeekNumber
(
this
.
date
);
}
,
monthDate
()
{
return
this
.
date
.
getDate
();
}
,
footerVisible
()
{
return
(
this
.
showTime
||
this
.
selectionMode
===
"
dates
"
||
this
.
selectionMode
===
"
months
"
||
this
.
selectionMode
===
"
years
"
);
}
,
visibleTime
()
{
if
(
this
.
userInputTime
!==
null
)
{
return
this
.
userInputTime
;
}
else
{
return
formatDate
(
this
.
value
||
this
.
defaultValue
,
this
.
timeFormat
);
}
}
,
visibleDate
()
{
if
(
this
.
userInputDate
!==
null
)
{
return
this
.
userInputDate
;
}
else
{
return
formatDate
(
this
.
value
||
this
.
defaultValue
,
this
.
dateFormat
);
}
}
,
yearLabel
()
{
const
yearTranslation
=
this
.
t
(
"
el.datepicker.year
"
);
if
(
this
.
currentView
===
"
year
"
)
{
const
startYear
=
Math
.
floor
(
this
.
year
/
10
)
*
10
;
if
(
yearTranslation
)
{
return
(
startYear
+
"
"
+
yearTranslation
+
"
-
"
+
(
startYear
+
9
)
+
"
"
+
yearTranslation
);
}
return
startYear
+
"
-
"
+
(
startYear
+
9
);
}
return
this
.
year
+
"
"
+
yearTranslation
;
}
,
timeFormat
()
{
if
(
this
.
format
)
{
return
extractTimeFormat
(
this
.
format
);
}
else
{
return
"
HH:mm:ss
"
;
}
}
,
dateFormat
()
{
if
(
this
.
format
)
{
return
extractDateFormat
(
this
.
format
);
}
else
{
return
"
yyyy-MM-dd
"
;
}
}
,
}
,
}
;
<
/script
>
admin_2/src/components/YDatePickerTab/date-picker/src/panel/month-range.vue
0 → 100644
View file @
6f2cf656
<
template
>
<transition
name=
"el-zoom-in-top"
@
after-leave=
"$emit('dodestroy')"
>
<div
v-show=
"visible"
class=
"el-picker-panel el-date-range-picker el-popper"
:class=
"[
{
'has-sidebar': $slots.sidebar || shortcuts,
},
popperClass,
]"
>
<div
class=
"el-picker-panel__body-wrapper"
>
<slot
name=
"sidebar"
class=
"el-picker-panel__sidebar"
></slot>
<div
class=
"el-picker-panel__sidebar"
v-if=
"shortcuts"
>
<button
type=
"button"
class=
"el-picker-panel__shortcut"
v-for=
"(shortcut, key) in shortcuts"
:key=
"key"
@
click=
"handleShortcutClick(shortcut)"
>
{{
shortcut
.
text
}}
</button>
</div>
<div
class=
"el-picker-panel__body"
>
<div
class=
"el-picker-panel__content el-date-range-picker__content is-left"
>
<div
class=
"el-date-range-picker__header"
>
<button
type=
"button"
@
click=
"leftPrevYear"
class=
"el-picker-panel__icon-btn el-icon-d-arrow-left"
></button>
<button
type=
"button"
v-if=
"unlinkPanels"
@
click=
"leftNextYear"
:disabled=
"!enableYearArrow"
:class=
"
{ 'is-disabled': !enableYearArrow }"
class="el-picker-panel__icon-btn el-icon-d-arrow-right"
>
</button>
<div>
{{
leftLabel
}}
</div>
</div>
<month-table
selection-mode=
"range"
:date=
"leftDate"
:default-value=
"defaultValue"
:min-date=
"minDate"
:max-date=
"maxDate"
:range-state=
"rangeState"
:disabled-date=
"disabledDate"
@
changerange=
"handleChangeRange"
@
pick=
"handleRangePick"
>
</month-table>
</div>
<div
class=
"el-picker-panel__content el-date-range-picker__content is-right"
>
<div
class=
"el-date-range-picker__header"
>
<button
type=
"button"
v-if=
"unlinkPanels"
@
click=
"rightPrevYear"
:disabled=
"!enableYearArrow"
:class=
"
{ 'is-disabled': !enableYearArrow }"
class="el-picker-panel__icon-btn el-icon-d-arrow-left"
>
</button>
<button
type=
"button"
@
click=
"rightNextYear"
class=
"el-picker-panel__icon-btn el-icon-d-arrow-right"
></button>
<div>
{{
rightLabel
}}
</div>
</div>
<month-table
selection-mode=
"range"
:date=
"rightDate"
:default-value=
"defaultValue"
:min-date=
"minDate"
:max-date=
"maxDate"
:range-state=
"rangeState"
:disabled-date=
"disabledDate"
@
changerange=
"handleChangeRange"
@
pick=
"handleRangePick"
>
</month-table>
</div>
</div>
</div>
</div>
</transition>
</
template
>
<
script
type=
"text/babel"
>
/* eslint-disable */
import
{
isDate
,
modifyWithTimeString
,
prevYear
,
nextYear
,
nextMonth
,
}
from
"
element-ui/src/utils/date-util
"
;
import
Clickoutside
from
"
element-ui/src/utils/clickoutside
"
;
import
Locale
from
"
element-ui/src/mixins/locale
"
;
import
MonthTable
from
"
../basic/month-table
"
;
import
ElInput
from
"
element-ui/packages/input
"
;
import
ElButton
from
"
element-ui/packages/button
"
;
const
calcDefaultValue
=
(
defaultValue
)
=>
{
if
(
Array
.
isArray
(
defaultValue
))
{
return
[
new
Date
(
defaultValue
[
0
]),
new
Date
(
defaultValue
[
1
])];
}
else
if
(
defaultValue
)
{
return
[
new
Date
(
defaultValue
),
nextMonth
(
new
Date
(
defaultValue
))];
}
else
{
return
[
new
Date
(),
nextMonth
(
new
Date
())];
}
};
export
default
{
mixins
:
[
Locale
],
directives
:
{
Clickoutside
},
computed
:
{
btnDisabled
()
{
return
!
(
this
.
minDate
&&
this
.
maxDate
&&
!
this
.
selecting
&&
this
.
isValidValue
([
this
.
minDate
,
this
.
maxDate
])
);
},
leftLabel
()
{
return
this
.
leftDate
.
getFullYear
()
+
"
"
+
this
.
t
(
"
el.datepicker.year
"
);
},
rightLabel
()
{
return
this
.
rightDate
.
getFullYear
()
+
"
"
+
this
.
t
(
"
el.datepicker.year
"
);
},
leftYear
()
{
return
this
.
leftDate
.
getFullYear
();
},
rightYear
()
{
return
this
.
rightDate
.
getFullYear
()
===
this
.
leftDate
.
getFullYear
()
?
this
.
leftDate
.
getFullYear
()
+
1
:
this
.
rightDate
.
getFullYear
();
},
enableYearArrow
()
{
return
this
.
unlinkPanels
&&
this
.
rightYear
>
this
.
leftYear
+
1
;
},
},
data
()
{
return
{
popperClass
:
""
,
value
:
[],
defaultValue
:
null
,
defaultTime
:
null
,
minDate
:
""
,
maxDate
:
""
,
leftDate
:
new
Date
(),
rightDate
:
nextYear
(
new
Date
()),
rangeState
:
{
endDate
:
null
,
selecting
:
false
,
row
:
null
,
column
:
null
,
},
shortcuts
:
""
,
visible
:
""
,
disabledDate
:
""
,
format
:
""
,
arrowControl
:
false
,
unlinkPanels
:
false
,
};
},
watch
:
{
value
(
newVal
)
{
if
(
!
newVal
)
{
this
.
minDate
=
null
;
this
.
maxDate
=
null
;
}
else
if
(
Array
.
isArray
(
newVal
))
{
this
.
minDate
=
isDate
(
newVal
[
0
])
?
new
Date
(
newVal
[
0
])
:
null
;
this
.
maxDate
=
isDate
(
newVal
[
1
])
?
new
Date
(
newVal
[
1
])
:
null
;
if
(
this
.
minDate
)
{
this
.
leftDate
=
this
.
minDate
;
if
(
this
.
unlinkPanels
&&
this
.
maxDate
)
{
const
minDateYear
=
this
.
minDate
.
getFullYear
();
const
maxDateYear
=
this
.
maxDate
.
getFullYear
();
this
.
rightDate
=
minDateYear
===
maxDateYear
?
nextYear
(
this
.
maxDate
)
:
this
.
maxDate
;
}
else
{
this
.
rightDate
=
nextYear
(
this
.
leftDate
);
}
}
else
{
this
.
leftDate
=
calcDefaultValue
(
this
.
defaultValue
)[
0
];
this
.
rightDate
=
nextYear
(
this
.
leftDate
);
}
}
},
defaultValue
(
val
)
{
if
(
!
Array
.
isArray
(
this
.
value
))
{
const
[
left
,
right
]
=
calcDefaultValue
(
val
);
this
.
leftDate
=
left
;
this
.
rightDate
=
val
&&
val
[
1
]
&&
left
.
getFullYear
()
!==
right
.
getFullYear
()
&&
this
.
unlinkPanels
?
right
:
nextYear
(
this
.
leftDate
);
}
},
},
methods
:
{
handleClear
()
{
this
.
minDate
=
null
;
this
.
maxDate
=
null
;
this
.
leftDate
=
calcDefaultValue
(
this
.
defaultValue
)[
0
];
this
.
rightDate
=
nextYear
(
this
.
leftDate
);
this
.
$emit
(
"
pick
"
,
null
);
},
handleChangeRange
(
val
)
{
this
.
minDate
=
val
.
minDate
;
this
.
maxDate
=
val
.
maxDate
;
this
.
rangeState
=
val
.
rangeState
;
},
handleRangePick
(
val
,
close
=
true
)
{
const
defaultTime
=
this
.
defaultTime
||
[];
const
minDate
=
modifyWithTimeString
(
val
.
minDate
,
defaultTime
[
0
]);
const
maxDate
=
modifyWithTimeString
(
val
.
maxDate
,
defaultTime
[
1
]);
if
(
this
.
maxDate
===
maxDate
&&
this
.
minDate
===
minDate
)
{
return
;
}
this
.
onPick
&&
this
.
onPick
(
val
);
this
.
maxDate
=
maxDate
;
this
.
minDate
=
minDate
;
// workaround for https://github.com/ElemeFE/element/issues/7539, should remove this block when we don't have to care about Chromium 55 - 57
setTimeout
(()
=>
{
this
.
maxDate
=
maxDate
;
this
.
minDate
=
minDate
;
},
10
);
if
(
!
close
)
return
;
this
.
handleConfirm
();
},
handleShortcutClick
(
shortcut
)
{
if
(
shortcut
.
onClick
)
{
shortcut
.
onClick
(
this
);
}
},
// leftPrev*, rightNext* need to take care of `unlinkPanels`
leftPrevYear
()
{
this
.
leftDate
=
prevYear
(
this
.
leftDate
);
if
(
!
this
.
unlinkPanels
)
{
this
.
rightDate
=
prevYear
(
this
.
rightDate
);
}
},
rightNextYear
()
{
if
(
!
this
.
unlinkPanels
)
{
this
.
leftDate
=
nextYear
(
this
.
leftDate
);
}
this
.
rightDate
=
nextYear
(
this
.
rightDate
);
},
// leftNext*, rightPrev* are called when `unlinkPanels` is true
leftNextYear
()
{
this
.
leftDate
=
nextYear
(
this
.
leftDate
);
},
rightPrevYear
()
{
this
.
rightDate
=
prevYear
(
this
.
rightDate
);
},
handleConfirm
(
visible
=
false
)
{
if
(
this
.
isValidValue
([
this
.
minDate
,
this
.
maxDate
]))
{
this
.
$emit
(
"
pick
"
,
[
this
.
minDate
,
this
.
maxDate
],
visible
);
}
},
isValidValue
(
value
)
{
return
(
Array
.
isArray
(
value
)
&&
value
&&
value
[
0
]
&&
value
[
1
]
&&
isDate
(
value
[
0
])
&&
isDate
(
value
[
1
])
&&
value
[
0
].
getTime
()
<=
value
[
1
].
getTime
()
&&
(
typeof
this
.
disabledDate
===
"
function
"
?
!
this
.
disabledDate
(
value
[
0
])
&&
!
this
.
disabledDate
(
value
[
1
])
:
true
)
);
},
resetView
()
{
// NOTE: this is a hack to reset {min, max}Date on picker open.
// TODO: correct way of doing so is to refactor {min, max}Date to be dependent on value and internal selection state
// an alternative would be resetView whenever picker becomes visible, should also investigate date-panel's resetView
this
.
minDate
=
this
.
value
&&
isDate
(
this
.
value
[
0
])
?
new
Date
(
this
.
value
[
0
])
:
null
;
this
.
maxDate
=
this
.
value
&&
isDate
(
this
.
value
[
0
])
?
new
Date
(
this
.
value
[
1
])
:
null
;
},
},
components
:
{
MonthTable
,
ElInput
,
ElButton
},
};
</
script
>
admin_2/src/components/YDatePickerTab/date-picker/src/panel/time-range.vue
0 → 100644
View file @
6f2cf656
<
template
>
<transition
name=
"el-zoom-in-top"
@
after-leave=
"$emit('dodestroy')"
>
<div
v-show=
"visible"
class=
"el-time-range-picker el-picker-panel el-popper"
:class=
"popperClass"
>
<div
class=
"el-time-range-picker__content"
>
<div
class=
"el-time-range-picker__cell"
>
<div
class=
"el-time-range-picker__header"
>
{{
t
(
"
el.datepicker.startTime
"
)
}}
</div>
<div
:class=
"
{ 'has-seconds': showSeconds, 'is-arrow': arrowControl }"
class="el-time-range-picker__body el-time-panel__content"
>
<time-spinner
ref=
"minSpinner"
:show-seconds=
"showSeconds"
:am-pm-mode=
"amPmMode"
@
change=
"handleMinChange"
:arrow-control=
"arrowControl"
@
select-range=
"setMinSelectionRange"
:date=
"minDate"
>
</time-spinner>
</div>
</div>
<div
class=
"el-time-range-picker__cell"
>
<div
class=
"el-time-range-picker__header"
>
{{
t
(
"
el.datepicker.endTime
"
)
}}
</div>
<div
:class=
"
{ 'has-seconds': showSeconds, 'is-arrow': arrowControl }"
class="el-time-range-picker__body el-time-panel__content"
>
<time-spinner
ref=
"maxSpinner"
:show-seconds=
"showSeconds"
:am-pm-mode=
"amPmMode"
@
change=
"handleMaxChange"
:arrow-control=
"arrowControl"
@
select-range=
"setMaxSelectionRange"
:date=
"maxDate"
>
</time-spinner>
</div>
</div>
</div>
<div
class=
"el-time-panel__footer"
>
<button
type=
"button"
class=
"el-time-panel__btn cancel"
@
click=
"handleCancel()"
>
{{
t
(
"
el.datepicker.cancel
"
)
}}
</button>
<button
type=
"button"
class=
"el-time-panel__btn confirm"
@
click=
"handleConfirm()"
:disabled=
"btnDisabled"
>
{{
t
(
"
el.datepicker.confirm
"
)
}}
</button>
</div>
</div>
</transition>
</
template
>
<
script
type=
"text/babel"
>
/* eslint-disable */
import
{
parseDate
,
limitTimeRange
,
modifyDate
,
clearMilliseconds
,
timeWithinRange
,
}
from
"
element-ui/src/utils/date-util
"
;
import
Locale
from
"
element-ui/src/mixins/locale
"
;
import
TimeSpinner
from
"
../basic/time-spinner
"
;
const
MIN_TIME
=
parseDate
(
"
00:00:00
"
,
"
HH:mm:ss
"
);
const
MAX_TIME
=
parseDate
(
"
23:59:59
"
,
"
HH:mm:ss
"
);
const
minTimeOfDay
=
function
(
date
)
{
return
modifyDate
(
MIN_TIME
,
date
.
getFullYear
(),
date
.
getMonth
(),
date
.
getDate
()
);
};
const
maxTimeOfDay
=
function
(
date
)
{
return
modifyDate
(
MAX_TIME
,
date
.
getFullYear
(),
date
.
getMonth
(),
date
.
getDate
()
);
};
// increase time by amount of milliseconds, but within the range of day
const
advanceTime
=
function
(
date
,
amount
)
{
return
new
Date
(
Math
.
min
(
date
.
getTime
()
+
amount
,
maxTimeOfDay
(
date
).
getTime
())
);
};
export
default
{
mixins
:
[
Locale
],
components
:
{
TimeSpinner
},
computed
:
{
showSeconds
()
{
return
(
this
.
format
||
""
).
indexOf
(
"
ss
"
)
!==
-
1
;
},
offset
()
{
return
this
.
showSeconds
?
11
:
8
;
},
spinner
()
{
return
this
.
selectionRange
[
0
]
<
this
.
offset
?
this
.
$refs
.
minSpinner
:
this
.
$refs
.
maxSpinner
;
},
btnDisabled
()
{
return
this
.
minDate
.
getTime
()
>
this
.
maxDate
.
getTime
();
},
amPmMode
()
{
if
((
this
.
format
||
""
).
indexOf
(
"
A
"
)
!==
-
1
)
return
"
A
"
;
if
((
this
.
format
||
""
).
indexOf
(
"
a
"
)
!==
-
1
)
return
"
a
"
;
return
""
;
},
},
data
()
{
return
{
popperClass
:
""
,
minDate
:
new
Date
(),
maxDate
:
new
Date
(),
value
:
[],
oldValue
:
[
new
Date
(),
new
Date
()],
defaultValue
:
null
,
format
:
"
HH:mm:ss
"
,
visible
:
false
,
selectionRange
:
[
0
,
2
],
arrowControl
:
false
,
};
},
watch
:
{
value
(
value
)
{
if
(
Array
.
isArray
(
value
))
{
this
.
minDate
=
new
Date
(
value
[
0
]);
this
.
maxDate
=
new
Date
(
value
[
1
]);
}
else
{
if
(
Array
.
isArray
(
this
.
defaultValue
))
{
this
.
minDate
=
new
Date
(
this
.
defaultValue
[
0
]);
this
.
maxDate
=
new
Date
(
this
.
defaultValue
[
1
]);
}
else
if
(
this
.
defaultValue
)
{
this
.
minDate
=
new
Date
(
this
.
defaultValue
);
this
.
maxDate
=
advanceTime
(
new
Date
(
this
.
defaultValue
),
60
*
60
*
1000
);
}
else
{
this
.
minDate
=
new
Date
();
this
.
maxDate
=
advanceTime
(
new
Date
(),
60
*
60
*
1000
);
}
}
},
visible
(
val
)
{
if
(
val
)
{
this
.
oldValue
=
this
.
value
;
this
.
$nextTick
(()
=>
this
.
$refs
.
minSpinner
.
emitSelectRange
(
"
hours
"
));
}
},
},
methods
:
{
handleClear
()
{
this
.
$emit
(
"
pick
"
,
null
);
},
handleCancel
()
{
this
.
$emit
(
"
pick
"
,
this
.
oldValue
);
},
handleMinChange
(
date
)
{
this
.
minDate
=
clearMilliseconds
(
date
);
this
.
handleChange
();
},
handleMaxChange
(
date
)
{
this
.
maxDate
=
clearMilliseconds
(
date
);
this
.
handleChange
();
},
handleChange
()
{
if
(
this
.
isValidValue
([
this
.
minDate
,
this
.
maxDate
]))
{
this
.
$refs
.
minSpinner
.
selectableRange
=
[
[
minTimeOfDay
(
this
.
minDate
),
this
.
maxDate
],
];
this
.
$refs
.
maxSpinner
.
selectableRange
=
[
[
this
.
minDate
,
maxTimeOfDay
(
this
.
maxDate
)],
];
this
.
$emit
(
"
pick
"
,
[
this
.
minDate
,
this
.
maxDate
],
true
);
}
},
setMinSelectionRange
(
start
,
end
)
{
this
.
$emit
(
"
select-range
"
,
start
,
end
,
"
min
"
);
this
.
selectionRange
=
[
start
,
end
];
},
setMaxSelectionRange
(
start
,
end
)
{
this
.
$emit
(
"
select-range
"
,
start
,
end
,
"
max
"
);
this
.
selectionRange
=
[
start
+
this
.
offset
,
end
+
this
.
offset
];
},
handleConfirm
(
visible
=
false
)
{
const
minSelectableRange
=
this
.
$refs
.
minSpinner
.
selectableRange
;
const
maxSelectableRange
=
this
.
$refs
.
maxSpinner
.
selectableRange
;
this
.
minDate
=
limitTimeRange
(
this
.
minDate
,
minSelectableRange
,
this
.
format
);
this
.
maxDate
=
limitTimeRange
(
this
.
maxDate
,
maxSelectableRange
,
this
.
format
);
this
.
$emit
(
"
pick
"
,
[
this
.
minDate
,
this
.
maxDate
],
visible
);
},
adjustSpinners
()
{
this
.
$refs
.
minSpinner
.
adjustSpinners
();
this
.
$refs
.
maxSpinner
.
adjustSpinners
();
},
changeSelectionRange
(
step
)
{
const
list
=
this
.
showSeconds
?
[
0
,
3
,
6
,
11
,
14
,
17
]
:
[
0
,
3
,
8
,
11
];
const
mapping
=
[
"
hours
"
,
"
minutes
"
].
concat
(
this
.
showSeconds
?
[
"
seconds
"
]
:
[]
);
const
index
=
list
.
indexOf
(
this
.
selectionRange
[
0
]);
const
next
=
(
index
+
step
+
list
.
length
)
%
list
.
length
;
const
half
=
list
.
length
/
2
;
if
(
next
<
half
)
{
this
.
$refs
.
minSpinner
.
emitSelectRange
(
mapping
[
next
]);
}
else
{
this
.
$refs
.
maxSpinner
.
emitSelectRange
(
mapping
[
next
-
half
]);
}
},
isValidValue
(
date
)
{
return
(
Array
.
isArray
(
date
)
&&
timeWithinRange
(
this
.
minDate
,
this
.
$refs
.
minSpinner
.
selectableRange
)
&&
timeWithinRange
(
this
.
maxDate
,
this
.
$refs
.
maxSpinner
.
selectableRange
)
);
},
handleKeydown
(
event
)
{
const
keyCode
=
event
.
keyCode
;
const
mapping
=
{
38
:
-
1
,
40
:
1
,
37
:
-
1
,
39
:
1
};
// Left or Right
if
(
keyCode
===
37
||
keyCode
===
39
)
{
const
step
=
mapping
[
keyCode
];
this
.
changeSelectionRange
(
step
);
event
.
preventDefault
();
return
;
}
// Up or Down
if
(
keyCode
===
38
||
keyCode
===
40
)
{
const
step
=
mapping
[
keyCode
];
this
.
spinner
.
scrollDown
(
step
);
event
.
preventDefault
();
return
;
}
},
},
};
</
script
>
admin_2/src/components/YDatePickerTab/date-picker/src/panel/time-select.vue
0 → 100644
View file @
6f2cf656
<
template
>
<transition
name=
"el-zoom-in-top"
@
before-enter=
"handleMenuEnter"
@
after-leave=
"$emit('dodestroy')"
>
<div
ref=
"popper"
v-show=
"visible"
:style=
"
{ width: width + 'px' }"
:class="popperClass"
class="el-picker-panel time-select el-popper"
>
<el-scrollbar
noresize
wrap-class=
"el-picker-panel__content"
>
<div
class=
"time-select-item"
v-for=
"item in items"
:class=
"
{
selected: value === item.value,
disabled: item.disabled,
default: item.value === defaultValue,
}"
:disabled="item.disabled"
:key="item.value"
@click="handleClick(item)"
>
{{
item
.
value
}}
</div>
</el-scrollbar>
</div>
</transition>
</
template
>
<
script
type=
"text/babel"
>
/* eslint-disable */
import
ElScrollbar
from
"
element-ui/packages/scrollbar
"
;
import
scrollIntoView
from
"
element-ui/src/utils/scroll-into-view
"
;
const
parseTime
=
function
(
time
)
{
const
values
=
(
time
||
""
).
split
(
"
:
"
);
if
(
values
.
length
>=
2
)
{
const
hours
=
parseInt
(
values
[
0
],
10
);
const
minutes
=
parseInt
(
values
[
1
],
10
);
return
{
hours
,
minutes
,
};
}
/* istanbul ignore next */
return
null
;
};
const
compareTime
=
function
(
time1
,
time2
)
{
const
value1
=
parseTime
(
time1
);
const
value2
=
parseTime
(
time2
);
const
minutes1
=
value1
.
minutes
+
value1
.
hours
*
60
;
const
minutes2
=
value2
.
minutes
+
value2
.
hours
*
60
;
if
(
minutes1
===
minutes2
)
{
return
0
;
}
return
minutes1
>
minutes2
?
1
:
-
1
;
};
const
formatTime
=
function
(
time
)
{
return
(
(
time
.
hours
<
10
?
"
0
"
+
time
.
hours
:
time
.
hours
)
+
"
:
"
+
(
time
.
minutes
<
10
?
"
0
"
+
time
.
minutes
:
time
.
minutes
)
);
};
const
nextTime
=
function
(
time
,
step
)
{
const
timeValue
=
parseTime
(
time
);
const
stepValue
=
parseTime
(
step
);
const
next
=
{
hours
:
timeValue
.
hours
,
minutes
:
timeValue
.
minutes
,
};
next
.
minutes
+=
stepValue
.
minutes
;
next
.
hours
+=
stepValue
.
hours
;
next
.
hours
+=
Math
.
floor
(
next
.
minutes
/
60
);
next
.
minutes
=
next
.
minutes
%
60
;
return
formatTime
(
next
);
};
export
default
{
components
:
{
ElScrollbar
},
watch
:
{
value
(
val
)
{
if
(
!
val
)
return
;
this
.
$nextTick
(()
=>
this
.
scrollToOption
());
},
},
methods
:
{
handleClick
(
item
)
{
if
(
!
item
.
disabled
)
{
this
.
$emit
(
"
pick
"
,
item
.
value
);
}
},
handleClear
()
{
this
.
$emit
(
"
pick
"
,
null
);
},
scrollToOption
(
selector
=
"
.selected
"
)
{
const
menu
=
this
.
$refs
.
popper
.
querySelector
(
"
.el-picker-panel__content
"
);
scrollIntoView
(
menu
,
menu
.
querySelector
(
selector
));
},
handleMenuEnter
()
{
const
selected
=
this
.
items
.
map
((
item
)
=>
item
.
value
).
indexOf
(
this
.
value
)
!==
-
1
;
const
hasDefault
=
this
.
items
.
map
((
item
)
=>
item
.
value
).
indexOf
(
this
.
defaultValue
)
!==
-
1
;
const
option
=
(
selected
&&
"
.selected
"
)
||
(
hasDefault
&&
"
.default
"
)
||
"
.time-select-item:not(.disabled)
"
;
this
.
$nextTick
(()
=>
this
.
scrollToOption
(
option
));
},
scrollDown
(
step
)
{
const
items
=
this
.
items
;
const
length
=
items
.
length
;
let
total
=
items
.
length
;
let
index
=
items
.
map
((
item
)
=>
item
.
value
).
indexOf
(
this
.
value
);
while
(
total
--
)
{
index
=
(
index
+
step
+
length
)
%
length
;
if
(
!
items
[
index
].
disabled
)
{
this
.
$emit
(
"
pick
"
,
items
[
index
].
value
,
true
);
return
;
}
}
},
isValidValue
(
date
)
{
return
(
this
.
items
.
filter
((
item
)
=>
!
item
.
disabled
)
.
map
((
item
)
=>
item
.
value
)
.
indexOf
(
date
)
!==
-
1
);
},
handleKeydown
(
event
)
{
const
keyCode
=
event
.
keyCode
;
if
(
keyCode
===
38
||
keyCode
===
40
)
{
const
mapping
=
{
40
:
1
,
38
:
-
1
};
const
offset
=
mapping
[
keyCode
.
toString
()];
this
.
scrollDown
(
offset
);
event
.
stopPropagation
();
return
;
}
},
},
data
()
{
return
{
popperClass
:
""
,
start
:
"
09:00
"
,
end
:
"
18:00
"
,
step
:
"
00:30
"
,
value
:
""
,
defaultValue
:
""
,
visible
:
false
,
minTime
:
""
,
maxTime
:
""
,
width
:
0
,
};
},
computed
:
{
items
()
{
const
start
=
this
.
start
;
const
end
=
this
.
end
;
const
step
=
this
.
step
;
const
result
=
[];
if
(
start
&&
end
&&
step
)
{
let
current
=
start
;
while
(
compareTime
(
current
,
end
)
<=
0
)
{
result
.
push
({
value
:
current
,
disabled
:
compareTime
(
current
,
this
.
minTime
||
"
-1:-1
"
)
<=
0
||
compareTime
(
current
,
this
.
maxTime
||
"
100:100
"
)
>=
0
,
});
current
=
nextTime
(
current
,
step
);
}
}
return
result
;
},
},
};
</
script
>
admin_2/src/components/YDatePickerTab/date-picker/src/panel/time.vue
0 → 100644
View file @
6f2cf656
<
template
>
<transition
name=
"el-zoom-in-top"
@
after-leave=
"$emit('dodestroy')"
>
<div
v-show=
"visible"
class=
"el-time-panel el-popper"
:class=
"popperClass"
>
<div
class=
"el-time-panel__content"
:class=
"
{ 'has-seconds': showSeconds }"
>
<time-spinner
ref=
"spinner"
@
change=
"handleChange"
:arrow-control=
"useArrow"
:show-seconds=
"showSeconds"
:am-pm-mode=
"amPmMode"
@
select-range=
"setSelectionRange"
:date=
"date"
>
</time-spinner>
</div>
<div
class=
"el-time-panel__footer"
>
<button
type=
"button"
class=
"el-time-panel__btn cancel"
@
click=
"handleCancel"
>
{{
t
(
"
el.datepicker.cancel
"
)
}}
</button>
<button
type=
"button"
class=
"el-time-panel__btn"
:class=
"
{ confirm: !disabled }"
@click="handleConfirm()"
>
{{
t
(
"
el.datepicker.confirm
"
)
}}
</button>
</div>
</div>
</transition>
</
template
>
<
script
type=
"text/babel"
>
/* eslint-disable */
import
{
limitTimeRange
,
isDate
,
clearMilliseconds
,
timeWithinRange
,
}
from
"
element-ui/src/utils/date-util
"
;
import
Locale
from
"
element-ui/src/mixins/locale
"
;
import
TimeSpinner
from
"
../basic/time-spinner
"
;
export
default
{
mixins
:
[
Locale
],
components
:
{
TimeSpinner
,
},
props
:
{
visible
:
Boolean
,
timeArrowControl
:
Boolean
,
},
watch
:
{
visible
(
val
)
{
if
(
val
)
{
this
.
oldValue
=
this
.
value
;
this
.
$nextTick
(()
=>
this
.
$refs
.
spinner
.
emitSelectRange
(
"
hours
"
));
}
else
{
this
.
needInitAdjust
=
true
;
}
},
value
(
newVal
)
{
let
date
;
if
(
newVal
instanceof
Date
)
{
date
=
limitTimeRange
(
newVal
,
this
.
selectableRange
,
this
.
format
);
}
else
if
(
!
newVal
)
{
date
=
this
.
defaultValue
?
new
Date
(
this
.
defaultValue
)
:
new
Date
();
}
this
.
date
=
date
;
if
(
this
.
visible
&&
this
.
needInitAdjust
)
{
this
.
$nextTick
((
_
)
=>
this
.
adjustSpinners
());
this
.
needInitAdjust
=
false
;
}
},
selectableRange
(
val
)
{
this
.
$refs
.
spinner
.
selectableRange
=
val
;
},
defaultValue
(
val
)
{
if
(
!
isDate
(
this
.
value
))
{
this
.
date
=
val
?
new
Date
(
val
)
:
new
Date
();
}
},
},
data
()
{
return
{
popperClass
:
""
,
format
:
"
HH:mm:ss
"
,
value
:
""
,
defaultValue
:
null
,
date
:
new
Date
(),
oldValue
:
new
Date
(),
selectableRange
:
[],
selectionRange
:
[
0
,
2
],
disabled
:
false
,
arrowControl
:
false
,
needInitAdjust
:
true
,
};
},
computed
:
{
showSeconds
()
{
return
(
this
.
format
||
""
).
indexOf
(
"
ss
"
)
!==
-
1
;
},
useArrow
()
{
return
this
.
arrowControl
||
this
.
timeArrowControl
||
false
;
},
amPmMode
()
{
if
((
this
.
format
||
""
).
indexOf
(
"
A
"
)
!==
-
1
)
return
"
A
"
;
if
((
this
.
format
||
""
).
indexOf
(
"
a
"
)
!==
-
1
)
return
"
a
"
;
return
""
;
},
},
methods
:
{
handleCancel
()
{
this
.
$emit
(
"
pick
"
,
this
.
oldValue
,
false
);
},
handleChange
(
date
)
{
// this.visible avoids edge cases, when use scrolls during panel closing animation
if
(
this
.
visible
)
{
this
.
date
=
clearMilliseconds
(
date
);
// if date is out of range, do not emit
if
(
this
.
isValidValue
(
this
.
date
))
{
this
.
$emit
(
"
pick
"
,
this
.
date
,
true
);
}
}
},
setSelectionRange
(
start
,
end
)
{
this
.
$emit
(
"
select-range
"
,
start
,
end
);
this
.
selectionRange
=
[
start
,
end
];
},
handleConfirm
(
visible
=
false
,
first
)
{
if
(
first
)
return
;
const
date
=
clearMilliseconds
(
limitTimeRange
(
this
.
date
,
this
.
selectableRange
,
this
.
format
)
);
this
.
$emit
(
"
pick
"
,
date
,
visible
,
first
);
},
handleKeydown
(
event
)
{
const
keyCode
=
event
.
keyCode
;
const
mapping
=
{
38
:
-
1
,
40
:
1
,
37
:
-
1
,
39
:
1
};
// Left or Right
if
(
keyCode
===
37
||
keyCode
===
39
)
{
const
step
=
mapping
[
keyCode
];
this
.
changeSelectionRange
(
step
);
event
.
preventDefault
();
return
;
}
// Up or Down
if
(
keyCode
===
38
||
keyCode
===
40
)
{
const
step
=
mapping
[
keyCode
];
this
.
$refs
.
spinner
.
scrollDown
(
step
);
event
.
preventDefault
();
return
;
}
},
isValidValue
(
date
)
{
return
timeWithinRange
(
date
,
this
.
selectableRange
,
this
.
format
);
},
adjustSpinners
()
{
return
this
.
$refs
.
spinner
.
adjustSpinners
();
},
changeSelectionRange
(
step
)
{
const
list
=
[
0
,
3
].
concat
(
this
.
showSeconds
?
[
6
]
:
[]);
const
mapping
=
[
"
hours
"
,
"
minutes
"
].
concat
(
this
.
showSeconds
?
[
"
seconds
"
]
:
[]
);
const
index
=
list
.
indexOf
(
this
.
selectionRange
[
0
]);
const
next
=
(
index
+
step
+
list
.
length
)
%
list
.
length
;
this
.
$refs
.
spinner
.
emitSelectRange
(
mapping
[
next
]);
},
},
mounted
()
{
this
.
$nextTick
(()
=>
this
.
handleConfirm
(
true
,
true
));
this
.
$emit
(
"
mounted
"
);
},
};
</
script
>
admin_2/src/components/YDatePickerTab/date-picker/src/picker.vue
0 → 100644
View file @
6f2cf656
<
template
>
<div
class=
"w-full"
ref=
"reference"
></div>
</
template
>
<
script
>
/* eslint-disable */
import
Vue
from
"
vue
"
;
import
Clickoutside
from
"
element-ui/src/utils/clickoutside
"
;
import
{
formatDate
,
parseDate
,
isDateObject
,
getWeekNumber
,
}
from
"
element-ui/src/utils/date-util
"
;
// import Popper from "element-ui/src/utils/vue-popper";
import
Emitter
from
"
element-ui/src/mixins/emitter
"
;
import
ElInput
from
"
element-ui/packages/input
"
;
// import merge from "element-ui/src/utils/merge";
// const NewPopper = {
// props: {
// appendToBody: Popper.props.appendToBody,
// offset: Popper.props.offset,
// boundariesPadding: Popper.props.boundariesPadding,
// arrowOffset: Popper.props.arrowOffset,
// transformOrigin: Popper.props.transformOrigin,
// },
// methods: Popper.methods,
// data() {
// return merge({ visibleArrow: true }, Popper.data);
// },
// beforeDestroy: Popper.beforeDestroy,
// };
const
DEFAULT_FORMATS
=
{
date
:
"
yyyy-MM-dd
"
,
month
:
"
yyyy-MM
"
,
months
:
"
yyyy-MM
"
,
datetime
:
"
yyyy-MM-dd HH:mm:ss
"
,
time
:
"
HH:mm:ss
"
,
week
:
"
yyyywWW
"
,
timerange
:
"
HH:mm:ss
"
,
daterange
:
"
yyyy-MM-dd
"
,
monthrange
:
"
yyyy-MM
"
,
datetimerange
:
"
yyyy-MM-dd HH:mm:ss
"
,
year
:
"
yyyy
"
,
years
:
"
yyyy
"
,
};
const
HAVE_TRIGGER_TYPES
=
[
"
date
"
,
"
datetime
"
,
"
time
"
,
"
time-select
"
,
"
week
"
,
"
month
"
,
"
year
"
,
"
daterange
"
,
"
monthrange
"
,
"
timerange
"
,
"
datetimerange
"
,
"
dates
"
,
"
months
"
,
"
years
"
,
];
const
DATE_FORMATTER
=
function
(
value
,
format
)
{
if
(
format
===
"
timestamp
"
)
return
value
.
getTime
();
return
formatDate
(
value
,
format
);
};
const
DATE_PARSER
=
function
(
text
,
format
)
{
if
(
format
===
"
timestamp
"
)
return
new
Date
(
Number
(
text
));
return
parseDate
(
text
,
format
);
};
const
RANGE_FORMATTER
=
function
(
value
,
format
)
{
if
(
Array
.
isArray
(
value
)
&&
value
.
length
===
2
)
{
const
start
=
value
[
0
];
const
end
=
value
[
1
];
if
(
start
&&
end
)
{
return
[
DATE_FORMATTER
(
start
,
format
),
DATE_FORMATTER
(
end
,
format
)];
}
}
return
""
;
};
const
RANGE_PARSER
=
function
(
array
,
format
,
separator
)
{
if
(
!
Array
.
isArray
(
array
))
{
array
=
array
.
split
(
separator
);
}
if
(
array
.
length
===
2
)
{
const
range1
=
array
[
0
];
const
range2
=
array
[
1
];
return
[
DATE_PARSER
(
range1
,
format
),
DATE_PARSER
(
range2
,
format
)];
}
return
[];
};
const
TYPE_VALUE_RESOLVER_MAP
=
{
default
:
{
formatter
(
value
)
{
if
(
!
value
)
return
""
;
return
""
+
value
;
},
parser
(
text
)
{
if
(
text
===
undefined
||
text
===
""
)
return
null
;
return
text
;
},
},
week
:
{
formatter
(
value
,
format
)
{
let
week
=
getWeekNumber
(
value
);
let
month
=
value
.
getMonth
();
const
trueDate
=
new
Date
(
value
);
if
(
week
===
1
&&
month
===
11
)
{
trueDate
.
setHours
(
0
,
0
,
0
,
0
);
trueDate
.
setDate
(
trueDate
.
getDate
()
+
3
-
((
trueDate
.
getDay
()
+
6
)
%
7
)
);
}
let
date
=
formatDate
(
trueDate
,
format
);
date
=
/WW/
.
test
(
date
)
?
date
.
replace
(
/WW/
,
week
<
10
?
"
0
"
+
week
:
week
)
:
date
.
replace
(
/W/
,
week
);
return
date
;
},
parser
(
text
,
format
)
{
// parse as if a normal date
return
TYPE_VALUE_RESOLVER_MAP
.
date
.
parser
(
text
,
format
);
},
},
date
:
{
formatter
:
DATE_FORMATTER
,
parser
:
DATE_PARSER
,
},
datetime
:
{
formatter
:
DATE_FORMATTER
,
parser
:
DATE_PARSER
,
},
daterange
:
{
formatter
:
RANGE_FORMATTER
,
parser
:
RANGE_PARSER
,
},
monthrange
:
{
formatter
:
RANGE_FORMATTER
,
parser
:
RANGE_PARSER
,
},
datetimerange
:
{
formatter
:
RANGE_FORMATTER
,
parser
:
RANGE_PARSER
,
},
timerange
:
{
formatter
:
RANGE_FORMATTER
,
parser
:
RANGE_PARSER
,
},
time
:
{
formatter
:
DATE_FORMATTER
,
parser
:
DATE_PARSER
,
},
month
:
{
formatter
:
DATE_FORMATTER
,
parser
:
DATE_PARSER
,
},
year
:
{
formatter
:
DATE_FORMATTER
,
parser
:
DATE_PARSER
,
},
number
:
{
formatter
(
value
)
{
if
(
!
value
)
return
""
;
return
""
+
value
;
},
parser
(
text
)
{
let
result
=
Number
(
text
);
if
(
!
isNaN
(
text
))
{
return
result
;
}
else
{
return
null
;
}
},
},
dates
:
{
formatter
(
value
,
format
)
{
return
value
.
map
((
date
)
=>
DATE_FORMATTER
(
date
,
format
));
},
parser
(
value
,
format
)
{
return
(
typeof
value
===
"
string
"
?
value
.
split
(
"
,
"
)
:
value
).
map
(
(
date
)
=>
(
date
instanceof
Date
?
date
:
DATE_PARSER
(
date
,
format
))
);
},
},
months
:
{
formatter
(
value
,
format
)
{
return
value
.
map
((
date
)
=>
DATE_FORMATTER
(
date
,
format
));
},
parser
(
value
,
format
)
{
return
(
typeof
value
===
"
string
"
?
value
.
split
(
"
,
"
)
:
value
).
map
(
(
date
)
=>
(
date
instanceof
Date
?
date
:
DATE_PARSER
(
date
,
format
))
);
},
},
years
:
{
formatter
(
value
,
format
)
{
return
value
.
map
((
date
)
=>
DATE_FORMATTER
(
date
,
format
));
},
parser
(
value
,
format
)
{
return
(
typeof
value
===
"
string
"
?
value
.
split
(
"
,
"
)
:
value
).
map
(
(
date
)
=>
(
date
instanceof
Date
?
date
:
DATE_PARSER
(
date
,
format
))
);
},
},
};
const
PLACEMENT_MAP
=
{
left
:
"
bottom-start
"
,
center
:
"
bottom
"
,
right
:
"
bottom-end
"
,
};
const
parseAsFormatAndType
=
(
value
,
customFormat
,
type
,
rangeSeparator
=
"
-
"
)
=>
{
if
(
!
value
)
return
null
;
const
parser
=
(
TYPE_VALUE_RESOLVER_MAP
[
type
]
||
TYPE_VALUE_RESOLVER_MAP
[
"
default
"
]
).
parser
;
const
format
=
customFormat
||
DEFAULT_FORMATS
[
type
];
return
parser
(
value
,
format
,
rangeSeparator
);
};
const
formatAsFormatAndType
=
(
value
,
customFormat
,
type
)
=>
{
if
(
!
value
)
return
null
;
const
formatter
=
(
TYPE_VALUE_RESOLVER_MAP
[
type
]
||
TYPE_VALUE_RESOLVER_MAP
[
"
default
"
]
).
formatter
;
const
format
=
customFormat
||
DEFAULT_FORMATS
[
type
];
return
formatter
(
value
,
format
);
};
/*
* Considers:
* 1. Date object
* 2. date string
* 3. array of 1 or 2
*/
const
valueEquals
=
function
(
a
,
b
)
{
// considers Date object and string
const
dateEquals
=
function
(
a
,
b
)
{
const
aIsDate
=
a
instanceof
Date
;
const
bIsDate
=
b
instanceof
Date
;
if
(
aIsDate
&&
bIsDate
)
{
return
a
.
getTime
()
===
b
.
getTime
();
}
if
(
!
aIsDate
&&
!
bIsDate
)
{
return
a
===
b
;
}
return
false
;
};
const
aIsArray
=
a
instanceof
Array
;
const
bIsArray
=
b
instanceof
Array
;
if
(
aIsArray
&&
bIsArray
)
{
if
(
a
.
length
!==
b
.
length
)
{
return
false
;
}
return
a
.
every
((
item
,
index
)
=>
dateEquals
(
item
,
b
[
index
]));
}
if
(
!
aIsArray
&&
!
bIsArray
)
{
return
dateEquals
(
a
,
b
);
}
return
false
;
};
const
isString
=
function
(
val
)
{
return
typeof
val
===
"
string
"
||
val
instanceof
String
;
};
const
validator
=
function
(
val
)
{
// either: String, Array of String, null / undefined
return
(
val
===
null
||
val
===
undefined
||
isString
(
val
)
||
(
Array
.
isArray
(
val
)
&&
val
.
length
===
2
&&
val
.
every
(
isString
))
);
};
export
default
{
mixins
:
[
Emitter
],
inject
:
{
elForm
:
{
default
:
""
,
},
elFormItem
:
{
default
:
""
,
},
},
props
:
{
size
:
String
,
format
:
String
,
valueFormat
:
String
,
readonly
:
Boolean
,
placeholder
:
String
,
startPlaceholder
:
String
,
endPlaceholder
:
String
,
prefixIcon
:
String
,
clearIcon
:
{
type
:
String
,
default
:
"
el-icon-circle-close
"
,
},
name
:
{
default
:
""
,
validator
,
},
disabled
:
Boolean
,
clearable
:
{
type
:
Boolean
,
default
:
true
,
},
id
:
{
default
:
""
,
validator
,
},
popperClass
:
String
,
editable
:
{
type
:
Boolean
,
default
:
true
,
},
align
:
{
type
:
String
,
default
:
"
left
"
,
},
value
:
{},
defaultValue
:
{},
defaultTime
:
{},
rangeSeparator
:
{
default
:
"
-
"
,
},
pickerOptions
:
{},
unlinkPanels
:
Boolean
,
validateEvent
:
{
type
:
Boolean
,
default
:
true
,
},
},
components
:
{
ElInput
},
directives
:
{
Clickoutside
},
data
()
{
return
{
pickerVisible
:
false
,
showClose
:
false
,
userInput
:
null
,
valueOnOpen
:
null
,
// value when picker opens, used to determine whether to emit change
unwatchPickerOptions
:
null
,
};
},
watch
:
{
pickerVisible
(
val
)
{
if
(
this
.
readonly
||
this
.
pickerDisabled
)
return
;
if
(
val
)
{
this
.
showPicker
();
this
.
valueOnOpen
=
Array
.
isArray
(
this
.
value
)
?
[...
this
.
value
]
:
this
.
value
;
}
else
{
this
.
hidePicker
();
this
.
emitChange
(
this
.
value
);
this
.
userInput
=
null
;
if
(
this
.
validateEvent
)
{
this
.
dispatch
(
"
ElFormItem
"
,
"
el.form.blur
"
);
}
this
.
$emit
(
"
blur
"
,
this
);
this
.
blur
();
}
},
parsedValue
:
{
immediate
:
true
,
handler
(
val
)
{
if
(
this
.
picker
)
{
this
.
picker
.
value
=
val
;
}
},
},
defaultValue
(
val
)
{
// NOTE: should eventually move to jsx style picker + panel ?
if
(
this
.
picker
)
{
this
.
picker
.
defaultValue
=
val
;
}
},
value
(
val
,
oldVal
)
{
if
(
!
valueEquals
(
val
,
oldVal
)
&&
!
this
.
pickerVisible
&&
this
.
validateEvent
)
{
this
.
dispatch
(
"
ElFormItem
"
,
"
el.form.change
"
,
val
);
}
},
},
computed
:
{
ranged
()
{
return
this
.
type
.
indexOf
(
"
range
"
)
>
-
1
;
},
reference
()
{
const
reference
=
this
.
$refs
.
reference
;
return
reference
.
$el
||
reference
;
},
refInput
()
{
if
(
this
.
reference
)
{
return
[].
slice
.
call
(
this
.
reference
.
querySelectorAll
(
"
input
"
));
}
return
[];
},
valueIsEmpty
()
{
const
val
=
this
.
value
;
if
(
Array
.
isArray
(
val
))
{
for
(
let
i
=
0
,
len
=
val
.
length
;
i
<
len
;
i
++
)
{
if
(
val
[
i
])
{
return
false
;
}
}
}
else
{
if
(
val
)
{
return
false
;
}
}
return
true
;
},
triggerClass
()
{
return
(
this
.
prefixIcon
||
(
this
.
type
.
indexOf
(
"
time
"
)
!==
-
1
?
"
el-icon-time
"
:
"
el-icon-date
"
)
);
},
selectionMode
()
{
if
(
this
.
type
===
"
week
"
)
{
return
"
week
"
;
}
else
if
(
this
.
type
===
"
month
"
)
{
return
"
month
"
;
}
else
if
(
this
.
type
===
"
year
"
)
{
return
"
year
"
;
}
else
if
(
this
.
type
===
"
dates
"
)
{
return
"
dates
"
;
}
else
if
(
this
.
type
===
"
months
"
)
{
return
"
months
"
;
}
else
if
(
this
.
type
===
"
years
"
)
{
return
"
years
"
;
}
return
"
day
"
;
},
haveTrigger
()
{
if
(
typeof
this
.
showTrigger
!==
"
undefined
"
)
{
return
this
.
showTrigger
;
}
return
HAVE_TRIGGER_TYPES
.
indexOf
(
this
.
type
)
!==
-
1
;
},
displayValue
()
{
const
formattedValue
=
formatAsFormatAndType
(
this
.
parsedValue
,
this
.
format
,
this
.
type
,
this
.
rangeSeparator
);
if
(
Array
.
isArray
(
this
.
userInput
))
{
return
[
this
.
userInput
[
0
]
||
(
formattedValue
&&
formattedValue
[
0
])
||
""
,
this
.
userInput
[
1
]
||
(
formattedValue
&&
formattedValue
[
1
])
||
""
,
];
}
else
if
(
this
.
userInput
!==
null
)
{
return
this
.
userInput
;
}
else
if
(
formattedValue
)
{
return
this
.
type
===
"
dates
"
||
this
.
type
===
"
years
"
||
this
.
type
===
"
months
"
?
formattedValue
.
join
(
"
,
"
)
:
formattedValue
;
}
else
{
return
""
;
}
},
parsedValue
()
{
if
(
!
this
.
value
)
return
this
.
value
;
// component value is not set
if
(
this
.
type
===
"
time-select
"
)
return
this
.
value
;
// time-select does not require parsing, this might change in next major version
const
valueIsDateObject
=
isDateObject
(
this
.
value
)
||
(
Array
.
isArray
(
this
.
value
)
&&
this
.
value
.
every
(
isDateObject
));
if
(
valueIsDateObject
)
{
return
this
.
value
;
}
if
(
this
.
valueFormat
)
{
return
(
parseAsFormatAndType
(
this
.
value
,
this
.
valueFormat
,
this
.
type
,
this
.
rangeSeparator
)
||
this
.
value
);
}
// NOTE: deal with common but incorrect usage, should remove in next major version
// user might provide string / timestamp without value-format, coerce them into date (or array of date)
return
Array
.
isArray
(
this
.
value
)
?
this
.
value
.
map
((
val
)
=>
new
Date
(
val
))
:
new
Date
(
this
.
value
);
},
_elFormItemSize
()
{
return
(
this
.
elFormItem
||
{}).
elFormItemSize
;
},
pickerSize
()
{
return
this
.
size
||
this
.
_elFormItemSize
||
(
this
.
$ELEMENT
||
{}).
size
;
},
pickerDisabled
()
{
return
this
.
disabled
||
(
this
.
elForm
||
{}).
disabled
;
},
firstInputId
()
{
const
obj
=
{};
let
id
;
if
(
this
.
ranged
)
{
id
=
this
.
id
&&
this
.
id
[
0
];
}
else
{
id
=
this
.
id
;
}
if
(
id
)
obj
.
id
=
id
;
return
obj
;
},
secondInputId
()
{
const
obj
=
{};
let
id
;
if
(
this
.
ranged
)
{
id
=
this
.
id
&&
this
.
id
[
1
];
}
if
(
id
)
obj
.
id
=
id
;
return
obj
;
},
},
created
()
{
// vue-popper
this
.
popperOptions
=
{
boundariesPadding
:
0
,
gpuAcceleration
:
false
,
};
this
.
placement
=
PLACEMENT_MAP
[
this
.
align
]
||
PLACEMENT_MAP
.
left
;
this
.
$on
(
"
fieldReset
"
,
this
.
handleFieldReset
);
},
mounted
()
{
this
.
showPicker
();
},
methods
:
{
focus
()
{
if
(
!
this
.
ranged
)
{
this
.
$refs
.
reference
.
focus
();
}
else
{
this
.
handleFocus
();
}
},
blur
()
{
this
.
refInput
.
forEach
((
input
)
=>
input
.
blur
());
},
// {parse, formatTo} Value deals maps component value with internal Date
parseValue
(
value
)
{
const
isParsed
=
isDateObject
(
value
)
||
(
Array
.
isArray
(
value
)
&&
value
.
every
(
isDateObject
));
if
(
this
.
valueFormat
&&
!
isParsed
)
{
return
(
parseAsFormatAndType
(
value
,
this
.
valueFormat
,
this
.
type
,
this
.
rangeSeparator
)
||
value
);
}
else
{
return
value
;
}
},
formatToValue
(
date
)
{
const
isFormattable
=
isDateObject
(
date
)
||
(
Array
.
isArray
(
date
)
&&
date
.
every
(
isDateObject
));
if
(
this
.
valueFormat
&&
isFormattable
)
{
return
formatAsFormatAndType
(
date
,
this
.
valueFormat
,
this
.
type
,
this
.
rangeSeparator
);
}
else
{
return
date
;
}
},
// {parse, formatTo} String deals with user input
parseString
(
value
)
{
const
type
=
Array
.
isArray
(
value
)
?
this
.
type
:
this
.
type
.
replace
(
"
range
"
,
""
);
return
parseAsFormatAndType
(
value
,
this
.
format
,
type
);
},
formatToString
(
value
)
{
const
type
=
Array
.
isArray
(
value
)
?
this
.
type
:
this
.
type
.
replace
(
"
range
"
,
""
);
return
formatAsFormatAndType
(
value
,
this
.
format
,
type
);
},
handleMouseEnter
()
{
if
(
this
.
readonly
||
this
.
pickerDisabled
)
return
;
if
(
!
this
.
valueIsEmpty
&&
this
.
clearable
)
{
this
.
showClose
=
true
;
}
},
handleChange
()
{
if
(
this
.
userInput
)
{
const
value
=
this
.
parseString
(
this
.
displayValue
);
if
(
value
)
{
this
.
picker
.
value
=
value
;
if
(
this
.
isValidValue
(
value
))
{
this
.
emitInput
(
value
);
this
.
userInput
=
null
;
}
}
}
if
(
this
.
userInput
===
""
)
{
this
.
emitInput
(
null
);
this
.
emitChange
(
null
);
this
.
userInput
=
null
;
}
},
handleStartInput
(
event
)
{
if
(
this
.
userInput
)
{
this
.
userInput
=
[
event
.
target
.
value
,
this
.
userInput
[
1
]];
}
else
{
this
.
userInput
=
[
event
.
target
.
value
,
null
];
}
},
handleEndInput
(
event
)
{
if
(
this
.
userInput
)
{
this
.
userInput
=
[
this
.
userInput
[
0
],
event
.
target
.
value
];
}
else
{
this
.
userInput
=
[
null
,
event
.
target
.
value
];
}
},
handleStartChange
(
event
)
{
const
value
=
this
.
parseString
(
this
.
userInput
&&
this
.
userInput
[
0
]);
if
(
value
)
{
this
.
userInput
=
[
this
.
formatToString
(
value
),
this
.
displayValue
[
1
]];
const
newValue
=
[
value
,
this
.
picker
.
value
&&
this
.
picker
.
value
[
1
]];
this
.
picker
.
value
=
newValue
;
if
(
this
.
isValidValue
(
newValue
))
{
this
.
emitInput
(
newValue
);
this
.
userInput
=
null
;
}
}
},
handleEndChange
(
event
)
{
const
value
=
this
.
parseString
(
this
.
userInput
&&
this
.
userInput
[
1
]);
if
(
value
)
{
this
.
userInput
=
[
this
.
displayValue
[
0
],
this
.
formatToString
(
value
)];
const
newValue
=
[
this
.
picker
.
value
&&
this
.
picker
.
value
[
0
],
value
];
this
.
picker
.
value
=
newValue
;
if
(
this
.
isValidValue
(
newValue
))
{
this
.
emitInput
(
newValue
);
this
.
userInput
=
null
;
}
}
},
handleClickIcon
(
event
)
{
if
(
this
.
readonly
||
this
.
pickerDisabled
)
return
;
if
(
this
.
showClose
)
{
this
.
valueOnOpen
=
this
.
value
;
event
.
stopPropagation
();
this
.
emitInput
(
null
);
this
.
emitChange
(
null
);
this
.
showClose
=
false
;
if
(
this
.
picker
&&
typeof
this
.
picker
.
handleClear
===
"
function
"
)
{
this
.
picker
.
handleClear
();
}
}
else
{
this
.
pickerVisible
=
!
this
.
pickerVisible
;
}
},
handleClose
()
{
if
(
!
this
.
pickerVisible
)
return
;
this
.
pickerVisible
=
false
;
if
(
this
.
type
===
"
dates
"
||
this
.
type
===
"
years
"
||
this
.
type
===
"
months
"
)
{
// restore to former value
const
oldValue
=
parseAsFormatAndType
(
this
.
valueOnOpen
,
this
.
valueFormat
,
this
.
type
,
this
.
rangeSeparator
)
||
this
.
valueOnOpen
;
this
.
emitInput
(
oldValue
);
}
},
handleFieldReset
(
initialValue
)
{
this
.
userInput
=
initialValue
===
""
?
null
:
initialValue
;
},
handleFocus
()
{
const
type
=
this
.
type
;
if
(
HAVE_TRIGGER_TYPES
.
indexOf
(
type
)
!==
-
1
&&
!
this
.
pickerVisible
)
{
this
.
pickerVisible
=
true
;
}
this
.
$emit
(
"
focus
"
,
this
);
},
handleKeydown
(
event
)
{
const
keyCode
=
event
.
keyCode
;
// ESC
if
(
keyCode
===
27
)
{
this
.
pickerVisible
=
false
;
event
.
stopPropagation
();
return
;
}
// Tab
if
(
keyCode
===
9
)
{
if
(
!
this
.
ranged
)
{
this
.
handleChange
();
this
.
pickerVisible
=
this
.
picker
.
visible
=
false
;
this
.
blur
();
event
.
stopPropagation
();
}
else
{
// user may change focus between two input
setTimeout
(()
=>
{
if
(
this
.
refInput
.
indexOf
(
document
.
activeElement
)
===
-
1
)
{
this
.
pickerVisible
=
false
;
this
.
blur
();
event
.
stopPropagation
();
}
},
0
);
}
return
;
}
// Enter
if
(
keyCode
===
13
)
{
if
(
this
.
userInput
===
""
||
this
.
isValidValue
(
this
.
parseString
(
this
.
displayValue
))
)
{
this
.
handleChange
();
this
.
pickerVisible
=
this
.
picker
.
visible
=
false
;
this
.
blur
();
}
event
.
stopPropagation
();
return
;
}
// if user is typing, do not let picker handle key input
if
(
this
.
userInput
)
{
event
.
stopPropagation
();
return
;
}
// delegate other keys to panel
if
(
this
.
picker
&&
this
.
picker
.
handleKeydown
)
{
this
.
picker
.
handleKeydown
(
event
);
}
},
handleRangeClick
()
{
const
type
=
this
.
type
;
if
(
HAVE_TRIGGER_TYPES
.
indexOf
(
type
)
!==
-
1
&&
!
this
.
pickerVisible
)
{
this
.
pickerVisible
=
true
;
}
this
.
$emit
(
"
focus
"
,
this
);
},
hidePicker
()
{
if
(
this
.
picker
)
{
this
.
picker
.
resetView
&&
this
.
picker
.
resetView
();
this
.
pickerVisible
=
this
.
picker
.
visible
=
false
;
// this.destroyPopper();
}
},
showPicker
()
{
if
(
this
.
$isServer
)
return
;
if
(
!
this
.
picker
)
{
this
.
mountPicker
();
}
this
.
pickerVisible
=
this
.
picker
.
visible
=
true
;
// this.updatePopper();
this
.
picker
.
value
=
this
.
parsedValue
;
this
.
picker
.
resetView
&&
this
.
picker
.
resetView
();
this
.
$nextTick
(()
=>
{
this
.
picker
.
adjustSpinners
&&
this
.
picker
.
adjustSpinners
();
});
},
mountPicker
()
{
this
.
picker
=
new
Vue
(
this
.
panel
).
$mount
();
this
.
picker
.
defaultValue
=
this
.
defaultValue
;
this
.
picker
.
defaultTime
=
this
.
defaultTime
;
this
.
picker
.
popperClass
=
this
.
popperClass
;
this
.
popperElm
=
this
.
picker
.
$el
;
this
.
picker
.
width
=
this
.
reference
.
getBoundingClientRect
().
width
;
this
.
picker
.
showTime
=
this
.
type
===
"
datetime
"
||
this
.
type
===
"
datetimerange
"
;
this
.
picker
.
selectionMode
=
this
.
selectionMode
;
this
.
picker
.
unlinkPanels
=
this
.
unlinkPanels
;
this
.
picker
.
arrowControl
=
this
.
arrowControl
||
this
.
timeArrowControl
||
false
;
this
.
$watch
(
"
format
"
,
(
format
)
=>
{
this
.
picker
.
format
=
format
;
});
const
updateOptions
=
()
=>
{
const
options
=
this
.
pickerOptions
;
if
(
options
&&
options
.
selectableRange
)
{
let
ranges
=
options
.
selectableRange
;
const
parser
=
TYPE_VALUE_RESOLVER_MAP
.
datetimerange
.
parser
;
const
format
=
DEFAULT_FORMATS
.
timerange
;
ranges
=
Array
.
isArray
(
ranges
)
?
ranges
:
[
ranges
];
this
.
picker
.
selectableRange
=
ranges
.
map
((
range
)
=>
parser
(
range
,
format
,
this
.
rangeSeparator
)
);
}
for
(
const
option
in
options
)
{
if
(
options
.
hasOwnProperty
(
option
)
&&
// 忽略 time-picker 的该配置项
option
!==
"
selectableRange
"
)
{
this
.
picker
[
option
]
=
options
[
option
];
}
}
// main format must prevail over undocumented pickerOptions.format
if
(
this
.
format
)
{
this
.
picker
.
format
=
this
.
format
;
}
};
updateOptions
();
this
.
unwatchPickerOptions
=
this
.
$watch
(
"
pickerOptions
"
,
()
=>
updateOptions
(),
{
deep
:
true
}
);
this
.
$el
.
appendChild
(
this
.
picker
.
$el
);
this
.
picker
.
resetView
&&
this
.
picker
.
resetView
();
this
.
picker
.
$on
(
"
dodestroy
"
,
this
.
doDestroy
);
this
.
picker
.
$on
(
"
pick
"
,
(
date
=
""
,
visible
=
false
)
=>
{
this
.
userInput
=
null
;
// this.pickerVisible = this.picker.visible = visible;
this
.
emitInput
(
date
);
this
.
picker
.
resetView
&&
this
.
picker
.
resetView
();
});
// this.picker.$on("select-range", (start, end, pos) => {
// if (this.refInput.length === 0) return;
// if (!pos || pos === "min") {
// this.refInput[0].setSelectionRange(start, end);
// this.refInput[0].focus();
// } else if (pos === "max") {
// this.refInput[1].setSelectionRange(start, end);
// this.refInput[1].focus();
// }
// });
},
unmountPicker
()
{
if
(
this
.
picker
)
{
this
.
picker
.
$destroy
();
this
.
picker
.
$off
();
if
(
typeof
this
.
unwatchPickerOptions
===
"
function
"
)
{
this
.
unwatchPickerOptions
();
}
this
.
picker
.
$el
.
parentNode
.
removeChild
(
this
.
picker
.
$el
);
}
},
emitChange
(
val
)
{
// determine user real change only
if
(
!
valueEquals
(
val
,
this
.
valueOnOpen
))
{
this
.
$emit
(
"
change
"
,
val
);
this
.
valueOnOpen
=
val
;
if
(
this
.
validateEvent
)
{
this
.
dispatch
(
"
ElFormItem
"
,
"
el.form.change
"
,
val
);
}
}
},
emitInput
(
val
)
{
const
formatted
=
this
.
formatToValue
(
val
);
if
(
!
valueEquals
(
this
.
value
,
formatted
))
{
this
.
$emit
(
"
input
"
,
formatted
);
}
},
isValidValue
(
value
)
{
if
(
!
this
.
picker
)
{
this
.
mountPicker
();
}
if
(
this
.
picker
.
isValidValue
)
{
return
value
&&
this
.
picker
.
isValidValue
(
value
);
}
else
{
return
true
;
}
},
},
};
</
script
>
admin_2/src/components/YDatePickerTab/date-picker/src/picker/date-picker.js
0 → 100644
View file @
6f2cf656
import
Picker
from
"
../picker.vue
"
;
import
DatePanel
from
"
../panel/date
"
;
import
DateRangePanel
from
"
../panel/date-range
"
;
import
MonthRangePanel
from
"
../panel/month-range
"
;
const
getPanel
=
function
(
type
)
{
if
(
type
===
"
daterange
"
||
type
===
"
datetimerange
"
)
{
return
DateRangePanel
;
}
else
if
(
type
===
"
monthrange
"
)
{
return
MonthRangePanel
;
}
return
DatePanel
;
};
export
default
{
mixins
:
[
Picker
],
name
:
"
DatePicker
"
,
props
:
{
type
:
{
type
:
String
,
default
:
"
date
"
,
},
timeArrowControl
:
Boolean
,
},
watch
:
{
type
(
type
)
{
if
(
this
.
picker
)
{
this
.
unmountPicker
();
this
.
panel
=
getPanel
(
type
);
this
.
mountPicker
();
}
else
{
this
.
panel
=
getPanel
(
type
);
}
},
},
created
()
{
this
.
panel
=
getPanel
(
this
.
type
);
},
};
admin_2/src/components/YDatePickerTab/date-picker/src/picker/time-picker.js
0 → 100644
View file @
6f2cf656
import
Picker
from
'
../picker
'
;
import
TimePanel
from
'
../panel/time
'
;
import
TimeRangePanel
from
'
../panel/time-range
'
;
export
default
{
mixins
:
[
Picker
],
name
:
'
ElTimePicker
'
,
props
:
{
isRange
:
Boolean
,
arrowControl
:
Boolean
},
data
()
{
return
{
type
:
''
};
},
watch
:
{
isRange
(
isRange
)
{
if
(
this
.
picker
)
{
this
.
unmountPicker
();
this
.
type
=
isRange
?
'
timerange
'
:
'
time
'
;
this
.
panel
=
isRange
?
TimeRangePanel
:
TimePanel
;
this
.
mountPicker
();
}
else
{
this
.
type
=
isRange
?
'
timerange
'
:
'
time
'
;
this
.
panel
=
isRange
?
TimeRangePanel
:
TimePanel
;
}
}
},
created
()
{
this
.
type
=
this
.
isRange
?
'
timerange
'
:
'
time
'
;
this
.
panel
=
this
.
isRange
?
TimeRangePanel
:
TimePanel
;
}
};
admin_2/src/components/YDatePickerTab/date-picker/src/picker/time-select.js
0 → 100644
View file @
6f2cf656
import
Picker
from
'
../picker
'
;
import
Panel
from
'
../panel/time-select
'
;
export
default
{
mixins
:
[
Picker
],
name
:
'
ElTimeSelect
'
,
componentName
:
'
ElTimeSelect
'
,
props
:
{
type
:
{
type
:
String
,
default
:
'
time-select
'
}
},
beforeCreate
()
{
this
.
panel
=
Panel
;
}
};
admin_2/src/main.js
View file @
6f2cf656
...
@@ -49,8 +49,8 @@ Vue.prototype.$clearSelection = clearSelection;
...
@@ -49,8 +49,8 @@ Vue.prototype.$clearSelection = clearSelection;
import
{
cloneDeep
}
from
'
lodash-es
'
;
import
{
cloneDeep
}
from
'
lodash-es
'
;
Vue
.
prototype
.
$cloneDeep
=
cloneDeep
;
Vue
.
prototype
.
$cloneDeep
=
cloneDeep
;
import
DatePicker
from
'
@/pages/engineSearch/components/date-picker
'
;
//
import DatePicker from '@/pages/engineSearch/components/date-picker';
Vue
.
use
(
DatePicker
);
//
Vue.use(DatePicker);
Vue
.
config
.
productionTip
=
false
;
Vue
.
config
.
productionTip
=
false
;
new
Vue
({
new
Vue
({
...
...
admin_2/src/pages/engineSearch/components/Search.vue
View file @
6f2cf656
...
@@ -210,8 +210,11 @@
...
@@ -210,8 +210,11 @@
<
script
>
<
script
>
import
{
findBottomSubarrays
}
from
'
@/utils
'
;
import
{
findBottomSubarrays
}
from
'
@/utils
'
;
import
DatePicker
from
'
./date-picker
'
;
export
default
{
export
default
{
components
:
{},
components
:
{
DatePicker
},
props
:
{
props
:
{
dict
:
{
dict
:
{
required
:
true
,
required
:
true
,
...
...
admin_2/src/pages/system/menu/components/AddMenu.vue
View file @
6f2cf656
...
@@ -2,7 +2,6 @@
...
@@ -2,7 +2,6 @@
<div>
<div>
<el-dialog
<el-dialog
:title=
"title"
:title=
"title"
:destroy-on-close=
"true"
:visible.sync=
"Visible"
:visible.sync=
"Visible"
width=
"650px"
width=
"650px"
@
close=
"handleClose"
@
close=
"handleClose"
...
@@ -140,6 +139,44 @@
...
@@ -140,6 +139,44 @@
</el-form-item>
</el-form-item>
</el-col>
</el-col>
</el-row>
</el-row>
<el-row>
<el-col
:span=
"24"
>
<el-form-item
label=
"资源类型"
prop=
"resourceType"
>
<el-radio-group
v-model=
"form.resourceType"
>
<el-radio
:label=
"1"
>
从资源列表获取
</el-radio>
<el-radio
:label=
"2"
>
自定义资源地址
</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col
:span=
"24"
v-show=
"form.resourceType == 1"
>
<el-form-item
label=
"资源"
prop=
"resourceUrl"
>
<select-res
v-model=
"form.resourceUrl"
:clearable=
"false"
></select-res>
</el-form-item>
</el-col>
<el-col
:span=
"24"
v-show=
"form.resourceType == 2"
>
<el-form-item
class=
"url-params-box"
label=
"资源"
>
<el-form-item
class=
"url-params"
v-for=
"(v, i) in form.urls"
:key=
"i"
:prop=
"`urls.$
{i}.value`"
:rules="[{ required: false, validator: validatorUrl, trigger: 'blur' }]"
>
<el-input
class=
"mr-[10px]"
v-model=
"v.value"
placeholder=
"请输入链接地址"
/>
<div
class=
"flex"
>
<el-button
type=
"primary"
@
click=
"changeParams(i, 'add')"
>
<i
class=
"el-icon-plus"
></i>
</el-button>
<el-button
type=
"danger"
v-if=
"i > 0"
@
click=
"changeParams(i, 'remove')"
><i
class=
"el-icon-minus"
></i
></el-button>
</div>
</el-form-item>
</el-form-item>
</el-col>
</el-row>
</el-form>
</el-form>
<span
slot=
"footer"
class=
"dialog-footer"
>
<span
slot=
"footer"
class=
"dialog-footer"
>
<el-button
size=
"medium"
@
click=
"handleRest"
>
重 置
</el-button>
<el-button
size=
"medium"
@
click=
"handleRest"
>
重 置
</el-button>
...
@@ -153,14 +190,15 @@
...
@@ -153,14 +190,15 @@
<
script
>
<
script
>
import
{
saveMenu
}
from
'
@/api/system
'
;
import
{
saveMenu
}
from
'
@/api/system
'
;
import
IconSelect
from
'
./IconSelect.vue
'
;
import
IconSelect
from
'
@/components/IconSelect/IconSelect
'
;
import
iconJson
from
'
@/assets/icon.json
'
;
import
SelectRes
from
'
./SelectRes.vue
'
;
import
Treeselect
from
'
@riophae/vue-treeselect
'
;
import
Treeselect
from
'
@riophae/vue-treeselect
'
;
import
'
@riophae/vue-treeselect/dist/vue-treeselect.css
'
;
import
'
@riophae/vue-treeselect/dist/vue-treeselect.css
'
;
export
default
{
export
default
{
components
:
{
components
:
{
IconSelect
,
IconSelect
,
Treeselect
Treeselect
,
SelectRes
},
},
props
:
{
props
:
{
title
:
{
title
:
{
...
@@ -186,7 +224,6 @@ export default {
...
@@ -186,7 +224,6 @@ export default {
},
},
data
()
{
data
()
{
return
{
return
{
iconJson
,
loading
:
false
,
loading
:
false
,
defaultProps
:
{
defaultProps
:
{
children
:
'
childList
'
,
children
:
'
childList
'
,
...
@@ -195,7 +232,7 @@ export default {
...
@@ -195,7 +232,7 @@ export default {
form
:
{
form
:
{
name
:
''
,
// 菜单名称
name
:
''
,
// 菜单名称
url
:
''
,
// 路由地址
url
:
''
,
// 路由地址
ancestors
:
''
,
// 当前
激活根目录
ancestors
:
''
,
// 当前
节点父id路径,“,”分割
parentId
:
0
,
// 父菜单ID,一级菜单的该字段值为-1
parentId
:
0
,
// 父菜单ID,一级菜单的该字段值为-1
linkType
:
0
,
// 链接方式 (0.普通,1.弹出,2.脚本)
linkType
:
0
,
// 链接方式 (0.普通,1.弹出,2.脚本)
imgPath
:
''
,
// 主菜单图标,主菜单图标的css样式名
imgPath
:
''
,
// 主菜单图标,主菜单图标的css样式名
...
@@ -212,7 +249,14 @@ export default {
...
@@ -212,7 +249,14 @@ export default {
status
:
1
,
// 菜单状态 (0.停用,1.启用)
status
:
1
,
// 菜单状态 (0.停用,1.启用)
cache
:
0
,
// 是否缓存
cache
:
0
,
// 是否缓存
activeDir
:
''
,
// 激活菜单
activeDir
:
''
,
// 激活菜单
hideChildrenInMenu
:
1
// 是否隐藏子菜单
resourceType
:
1
,
// 资源类型 (1.按资源id,1.链接地址)
resourceUrl
:
[],
// 资源id或者路径
hideChildrenInMenu
:
1
,
// 是否隐藏子菜单
urls
:
[
{
value
:
''
}
]
},
},
rules
:
{
rules
:
{
name
:
[{
required
:
true
,
message
:
'
请输入菜单名称
'
,
trigger
:
'
blur
'
}],
name
:
[{
required
:
true
,
message
:
'
请输入菜单名称
'
,
trigger
:
'
blur
'
}],
...
@@ -238,7 +282,19 @@ export default {
...
@@ -238,7 +282,19 @@ export default {
this
.
$refs
.
form
.
validate
(
async
(
valid
)
=>
{
this
.
$refs
.
form
.
validate
(
async
(
valid
)
=>
{
if
(
valid
)
{
if
(
valid
)
{
this
.
loading
=
true
;
this
.
loading
=
true
;
let
res
=
await
saveMenu
(
this
.
form
);
let
resourceUrl
;
let
form
=
{
...
this
.
form
};
if
(
this
.
form
.
resourceType
===
1
)
{
resourceUrl
=
this
.
form
.
resourceUrl
.
join
(
'
,
'
);
}
else
{
resourceUrl
=
this
.
form
.
urls
.
map
((
v
)
=>
v
.
value
).
join
(
'
,
'
);
}
this
.
$delete
(
form
,
'
resourceType
'
);
this
.
$delete
(
form
,
'
urls
'
);
let
res
=
await
saveMenu
({
...
form
,
resourceUrl
});
let
{
code
,
msg
}
=
res
.
data
;
let
{
code
,
msg
}
=
res
.
data
;
if
(
code
===
1
)
{
if
(
code
===
1
)
{
this
.
$message
.
success
(
msg
);
this
.
$message
.
success
(
msg
);
...
@@ -258,8 +314,29 @@ export default {
...
@@ -258,8 +314,29 @@ export default {
onEdit
(
row
)
{
onEdit
(
row
)
{
setTimeout
(()
=>
{
setTimeout
(()
=>
{
this
.
form
=
{
...
row
};
this
.
form
=
{
...
row
};
this
.
$set
(
this
.
form
,
'
resourceType
'
,
1
);
this
.
$set
(
this
.
form
,
'
urls
'
,
[{
value
:
''
}]);
this
.
form
.
resourceUrl
=
[];
if
(
row
.
resourceUrl
)
{
let
arr
=
row
.
resourceUrl
.
split
(
'
,
'
);
if
(
this
.
isUrl
(
row
.
resourceUrl
))
{
this
.
form
.
urls
=
arr
.
map
((
v
)
=>
{
return
{
value
:
v
};
});
this
.
form
.
resourceType
=
2
;
this
.
form
.
resourceUrl
=
arr
;
}
else
{
this
.
form
.
resourceUrl
=
arr
.
map
(
Number
);
}
}
},
10
);
},
10
);
},
},
// 判断资源是否是链接
isUrl
(
val
)
{
return
val
.
startsWith
(
'
/
'
);
},
// 重置
// 重置
handleRest
()
{
handleRest
()
{
this
.
$resetForm
(
'
form
'
);
this
.
$resetForm
(
'
form
'
);
...
@@ -280,19 +357,55 @@ export default {
...
@@ -280,19 +357,55 @@ export default {
children
:
node
.
childList
children
:
node
.
childList
};
};
},
},
changeParent
(
row
)
{
// 判断是否存在链接
console
.
log
(
row
);
isRepeat
(
val
)
{
return
this
.
form
.
urls
.
filter
((
v
)
=>
v
.
value
==
val
).
length
>
1
;
},
// 校验链接地址
validatorUrl
(
rule
,
value
,
callback
)
{
if
(
!
value
)
{
if
(
rule
.
required
)
{
callback
(
new
Error
(
'
请输入链接
'
));
}
else
{
callback
();
}
}
else
if
(
this
.
isRepeat
(
value
))
{
callback
(
new
Error
(
'
重复的链接地址
'
));
}
else
{
callback
();
}
},
changeParams
(
index
,
type
)
{
if
(
type
==
'
add
'
)
{
let
obj
=
{
value
:
''
};
if
(
this
.
form
.
urls
.
some
((
v
)
=>
!
v
.
value
))
{
this
.
$message
.
warning
(
'
请先完成前面地址的填写
'
);
return
;
}
this
.
form
.
urls
.
splice
(
index
+
1
,
0
,
obj
);
}
else
{
this
.
form
.
urls
.
splice
(
index
,
1
);
}
// this.$forceUpdate();
}
}
}
}
};
};
</
script
>
</
script
>
<
style
lang=
"less"
scoped
>
<
style
lang=
"less"
scoped
>
//
:deep(.el-dialog__body) {
:deep(.el-dialog__body) {
// max-height: 60
0px;
max-height: 65
0px;
//
overflow: auto;
overflow: auto;
//
}
}
:deep(.el-select) {
:deep(.el-select) {
width: 100%;
width: 100%;
}
}
:deep(.url-params) {
margin-bottom: 22px;
.el-form-item__content {
display: flex;
}
}
</
style
>
</
style
>
admin_2/src/pages/system/menu/components/SelectRes.vue
0 → 100644
View file @
6f2cf656
<
template
>
<div
class=
"w-full"
>
<el-cascader
clearable
filterable
:value=
"value"
placeholder=
"请选择资源"
:options=
"resourceList"
:props=
"
{
value: 'id',
label: 'name',
multiple: true,
emitPath: false,
expandTrigger: 'hover'
}"
v-bind="$attrs"
v-on="$listeners"
@change="handleChange"
>
</el-cascader>
</div>
</
template
>
<
script
>
import
{
getResourceGroup
}
from
'
@/api/system
'
;
export
default
{
model
:
{
prop
:
'
value
'
,
event
:
'
change
'
},
props
:
{
value
:
{
default
:
''
},
dict
:
{
type
:
Object
,
default
:
()
=>
{}
},
form
:
{
type
:
Object
,
default
:
()
=>
{}
}
},
data
()
{
return
{
resourceList
:
[]
// 资源列表
};
},
created
()
{
this
.
getResourceGroup
();
},
methods
:
{
// 获取资源列表
async
getResourceGroup
()
{
this
.
loading
=
true
;
let
res
=
await
getResourceGroup
({
page
:
1
,
size
:
-
1
});
if
(
res
.
data
.
code
==
1
)
{
let
{
data
}
=
res
.
data
.
data
;
this
.
resourceList
=
this
.
formatGroup
(
data
);
}
},
// 格式化分组
formatGroup
(
data
)
{
let
arr
=
[];
Object
.
keys
(
data
).
forEach
((
key
,
index
)
=>
{
let
group
=
{};
group
=
{
name
:
key
,
id
:
-
index
,
children
:
[]
};
group
.
children
.
push
(...
data
[
key
]);
arr
.
push
(
group
);
});
return
arr
;
},
handleChange
(
value
)
{
this
.
$emit
(
'
change
'
,
value
);
}
}
};
</
script
>
<
style
lang=
"less"
scoped
>
:deep(.el-cascader) {
width: 100%;
}
</
style
>
admin_2/src/pages/system/resourceManage/components/AddResource.vue
View file @
6f2cf656
...
@@ -193,6 +193,7 @@ export default {
...
@@ -193,6 +193,7 @@ export default {
width: 100%;
width: 100%;
}
}
:deep(.url-params) {
:deep(.url-params) {
margin-bottom: 22px;
.el-form-item__content {
.el-form-item__content {
display: flex;
display: flex;
}
}
...
...
admin_2/src/utils/request.js
View file @
6f2cf656
...
@@ -29,7 +29,7 @@ function resSuccess(response) {
...
@@ -29,7 +29,7 @@ function resSuccess(response) {
if
(
response
.
data
.
code
!==
undefined
&&
response
.
data
.
msg
!==
undefined
)
{
if
(
response
.
data
.
code
!==
undefined
&&
response
.
data
.
msg
!==
undefined
)
{
// 取出数据
// 取出数据
let
{
code
,
msg
}
=
response
.
data
;
let
{
code
,
msg
}
=
response
.
data
;
if
(
code
==
-
1
)
{
if
(
code
==
-
1
||
code
==
405
)
{
message
.
error
({
message
.
error
({
message
:
msg
message
:
msg
});
});
...
...
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