Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wx-school-app
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
姜雷
wx-school-app
Commits
446a9198
Commit
446a9198
authored
Jul 26, 2019
by
姜雷
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
添加交互逻辑
parent
f3f7f84b
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
670 additions
and
167 deletions
+670
-167
shower.ts
src/api/shower.ts
+179
-2
app.tsx
src/app.tsx
+2
-2
useInputValue.ts
src/hooks/useInputValue.ts
+22
-0
Home.tsx
src/pages/Home/Home.tsx
+11
-1
ShowerAppointment.scss
src/pages/Shower/ShowerAppointment.scss
+4
-47
ShowerAppointment.tsx
src/pages/Shower/ShowerAppointment.tsx
+120
-108
AppointermentCard.scss
...hower/components/AppointermentCard/AppointermentCard.scss
+3
-0
AppointermentCard.tsx
...Shower/components/AppointermentCard/AppointermentCard.tsx
+14
-7
AppointermentEquipment.scss
...onents/AppointermentEquipment/AppointermentEquipment.scss
+52
-0
AppointermentEquipment.tsx
...ponents/AppointermentEquipment/AppointermentEquipment.tsx
+46
-0
useAppointRecordsList.ts
src/pages/Shower/hooks/useAppointRecordsList.ts
+78
-0
useCheckAppointable.ts
src/pages/Shower/hooks/useCheckAppointable.ts
+44
-0
useDeviceList.ts
src/pages/Shower/hooks/useDeviceList.ts
+54
-0
reducers.ts
src/store/reducers.ts
+2
-0
shower.ts
src/store/rootReducers/shower.ts
+39
-0
No files found.
src/api/shower.ts
View file @
446a9198
...
@@ -65,13 +65,28 @@ type ControllerParams = {
...
@@ -65,13 +65,28 @@ type ControllerParams = {
customerId
:
number
;
customerId
:
number
;
campusId
:
number
;
campusId
:
number
;
};
};
type
ControllerResponse
=
{
type
Balance
=
{
amount
:
number
;
// allowEmptyValue: false
// 服务数量
serviceId
:
string
;
// allowEmptyValue: false
// 服务id -1:授信额度;0:艾米;1:豆
serviceName
:
string
;
// allowEmptyValue: false
// 服务名称
};
export
type
ControllerResponse
=
{
appointmentThresholdPrompt
:
string
;
balances
:
Balance
[];
beanAmount
:
number
;
beanAmount
:
number
;
defaultType
:
ShowerUseType
;
money
:
number
;
money
:
number
;
thresholdPrompt
:
string
;
thresholdPrompt
:
string
;
thresholdValue
:
number
;
thresholdValue
:
number
;
useType
:
ShowerUseType
;
useType
:
ShowerUseType
;
defaultType
:
ShowerUseType
;
};
};
export
const
getShowerController
=
(
export
const
getShowerController
=
(
...
@@ -81,3 +96,165 @@ export const getShowerController = (
...
@@ -81,3 +96,165 @@ export const getShowerController = (
url
:
'/dcxy/api/shower/controllerConfigs'
,
url
:
'/dcxy/api/shower/controllerConfigs'
,
data
:
params
,
data
:
params
,
});
});
type
AppointDeviceParam
=
{
userId
:
number
;
campusId
:
number
;
location
?:
string
;
pageNum
?:
number
;
pageSize
?:
number
;
};
export
type
AppointDeviceResponse
=
{
appointable
:
boolean
;
// example: false
// allowEmptyValue: false
// 是否可预约
code
:
string
;
// allowEmptyValue: false
// 设备编号
inPunishment
:
boolean
;
// example: false
// allowEmptyValue: false
// 用户是在惩罚中
location
:
string
;
// allowEmptyValue: false
// 设备位置
operationMode
:
number
;
// allowEmptyValue: false
// 设备计费模式
};
export
const
getAppointmentDevice
=
(
params
:
AppointDeviceParam
,
):
Promise
<
ResponseDataEntity
<
{
list
:
AppointDeviceResponse
[]
}
>>
=>
showerFetch
({
url
:
'/dcxy/api/shower/appointment/devices'
,
data
:
params
,
});
type
AppointingParams
=
{
account
:
string
;
// allowEmptyValue: false
// 登录账号
deviceCode
:
string
;
// allowEmptyValue: false
// 设备编号
phone
:
string
;
// allowEmptyValue: false
// 手机号
userId
:
number
;
// allowEmptyValue: false
// 用户ID
userName
:
string
;
// allowEmptyValue: false
// 用户名称
};
export
const
appointingEquipment
=
(
params
:
AppointingParams
)
=>
showerFetch
({
url
:
'/dcxy/api/shower/appointment/appointing'
,
method
:
'POST'
,
data
:
params
,
});
type
AppointmentRecordsParams
=
{
pageNum
?:
number
;
// 当前页码
pageSize
?:
number
;
// 页面大小
orderSort
?:
string
;
// 排序
userId
:
number
;
// 用户ID
appointTimeStart
?:
string
;
// 预约时间区间上限
appointTimeEnd
?:
string
;
// 预约时间区间下限
};
export
type
AppointmentRecordsResponse
=
{
appointTime
:
string
;
// allowEmptyValue: false
// 预约时间
campusName
:
string
;
// allowEmptyValue: false
// 所属区域
deviceCode
:
string
;
// allowEmptyValue: false
// 设备编号
deviceLocation
:
string
;
// allowEmptyValue: false
// 设备位置
expireTime
:
string
;
// allowEmptyValue: false
// 到期时间
status
:
number
;
// allowEmptyValue: false
// 状态: 0-预约中,1-预约成功,2-使用中,3-完成,4-预约失败,5-失效(逾期未使用)
used
:
boolean
;
// example: false
// allowEmptyValue: false
// 是否使用
};
export
const
getAppointmentRecords
=
(
params
:
AppointmentRecordsParams
,
):
Promise
<
ResponseDataEntity
<
{
list
:
AppointmentRecordsResponse
[]
}
>>
=>
showerFetch
({
url
:
'/dcxy/api/shower/appointment/appointRecords'
,
data
:
params
,
});
type
UserAppointableParams
=
{
userId
:
number
;
campusId
:
number
;
};
export
type
UserAppointableData
=
{
appointMode
:
number
;
// allowEmptyValue: false
// 校验结果:0-校区未启用预约功能,1-校区未设置惩罚时长,2-用户未在惩罚中,3-用户在惩罚中
defaultType
:
number
;
// allowEmptyValue: false
// 混合模式时的默认使用模式
duration
:
number
;
// allowEmptyValue: false
// 预约有效时长
message
:
string
;
// allowEmptyValue: false
// 被禁用时提示消息
punishment
:
number
;
// allowEmptyValue: false
// 系统惩罚时长
useType
:
number
;
// allowEmptyValue: false
// 使用模式: 1-蓝牙,2-预约,3-混合
userPunishment
:
number
;
// allowEmptyValue: false
// 用户剩余惩罚时长
};
export
const
getUserAppointableData
=
(
params
:
UserAppointableParams
,
):
Promise
<
ResponseDataEntity
<
UserAppointableData
>>
=>
showerFetch
({
url
:
`/dcxy/api/shower/appointment/user/
${
params
.
userId
}
/appointable/
${
params
.
campusId
}
`
,
});
src/app.tsx
View file @
446a9198
...
@@ -24,7 +24,7 @@ class App extends Component {
...
@@ -24,7 +24,7 @@ class App extends Component {
*/
*/
config
:
Config
=
{
config
:
Config
=
{
pages
:
[
pages
:
[
'pages/Shower/ShowerAppointment'
,
//
'pages/Shower/ShowerAppointment',
'pages/index/index'
,
'pages/index/index'
,
'pages/Home/Home'
,
'pages/Home/Home'
,
'pages/Order/OrderPay/OrderPay'
,
'pages/Order/OrderPay/OrderPay'
,
...
@@ -41,7 +41,7 @@ class App extends Component {
...
@@ -41,7 +41,7 @@ class App extends Component {
'pages/Content/Content'
,
'pages/Content/Content'
,
'pages/WebPage/WebPage'
,
'pages/WebPage/WebPage'
,
'pages/Shower/Shower'
,
'pages/Shower/Shower'
,
//
'pages/Shower/ShowerAppointment',
'pages/Shower/ShowerAppointment'
,
'pages/WaterDispenser/WaterDispenser'
,
'pages/WaterDispenser/WaterDispenser'
,
'pages/Account/Account'
,
'pages/Account/Account'
,
],
],
...
...
src/hooks/useInputValue.ts
0 → 100644
View file @
446a9198
import
{
useState
,
useCallback
}
from
'@tarojs/taro'
;
import
{
BaseEventOrig
}
from
'@tarojs/components/types/common'
;
function
useInputValue
(
initialValue
:
string
)
{
let
[
value
,
setValue
]
=
useState
(
initialValue
);
let
onChange
=
useCallback
(
function
(
event
:
BaseEventOrig
<
{
value
:
string
;
cursor
:
number
;
keyCode
:
number
;
}
>
,
)
{
setValue
(
event
.
detail
.
value
);
},
[]);
return
{
value
,
onChange
,
};
}
export
default
useInputValue
;
src/pages/Home/Home.tsx
View file @
446a9198
...
@@ -38,7 +38,12 @@ import MenuIconNormal from '@/components/MenuIcon/normal/MenuIconNormal';
...
@@ -38,7 +38,12 @@ import MenuIconNormal from '@/components/MenuIcon/normal/MenuIconNormal';
import
MenuIconBlock
from
'@/components/MenuIcon/block/MenuIconBlock'
;
import
MenuIconBlock
from
'@/components/MenuIcon/block/MenuIconBlock'
;
import
MenuIconBig
from
'@/components/MenuIcon/big/MenuIconBig'
;
import
MenuIconBig
from
'@/components/MenuIcon/big/MenuIconBig'
;
import
{
updateServiceList
}
from
'@/store/rootReducers/service'
;
import
{
updateServiceList
}
from
'@/store/rootReducers/service'
;
import
{
getShowerController
,
ShowerUseType
}
from
'@/api/shower'
;
import
{
getShowerController
,
ShowerUseType
,
ControllerResponse
,
}
from
'@/api/shower'
;
import
{
updateShowerControlConfig
}
from
'@/store/rootReducers/shower'
;
type
PageStateProps
=
{
type
PageStateProps
=
{
userinfo
:
Customer
;
userinfo
:
Customer
;
...
@@ -47,6 +52,7 @@ type PageStateProps = {
...
@@ -47,6 +52,7 @@ type PageStateProps = {
type
PageDispatchProps
=
{
type
PageDispatchProps
=
{
updateUserInfo
:
(
e
:
UserState
)
=>
void
;
updateUserInfo
:
(
e
:
UserState
)
=>
void
;
updateServiceList
:
(
e
:
Service
[])
=>
void
;
updateServiceList
:
(
e
:
Service
[])
=>
void
;
updateShowerControlConfig
:
(
e
:
ControllerResponse
)
=>
void
;
};
};
type
BeanAccount
=
{
type
BeanAccount
=
{
...
@@ -78,6 +84,9 @@ interface Home {
...
@@ -78,6 +84,9 @@ interface Home {
updateServiceList
(
entity
:
Service
[])
{
updateServiceList
(
entity
:
Service
[])
{
dispatch
(
updateServiceList
(
entity
));
dispatch
(
updateServiceList
(
entity
));
},
},
updateShowerControlConfig
(
e
:
ControllerResponse
)
{
dispatch
(
updateShowerControlConfig
(
e
));
},
}),
}),
)
)
class
Home
extends
Component
{
class
Home
extends
Component
{
...
@@ -191,6 +200,7 @@ class Home extends Component {
...
@@ -191,6 +200,7 @@ class Home extends Component {
})
})
.
then
(
res
=>
{
.
then
(
res
=>
{
let
data
=
res
.
data
;
let
data
=
res
.
data
;
updateShowerControlConfig
(
res
.
data
);
let
type
=
let
type
=
data
.
useType
===
ShowerUseType
.
mix
?
data
.
defaultType
:
data
.
useType
;
data
.
useType
===
ShowerUseType
.
mix
?
data
.
defaultType
:
data
.
useType
;
if
(
type
===
ShowerUseType
.
bluetooth
)
{
if
(
type
===
ShowerUseType
.
bluetooth
)
{
...
...
src/pages/Shower/ShowerAppointment.scss
View file @
446a9198
...
@@ -5,7 +5,7 @@
...
@@ -5,7 +5,7 @@
background
:
linear-gradient
(
180deg
,
#486dec
,
#b3b8fc
);
background
:
linear-gradient
(
180deg
,
#486dec
,
#b3b8fc
);
.ShowerAppointment-Searchbox
{
.ShowerAppointment-Searchbox
{
height
:
100px
;
height
:
100px
;
margin
:
0
40px
0
;
margin
:
0
40px
28px
;
background-color
:
#fff
;
background-color
:
#fff
;
border-radius
:
16px
;
border-radius
:
16px
;
display
:
flex
;
display
:
flex
;
...
@@ -22,7 +22,7 @@
...
@@ -22,7 +22,7 @@
}
}
}
}
.ShowerAppointment-Account
{
.ShowerAppointment-Account
{
margin
:
28px
40px
34px
;
margin
:
0
40px
34px
;
color
:
#fff
;
color
:
#fff
;
font-size
:
28px
;
font-size
:
28px
;
display
:
flex
;
display
:
flex
;
...
@@ -42,6 +42,7 @@
...
@@ -42,6 +42,7 @@
}
}
}
}
.ShowerAppointment-Content
{
.ShowerAppointment-Content
{
box-sizing
:
border-box
;
padding
:
60px
40px
;
padding
:
60px
40px
;
background-color
:
#fff
;
background-color
:
#fff
;
flex
:
1
;
flex
:
1
;
...
@@ -56,53 +57,9 @@
...
@@ -56,53 +57,9 @@
font-size
:
24px
;
font-size
:
24px
;
color
:
#6180f4
;
color
:
#6180f4
;
}
}
.ShowerAppointment-Equipment-item
{
position
:
relative
;
font-size
:
28px
;
color
:
#333
;
height
:
158px
;
background-color
:
#f7f8fe
;
border-radius
:
16px
;
padding
:
14px
0
0
32px
;
margin-bottom
:
20px
;
&
.disabled
{
color
:
#999
;
}
.ShowerAppointment-Equipment-row
{
display
:
flex
;
margin-bottom
:
6px
;
line-height
:
44px
;
.ShowerAppointment-Equipment-name
{
margin-right
:
32px
;
}
.ShowerAppointment-Equipment-value
{
width
:
312px
;
}
}
.ShowerAppointment-Equipment-appoint
{
position
:
absolute
;
top
:
50px
;
right
:
0
;
width
:
136px
;
height
:
68px
;
text-align
:
center
;
line-height
:
68px
;
background-color
:
#e4f3da
;
color
:
#6bb11a
;
font-size
:
32px
;
font-weight
:
bold
;
border-radius
:
16px
0
0
16px
;
}
.ShowerAppointment-Equipment-disabled
{
position
:
absolute
;
width
:
40px
;
height
:
40px
;
right
:
46px
;
top
:
62px
;
}
}
}
}
.ShowerAppointment-AppointmentList
{
.ShowerAppointment-AppointmentList
{
box-sizing
:
border-box
;
flex
:
1
;
flex
:
1
;
overflow-y
:
scroll
;
overflow-y
:
scroll
;
padding
:
10px
40px
20px
;
padding
:
10px
40px
20px
;
...
...
src/pages/Shower/ShowerAppointment.tsx
View file @
446a9198
import
'./ShowerAppointment.scss'
;
import
'./ShowerAppointment.scss'
;
import
{
View
,
Input
,
Text
,
Image
}
from
'@tarojs/components'
;
import
{
View
,
Input
,
Text
,
Image
,
ScrollView
}
from
'@tarojs/components'
;
import
DisabledIcon
from
'../../images/shower/ic_jinyuyue@2x.png'
;
import
Taro
,
{
useState
,
useReducer
,
useEffect
}
from
'@tarojs/taro'
;
import
{
useState
}
from
'@tarojs/taro'
;
import
AppointermentCard
from
'./components/AppointermentCard/AppointermentCard'
;
import
AppointermentCard
from
'./components/AppointermentCard/AppointermentCard'
;
import
useInputValue
from
'@/hooks/useInputValue'
;
import
{
getAppointmentDevice
,
appointingEquipment
,
ShowerUseType
,
}
from
'@/api/shower'
;
import
{
useSelector
}
from
'@tarojs/redux'
;
import
{
Customer
}
from
'@/types/Customer/Customer'
;
import
useDeviceList
from
'./hooks/useDeviceList'
;
import
AppointermentEquipment
from
'./components/AppointermentEquipment/AppointermentEquipment'
;
import
useAppointRecordsList
from
'./hooks/useAppointRecordsList'
;
import
useCheckAppointable
from
'./hooks/useCheckAppointable'
;
import
{
ShowerState
}
from
'@/store/rootReducers/shower'
;
function
ShowerAppointment
()
{
function
ShowerAppointment
()
{
const
[
showState
,
setShowState
]
=
useState
(
2
);
const
userInfo
=
useSelector
(
(
state
:
{
userinfo
:
Customer
})
=>
state
.
userinfo
,
);
const
showerControlConfig
=
useSelector
(
(
state
:
{
showerState
:
ShowerState
})
=>
state
.
showerState
,
);
const
[
showState
,
setShowState
]
=
useState
(
1
);
const
search
=
useInputValue
(
''
);
const
[
searchString
,
setSearchString
]
=
useState
(
''
);
const
appointableData
=
useCheckAppointable
(
userInfo
.
customerId
,
userInfo
.
areaId
,
);
const
list
=
useDeviceList
(
userInfo
.
areaId
,
userInfo
.
customerId
,
searchString
,
);
const
[
records
,
resetRecordList
,
fetchMoreRecordList
]
=
useAppointRecordsList
(
userInfo
.
customerId
,
);
const
searchEquipment
=
()
=>
{
setSearchString
(
search
.
value
);
};
const
appointingStart
=
(
deviceCode
:
string
)
=>
{
// Taro.showModal({
// title: '',
// content: '',
// }).then(res => {
// if(res.confirm){
// }
// })
appointingEquipment
({
account
:
userInfo
.
customerId
.
toString
(),
phone
:
userInfo
.
customerPhone
,
userId
:
userInfo
.
customerId
,
userName
:
userInfo
.
customerName
,
deviceCode
:
deviceCode
,
})
.
then
(
res
=>
{
console
.
log
(
res
);
Taro
.
showToast
({
title
:
res
.
msg
,
});
})
.
catch
(
err
=>
{
console
.
log
(
err
);
});
};
const
goBluetoothShower
=
()
=>
{
Taro
.
navigateTo
({
url
:
'/pages/Shower/Shower'
,
});
};
return
(
return
(
<
View
className=
'ShowerAppointment'
>
<
View
className=
'ShowerAppointment'
>
{
showState
==
1
&&
(
{
showState
==
1
&&
(
<
View
className=
'ShowerAppointment-Searchbox'
>
<
View
className=
'ShowerAppointment-Searchbox'
>
<
Input
placeholder=
'请输入要少选的设备位置'
/>
<
Input
<
Text
className=
'ShowerAppointment-Searchbox-btn'
>
开始筛选
</
Text
>
placeholder=
'请输入要少选的设备位置'
value=
{
search
.
value
}
onInput=
{
e
=>
search
.
onChange
(
e
)
}
/>
<
Text
className=
'ShowerAppointment-Searchbox-btn'
onClick=
{
searchEquipment
}
>
开始筛选
</
Text
>
</
View
>
</
View
>
)
}
)
}
{
showState
==
1
&&
(
{
showState
==
1
&&
showerControlConfig
.
controllerConfigs
.
balances
.
length
&&
(
<
View
className=
'ShowerAppointment-Account'
>
<
View
className=
'ShowerAppointment-Account'
>
<
View
className=
'ShowerAppointment-Account-item'
>
{
showerControlConfig
.
controllerConfigs
.
balances
.
map
(
item
=>
(
<
Text
className=
'name'
>
艾米币
</
Text
>
<
View
className=
'ShowerAppointment-Account-item'
>
<
Text
>
10.00元
</
Text
>
<
Text
className=
'name'
>
{
item
.
serviceName
}
</
Text
>
</
View
>
<
Text
>
{
item
.
amount
.
toFixed
(
2
)
}
</
Text
>
<
View
className=
'ShowerAppointment-Account-item'
>
</
View
>
<
Text
className=
'name'
>
吹风豆
</
Text
>
))
}
<
Text
>
22.00元
</
Text
>
</
View
>
</
View
>
</
View
>
)
}
)
}
{
showState
==
1
&&
(
{
showState
==
1
&&
(
<
View
className=
'ShowerAppointment-Content'
>
<
View
className=
'ShowerAppointment-Content'
>
<
View
className=
'ShowerAppointment-Equipment-title'
>
设备列表
</
View
>
<
View
className=
'ShowerAppointment-Equipment-title'
>
设备列表
</
View
>
<
View
className=
'ShowerAppointment-Equipment-info'
>
<
View
className=
'ShowerAppointment-Equipment-info'
>
如预约未使用,将在12小时内无法再次预约
{
appointableData
.
message
}
</
View
>
<
View
className=
'ShowerAppointment-Equipment-item'
>
<
View
className=
'ShowerAppointment-Equipment-row'
>
<
Text
className=
'ShowerAppointment-Equipment-name'
>
设备编码
</
Text
>
<
Text
className=
'ShowerAppointment-Equipment-value'
>
AB000075
</
Text
>
</
View
>
<
View
className=
'ShowerAppointment-Equipment-row'
>
<
Text
className=
'ShowerAppointment-Equipment-name'
>
设备位置
</
Text
>
<
Text
className=
'ShowerAppointment-Equipment-value'
>
高新区天赋三街福年广场T2-1812
</
Text
>
</
View
>
<
View
className=
'ShowerAppointment-Equipment-appoint'
>
可预约
</
View
>
</
View
>
<
View
className=
'ShowerAppointment-Equipment-item'
>
<
View
className=
'ShowerAppointment-Equipment-row'
>
<
Text
className=
'ShowerAppointment-Equipment-name'
>
设备编码
</
Text
>
<
Text
className=
'ShowerAppointment-Equipment-value'
>
AB000075
</
Text
>
</
View
>
<
View
className=
'ShowerAppointment-Equipment-row'
>
<
Text
className=
'ShowerAppointment-Equipment-name'
>
设备位置
</
Text
>
<
Text
className=
'ShowerAppointment-Equipment-value'
>
高新区天赋三街福年广场T2-1812
</
Text
>
</
View
>
<
View
className=
'ShowerAppointment-Equipment-appoint'
>
可预约
</
View
>
</
View
>
<
View
className=
'ShowerAppointment-Equipment-item disabled'
>
<
View
className=
'ShowerAppointment-Equipment-row'
>
<
Text
className=
'ShowerAppointment-Equipment-name'
>
设备编码
</
Text
>
<
Text
className=
'ShowerAppointment-Equipment-value'
>
AB000075
</
Text
>
</
View
>
<
View
className=
'ShowerAppointment-Equipment-row'
>
<
Text
className=
'ShowerAppointment-Equipment-name'
>
设备位置
</
Text
>
<
Text
className=
'ShowerAppointment-Equipment-value'
>
高新区天赋三街福年广场T2-1812
</
Text
>
</
View
>
<
Image
className=
'ShowerAppointment-Equipment-disabled'
src=
{
DisabledIcon
}
/>
</
View
>
<
View
className=
'ShowerAppointment-Equipment-item disabled'
>
<
View
className=
'ShowerAppointment-Equipment-row'
>
<
Text
className=
'ShowerAppointment-Equipment-name'
>
设备编码
</
Text
>
<
Text
className=
'ShowerAppointment-Equipment-value'
>
AB000075
</
Text
>
</
View
>
<
View
className=
'ShowerAppointment-Equipment-row'
>
<
Text
className=
'ShowerAppointment-Equipment-name'
>
设备位置
</
Text
>
<
Text
className=
'ShowerAppointment-Equipment-value'
>
高新区天赋三街福年广场T2-1812
</
Text
>
</
View
>
<
Image
className=
'ShowerAppointment-Equipment-disabled'
src=
{
DisabledIcon
}
/>
</
View
>
</
View
>
<
View
className=
'ShowerAppointment-Equipment-item disabled'
>
{
list
.
map
(
item
=>
(
<
View
className=
'ShowerAppointment-Equipment-row'
>
<
AppointermentEquipment
<
Text
className=
'ShowerAppointment-Equipment-name'
>
设备编码
</
Text
>
key=
{
item
.
code
}
<
Text
className=
'ShowerAppointment-Equipment-value'
>
data=
{
item
}
AB000075
appointingStart=
{
appointingStart
}
</
Text
>
</
View
>
<
View
className=
'ShowerAppointment-Equipment-row'
>
<
Text
className=
'ShowerAppointment-Equipment-name'
>
设备位置
</
Text
>
<
Text
className=
'ShowerAppointment-Equipment-value'
>
高新区天赋三街福年广场T2-1812
</
Text
>
</
View
>
<
Image
className=
'ShowerAppointment-Equipment-disabled'
src=
{
DisabledIcon
}
/>
/>
</
View
>
))
}
</
View
>
</
View
>
)
}
)
}
{
showState
==
1
&&
(
{
showState
==
1
&&
<
View
className=
'ShowerAppointment-ToggleBtn'
>
自助洗浴
</
View
>
showerControlConfig
.
controllerConfigs
.
useType
===
ShowerUseType
.
mix
&&
(
)
}
<
View
className=
'ShowerAppointment-ToggleBtn'
onClick=
{
goBluetoothShower
}
>
自助洗浴
</
View
>
)
}
{
showState
==
2
&&
(
{
showState
==
2
&&
(
<
View
className=
'ShowerAppointment-AppointmentList'
>
<
ScrollView
<
AppointermentCard
disabled
/>
className=
'ShowerAppointment-AppointmentList'
<
AppointermentCard
/>
scrollY
<
AppointermentCard
/>
scrollWithAnimation
<
AppointermentCard
/>
lowerThreshold=
{
50
}
</
View
>
onScrollToLower=
{
fetchMoreRecordList
}
>
{
records
.
map
(
item
=>
(
<
AppointermentCard
key=
{
item
.
deviceCode
}
data=
{
item
}
/>
))
}
</
ScrollView
>
)
}
)
}
<
View
className=
'ShowerAppointment-Footer'
>
<
View
className=
'ShowerAppointment-Footer'
>
...
@@ -150,9 +158,13 @@ function ShowerAppointment() {
...
@@ -150,9 +158,13 @@ function ShowerAppointment() {
</
View
>
</
View
>
);
);
}
}
ShowerAppointment
.
onPullDownRefresh
=
()
=>
{
console
.
log
(
'in onPullDownRefresh'
);
};
ShowerAppointment
.
config
=
{
ShowerAppointment
.
config
=
{
navigationBarBackgroundColor
:
'#486dec'
,
navigationBarBackgroundColor
:
'#486dec'
,
navigationBarTitleText
:
''
,
navigationBarTitleText
:
''
,
backgroundColor
:
'#486dec'
,
};
};
export
default
ShowerAppointment
;
export
default
ShowerAppointment
;
src/pages/Shower/components/AppointermentCard/AppointermentCard.scss
View file @
446a9198
...
@@ -32,6 +32,9 @@
...
@@ -32,6 +32,9 @@
line-height
:
36px
;
line-height
:
36px
;
font-size
:
24px
;
font-size
:
24px
;
margin-bottom
:
10px
;
margin-bottom
:
10px
;
&
:last-child
{
margin-bottom
:
20px
;
}
text
:first-child
{
text
:first-child
{
margin-right
:
16px
;
margin-right
:
16px
;
}
}
...
...
src/pages/Shower/components/AppointermentCard/AppointermentCard.tsx
View file @
446a9198
import
'./AppointermentCard.scss'
;
import
'./AppointermentCard.scss'
;
import
{
View
,
Text
,
Image
}
from
'@tarojs/components'
;
import
{
View
,
Text
,
Image
}
from
'@tarojs/components'
;
import
DisabledIcon
from
'../../../../images/shower/img_shixiao@2x.png'
;
import
DisabledIcon
from
'../../../../images/shower/img_shixiao@2x.png'
;
import
{
AppointmentRecordsResponse
}
from
'@/api/shower'
;
type
PageOwnProps
=
{
type
PageOwnProps
=
{
d
isabled
?:
boolean
;
d
ata
:
AppointmentRecordsResponse
;
};
};
const
AppointermentCard
=
(
props
:
PageOwnProps
)
=>
{
const
AppointermentCard
=
(
props
:
PageOwnProps
)
=>
{
const
{
data
}
=
props
;
return
(
return
(
<
View
className=
{
`AppointermentCard ${props.disabled ? 'disabled' : ''}`
}
>
<
View
className=
{
`AppointermentCard ${data.status === 5 ? 'disabled' : ''}`
}
>
<
View
className=
'AppointermentCard-Title'
>
我的预约
</
View
>
<
View
className=
'AppointermentCard-Title'
>
我的预约
</
View
>
<
View
className=
'AppointermentCard-row'
>
<
View
className=
'AppointermentCard-row'
>
<
Text
>
设备编码:
</
Text
>
<
Text
>
设备编码:
</
Text
>
<
Text
>
AB00075
</
Text
>
<
Text
>
{
data
.
deviceCode
}
</
Text
>
</
View
>
</
View
>
<
View
className=
'AppointermentCard-row'
>
<
View
className=
'AppointermentCard-row'
>
<
Text
>
设备位置:
</
Text
>
<
Text
>
设备位置:
</
Text
>
<
Text
className=
'AppointermentCard-row-location'
>
<
Text
className=
'AppointermentCard-row-location'
>
高新区天府三街福年广场T2-1812
{
data
.
deviceLocation
}
</
Text
>
</
Text
>
</
View
>
</
View
>
<
View
className=
'AppointermentCard-row'
>
<
View
className=
'AppointermentCard-row'
>
<
Text
>
预约生效时间:
</
Text
>
<
Text
>
预约生效时间:
</
Text
>
<
Text
>
2019-7-9 18:09:30
</
Text
>
<
Text
>
{
data
.
appointTime
?
data
.
appointTime
:
''
}
</
Text
>
</
View
>
</
View
>
<
View
className=
'AppointermentCard-Time'
>
<
View
className=
'AppointermentCard-Time'
>
预约失效时间: 2019-7-9 20:03:20
<
Text
>
预约失效时间:
</
Text
>
<
Text
>
2019-15-24 12:45:31
</
Text
>
{
/* <Text>{data.expireTime ? data.expireTime : ''}</Text> */
}
</
View
>
</
View
>
{
props
.
disabled
&&
<
Image
className=
'AppointermentCard-Dis-Icon'
src=
{
DisabledIcon
}
/>
}
{
data
.
status
===
5
&&
(
<
Image
className=
'AppointermentCard-Dis-Icon'
src=
{
DisabledIcon
}
/>
)
}
</
View
>
</
View
>
);
);
};
};
...
...
src/pages/Shower/components/AppointermentEquipment/AppointermentEquipment.scss
0 → 100644
View file @
446a9198
.ShowerAppointment-Equipment
{
position
:
relative
;
font-size
:
28px
;
color
:
#333
;
height
:
158px
;
background-color
:
#f7f8fe
;
border-radius
:
16px
;
padding
:
14px
0
0
32px
;
margin-bottom
:
20px
;
&
.disabled
{
color
:
#999
;
}
.ShowerAppointment-Equipment-row
{
display
:
flex
;
margin-bottom
:
6px
;
line-height
:
44px
;
.ShowerAppointment-Equipment-name
{
margin-right
:
32px
;
}
.ShowerAppointment-Equipment-value
{
width
:
312px
;
&
.location
{
overflow
:
hidden
;
text-overflow
:
ellipsis
;
display
:
-
webkit-box
;
-webkit-line-clamp
:
2
;
-webkit-box-orient
:
vertical
;
}
}
}
.ShowerAppointment-Equipment-appoint
{
position
:
absolute
;
top
:
50px
;
right
:
0
;
width
:
136px
;
height
:
68px
;
text-align
:
center
;
line-height
:
68px
;
background-color
:
#e4f3da
;
color
:
#6bb11a
;
font-size
:
32px
;
font-weight
:
bold
;
border-radius
:
16px
0
0
16px
;
}
.ShowerAppointment-Equipment-disabled
{
position
:
absolute
;
width
:
40px
;
height
:
40px
;
right
:
46px
;
top
:
62px
;
}
}
src/pages/Shower/components/AppointermentEquipment/AppointermentEquipment.tsx
0 → 100644
View file @
446a9198
import
'./AppointermentEquipment.scss'
;
import
{
View
,
Text
,
Image
}
from
'@tarojs/components'
;
import
{
AppointDeviceResponse
}
from
'@/api/shower'
;
import
DisabledIcon
from
'@/images/shower/ic_jinyuyue@2x.png'
;
type
PageOwnProps
=
{
data
:
AppointDeviceResponse
;
appointingStart
:
(
deviceCode
:
string
)
=>
void
;
};
const
AppointermentEquipment
=
(
props
:
PageOwnProps
)
=>
{
const
{
data
,
appointingStart
}
=
props
;
const
clickHandle
=
()
=>
{
appointingStart
&&
appointingStart
(
data
.
code
);
};
return
(
<
View
className=
{
`ShowerAppointment-Equipment ${
data.appointable && !data.inPunishment ? '' : 'disabled'
}`
}
>
<
View
className=
'ShowerAppointment-Equipment-row'
>
<
Text
className=
'ShowerAppointment-Equipment-name'
>
设备编码
</
Text
>
<
Text
className=
'ShowerAppointment-Equipment-value'
>
{
data
.
code
}
</
Text
>
</
View
>
<
View
className=
'ShowerAppointment-Equipment-row'
>
<
Text
className=
'ShowerAppointment-Equipment-name'
>
设备位置
</
Text
>
<
Text
className=
'ShowerAppointment-Equipment-value location'
>
{
data
.
location
}
</
Text
>
</
View
>
{
data
.
appointable
?
(
<
View
className=
'ShowerAppointment-Equipment-appoint'
onClick=
{
clickHandle
}
>
可预约
</
View
>
)
:
(
<
Image
className=
'ShowerAppointment-Equipment-disabled'
src=
{
DisabledIcon
}
/>
)
}
</
View
>
);
};
export
default
AppointermentEquipment
;
src/pages/Shower/hooks/useAppointRecordsList.ts
0 → 100644
View file @
446a9198
import
Taro
,
{
useEffect
,
useState
,
useReducer
}
from
'@tarojs/taro'
;
import
{
getAppointmentRecords
,
AppointmentRecordsResponse
,
}
from
'@/api/shower'
;
import
Actions
from
'@/types/Store/Actions'
;
const
reducer
=
(
state
:
AppointmentRecordsResponse
[],
action
:
Actions
)
=>
{
switch
(
action
.
type
)
{
case
'getRecordList'
:
return
action
.
payload
;
case
'appendRecordList'
:
return
[...
state
,
...
action
.
payload
];
default
:
return
state
;
}
};
const
useAppointRecordsList
=
(
userId
:
number
,
):
[
AppointmentRecordsResponse
[],
()
=>
void
,
()
=>
void
]
=>
{
const
[
pageNum
,
setPageNum
]
=
useState
(
1
);
const
[
list
,
dispatch
]
=
useReducer
(
reducer
,
[]);
const
fetchList
=
(
pageNum
:
number
)
=>
{
return
getAppointmentRecords
({
userId
,
pageSize
:
10
,
pageNum
,
});
};
const
fetchMoreList
=
()
=>
{
Taro
.
showLoading
();
fetchList
(
pageNum
+
1
)
.
then
(
res
=>
{
Taro
.
hideLoading
();
console
.
log
(
res
);
let
list
=
res
.
data
.
list
;
if
(
list
.
length
)
{
setPageNum
(
pageNum
+
1
);
dispatch
({
type
:
'appendRecordList'
,
payload
:
res
.
data
.
list
});
}
})
.
catch
(
err
=>
{
console
.
log
(
err
);
Taro
.
showToast
({
title
:
err
.
msg
||
'网络错误'
,
icon
:
'none'
,
});
});
};
const
fetchNewList
=
()
=>
{
Taro
.
showLoading
();
fetchList
(
1
)
.
then
(
res
=>
{
Taro
.
hideLoading
();
console
.
log
(
res
);
dispatch
({
type
:
'getRecordList'
,
payload
:
res
.
data
.
list
});
})
.
catch
(
err
=>
{
console
.
log
(
err
);
Taro
.
showToast
({
title
:
err
.
msg
||
'网络错误'
,
icon
:
'none'
,
});
});
};
useEffect
(()
=>
{
fetchNewList
();
},
[
userId
]);
return
[
list
,
fetchNewList
,
fetchMoreList
];
};
export
default
useAppointRecordsList
;
src/pages/Shower/hooks/useCheckAppointable.ts
0 → 100644
View file @
446a9198
import
{
useEffect
,
useReducer
}
from
'@tarojs/taro'
;
import
{
getUserAppointableData
,
UserAppointableData
}
from
'@/api/shower'
;
import
Actions
from
'@/types/Store/Actions'
;
const
reducer
=
(
state
:
UserAppointableData
,
action
:
Actions
)
=>
{
switch
(
action
.
type
)
{
case
'getAppointData'
:
return
action
.
payload
;
default
:
return
state
;
}
};
const
initState
:
UserAppointableData
=
{
appointMode
:
0
,
defaultType
:
0
,
duration
:
0
,
message
:
''
,
punishment
:
0
,
useType
:
0
,
userPunishment
:
0
,
};
const
useCheckAppointable
=
(
userId
:
number
,
campusId
:
number
,
):
UserAppointableData
=>
{
const
[
data
,
dispatch
]
=
useReducer
(
reducer
,
initState
);
useEffect
(()
=>
{
getUserAppointableData
({
userId
,
campusId
,
})
.
then
(
res
=>
{
console
.
log
(
res
);
dispatch
({
type
:
'getAppointData'
,
payload
:
res
.
data
});
})
.
catch
(
err
=>
{
console
.
log
(
err
);
});
},
[
userId
,
campusId
]);
return
data
;
};
export
default
useCheckAppointable
;
src/pages/Shower/hooks/useDeviceList.ts
0 → 100644
View file @
446a9198
import
Taro
,
{
useReducer
,
useEffect
}
from
'@tarojs/taro'
;
import
Actions
from
'@/types/Store/Actions'
;
import
{
getAppointmentDevice
,
AppointDeviceResponse
}
from
'@/api/shower'
;
const
reducer
=
(
state
:
AppointDeviceResponse
[],
action
:
Actions
)
=>
{
switch
(
action
.
type
)
{
case
'updateDeviceList'
:
return
action
.
payload
;
default
:
return
state
;
}
};
const
useDeviceList
=
(
campusId
:
number
,
userId
:
number
,
location
:
string
,
):
AppointDeviceResponse
[]
=>
{
const
[
list
,
dispatch
]
=
useReducer
(
reducer
,
[]);
// const fetchList = (pageNum: number) => {
// getAppointmentDevice({ location, campusId, userId, pageNum })
// .then(res => {
// Taro.hideLoading();
// dispatch({ type: 'updateDeviceList', payload: res.data.list });
// })
// .catch(err => {
// Taro.showToast({
// title: err.msg || '网络错误',
// icon: 'none',
// });
// });
// };
// const fetchNewList = () => {};
// const fetchMoreList = () => {};
useEffect
(()
=>
{
Taro
.
showLoading
();
getAppointmentDevice
(
location
?
{
location
,
campusId
,
userId
}
:
{
campusId
,
userId
},
)
.
then
(
res
=>
{
Taro
.
hideLoading
();
dispatch
({
type
:
'updateDeviceList'
,
payload
:
res
.
data
.
list
});
})
.
catch
(
err
=>
{
Taro
.
showToast
({
title
:
err
.
msg
||
'网络错误'
,
icon
:
'none'
,
});
});
},
[
campusId
,
userId
,
location
]);
return
list
;
};
export
default
useDeviceList
;
src/store/reducers.ts
View file @
446a9198
...
@@ -4,6 +4,7 @@ import OrderList from '../pages/Order/OrderList/store';
...
@@ -4,6 +4,7 @@ import OrderList from '../pages/Order/OrderList/store';
import
ShowerReducer
from
'@/pages/Shower/store'
;
import
ShowerReducer
from
'@/pages/Shower/store'
;
import
serviceList
from
'./rootReducers/service'
;
import
serviceList
from
'./rootReducers/service'
;
import
orderState
from
'./rootReducers/orderState'
;
import
orderState
from
'./rootReducers/orderState'
;
import
showerState
from
'./rootReducers/shower'
;
export
default
combineReducers
({
export
default
combineReducers
({
userinfo
,
userinfo
,
...
@@ -11,4 +12,5 @@ export default combineReducers({
...
@@ -11,4 +12,5 @@ export default combineReducers({
Shower
:
ShowerReducer
,
Shower
:
ShowerReducer
,
serviceList
,
serviceList
,
orderState
,
orderState
,
showerState
,
});
});
src/store/rootReducers/shower.ts
0 → 100644
View file @
446a9198
import
Actions
from
'@/types/Store/Actions'
;
import
{
ControllerResponse
}
from
'@/api/shower'
;
export
type
ShowerState
=
{
controllerConfigs
:
ControllerResponse
;
};
const
INITIAL_STATE
=
{
controllerConfigs
:
{
appointmentThresholdPrompt
:
''
,
balances
:
[],
beanAmount
:
0
,
defaultType
:
0
,
money
:
0
,
thresholdPrompt
:
''
,
thresholdValue
:
0
,
useType
:
0
,
},
};
export
const
updateShowerControlConfig
=
(
entity
:
ControllerResponse
,
):
Actions
=>
({
type
:
'UPDATE_SHOWER_CONFIG'
,
payload
:
entity
,
});
export
default
function
shower
(
state
:
ShowerState
=
INITIAL_STATE
,
actions
:
Actions
,
):
ShowerState
{
switch
(
actions
.
type
)
{
case
'UPDATE_SHOWER_CONFIG'
:
return
{
...
state
,
controllerConfigs
:
actions
.
payload
,
};
default
:
return
state
;
}
}
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