Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
5
51business
Project
Project
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
方斌
51business
Commits
4e1c48c8
Commit
4e1c48c8
authored
Apr 13, 2020
by
任国军
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add class & fix header
parent
9880cadd
Pipeline
#21628
passed with stage
in 47 seconds
Changes
9
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
110 additions
and
1040 deletions
+110
-1040
institution.js
app/controller/course/v5/institution.js
+5
-192
option.js
app/controller/course/v5/option.js
+13
-5
mini_auth_v5.js
app/middleware/mini_auth_v5.js
+1
-1
courseBanner.js
app/model/class/v5/courseBanner.js
+2
-2
courseBannerType.js
app/model/class/v5/courseBannerType.js
+2
-2
courseV5Category.js
app/model/class/v5/courseV5Category.js
+0
-1
course_v5.js
app/router/course_v5.js
+7
-0
institution.js
app/service/course/v5/institution.js
+55
-832
option.js
app/service/course/v5/option.js
+25
-5
No files found.
app/controller/course/v5/institution.js
View file @
4e1c48c8
...
...
@@ -3,213 +3,26 @@
const
Controller
=
require
(
'egg'
).
Controller
;
class
InstitutionController
extends
Controller
{
// 机构列表
async
getInstitutions
()
{
const
{
ctx
}
=
this
;
const
inputParams
=
ctx
.
request
.
query
;
const
ret
=
await
ctx
.
service
.
course
.
v4
.
institution
.
getInstitutions
(
inputParams
);
ctx
.
success
(
ret
);
}
// 机构详情
async
getInstitution
()
{
const
{
ctx
}
=
this
;
let
inputParams
=
ctx
.
params
;
const
query
=
ctx
.
query
;
inputParams
=
Object
.
assign
(
inputParams
,
query
);
const
result
=
await
ctx
.
service
.
course
.
v4
.
institution
.
getInstitution
(
inputParams
);
ctx
.
success
({
result
});
}
// 课程列表
async
getClass
es
()
{
async
getClass
List
()
{
const
{
ctx
}
=
this
;
const
input
Params
=
ctx
.
request
.
query
;
const
ret
=
await
ctx
.
service
.
course
.
v4
.
institution
.
getClass
es
(
input
Params
);
const
query
Params
=
ctx
.
request
.
query
;
const
ret
=
await
ctx
.
service
.
course
.
v4
.
institution
.
getClass
List
(
query
Params
);
ctx
.
success
(
ret
);
}
// 课程详情
async
getClass
()
{
async
getClass
Info
()
{
const
{
ctx
}
=
this
;
const
class_id
=
ctx
.
params
.
class_id
;
if
(
!
class_id
)
{
ctx
.
failed
(
'error class_id'
);
}
const
inputParams
=
ctx
.
request
.
query
;
inputParams
.
id
=
class_id
;
const
ret
=
await
ctx
.
service
.
course
.
v4
.
institution
.
getClass
(
inputParams
);
ctx
.
success
(
ret
);
}
// 老师列表
async
getTeachers
()
{
const
{
ctx
}
=
this
;
const
inputParams
=
ctx
.
request
.
query
;
if
(
ctx
.
isEmpty
(
inputParams
.
institution_id
))
{
ctx
.
failed
(
'institution_id is empty'
);
}
const
ret
=
await
ctx
.
service
.
course
.
v4
.
institution
.
getTeachers
(
inputParams
);
ctx
.
success
(
ret
);
}
// 老师详情
async
getTeacher
()
{
const
{
ctx
}
=
this
;
const
teacher_id
=
ctx
.
params
.
teacher_id
;
if
(
!
teacher_id
)
{
ctx
.
failed
(
'error teacher_id'
);
}
const
ret
=
await
ctx
.
service
.
course
.
v4
.
institution
.
getTeacher
(
teacher_id
);
ctx
.
success
(
ret
);
}
// 获取分类
async
getCats
()
{
const
{
ctx
}
=
this
;
const
ret
=
await
ctx
.
service
.
course
.
v4
.
institution
.
getCats
();
ctx
.
success
(
ret
);
}
// 搜索
async
search
()
{
const
{
ctx
}
=
this
;
const
inputParams
=
ctx
.
request
.
query
;
const
ret
=
await
ctx
.
service
.
course
.
v4
.
institution
.
search
(
inputParams
);
ctx
.
success
(
ret
);
}
// 用户搜索历史
async
getUserSearch
()
{
const
{
ctx
,
service
}
=
this
;
const
ret
=
await
service
.
course
.
v4
.
institution
.
getUserSearch
();
ctx
.
success
(
ret
);
}
// 获取热搜
async
getHotSearch
()
{
const
{
ctx
,
service
}
=
this
;
const
ret
=
await
service
.
course
.
v4
.
institution
.
getHotSearch
();
ctx
.
success
(
ret
);
}
// 删除用户搜索历史
async
deleteUserSearch
()
{
const
{
ctx
,
service
}
=
this
;
await
service
.
course
.
v4
.
institution
.
deleteUserSearch
();
ctx
.
success
();
}
// 评论列表
async
getComments
()
{
const
{
ctx
,
service
}
=
this
;
const
inputParams
=
ctx
.
request
.
query
;
const
ret
=
await
service
.
course
.
v4
.
institution
.
getComments
(
inputParams
);
ctx
.
success
(
ret
);
}
// 搜索联想
async
getSuggestSearch
()
{
const
{
ctx
,
service
}
=
this
;
const
inputParams
=
ctx
.
request
.
query
;
const
ret
=
await
service
.
course
.
v4
.
institution
.
getSuggestSearch
(
inputParams
);
ctx
.
success
(
ret
);
}
// 用户收藏机构列表
async
getUserCollectedInstitutions
()
{
const
{
ctx
,
service
}
=
this
;
const
inputParams
=
ctx
.
request
.
query
;
const
ret
=
await
service
.
course
.
v4
.
institution
.
getUserCollectedInstitutions
(
inputParams
);
ctx
.
success
(
ret
);
}
// 用户收藏课程列表
async
getUserCollectedClasses
()
{
const
{
ctx
,
service
}
=
this
;
const
inputParams
=
ctx
.
request
.
query
;
const
ret
=
await
service
.
course
.
v4
.
institution
.
getUserCollectedClasses
(
inputParams
);
ctx
.
success
(
ret
);
}
// 根据分类获取选课指南
async
getArticlesByCat
()
{
const
{
ctx
,
service
}
=
this
;
const
inputParams
=
ctx
.
request
.
query
;
if
(
ctx
.
isEmpty
(
inputParams
)
||
ctx
.
isEmpty
(
inputParams
.
cat_id
))
{
ctx
.
failed
(
'cat_id is empty'
);
}
const
ret
=
await
service
.
course
.
v4
.
institution
.
getArticlesByCat
(
inputParams
);
ctx
.
success
(
ret
);
}
// 获取选课指南详情
async
getArticle
()
{
const
{
ctx
,
service
}
=
this
;
const
inputParams
=
ctx
.
params
;
if
(
ctx
.
isEmpty
(
inputParams
)
||
ctx
.
isEmpty
(
inputParams
.
id
))
{
ctx
.
failed
(
'article_id is empty'
);
}
const
ret
=
await
service
.
course
.
v4
.
institution
.
getArticle
(
Number
(
inputParams
.
id
));
ctx
.
success
(
ret
);
}
// 点赞
async
like
()
{
const
{
ctx
,
service
}
=
this
;
const
inputParams
=
ctx
.
request
.
body
;
if
(
ctx
.
isEmpty
(
inputParams
)
||
ctx
.
isEmpty
(
inputParams
.
type
)
||
ctx
.
isEmpty
(
inputParams
.
type_id
))
{
ctx
.
failed
(
'参数错误'
);
}
const
ret
=
await
service
.
course
.
v4
.
institution
.
like
(
inputParams
);
ctx
.
success
(
ret
);
}
// 取消点赞
async
unlike
()
{
const
{
ctx
,
service
}
=
this
;
const
inputParams
=
ctx
.
request
.
body
;
if
(
ctx
.
isEmpty
(
inputParams
)
||
ctx
.
isEmpty
(
inputParams
.
type
)
||
ctx
.
isEmpty
(
inputParams
.
type_id
))
{
ctx
.
failed
(
'参数错误'
);
}
const
ret
=
await
service
.
course
.
v4
.
institution
.
unlike
(
inputParams
);
ctx
.
success
(
ret
);
}
// 获取推荐选课指南
async
getArticlesByRecommend
()
{
const
{
ctx
,
service
}
=
this
;
const
inputParams
=
ctx
.
request
.
query
;
const
ret
=
await
ctx
.
service
.
course
.
v4
.
institution
.
getClassInfo
(
class_id
);
const
ret
=
await
service
.
course
.
v4
.
institution
.
getArticlesByRecommend
(
inputParams
);
ctx
.
success
(
ret
);
}
}
...
...
app/controller/course/v5/option.js
View file @
4e1c48c8
...
...
@@ -10,22 +10,30 @@ class OptionController extends Controller {
async
getOptions
()
{
const
{
ctx
}
=
this
;
const
results
=
await
ctx
.
service
.
course
.
v
4
.
option
.
getOptions
();
const
results
=
await
ctx
.
service
.
course
.
v
5
.
option
.
getOptions
();
ctx
.
success
({
results
});
}
async
getBanner
s
()
{
async
getBanner
List
()
{
const
{
ctx
,
service
}
=
this
;
const
input
Params
=
ctx
.
request
.
query
;
if
(
ctx
.
isEmpty
(
input
Params
.
alias
))
{
const
query
Params
=
ctx
.
request
.
query
;
if
(
ctx
.
isEmpty
(
query
Params
.
alias
))
{
ctx
.
failed
(
'alias is empty'
);
}
const
ret
=
await
service
.
course
.
v
4
.
option
.
getBanners
(
input
Params
.
alias
);
const
ret
=
await
service
.
course
.
v
5
.
option
.
getBannerList
(
query
Params
.
alias
);
ctx
.
success
(
ret
);
}
// 获取分类列表
async
getCategoryList
()
{
const
{
ctx
,
service
}
=
this
;
const
queryParams
=
ctx
.
request
.
query
;
const
ret
=
await
service
.
course
.
v5
.
option
.
getCategoryList
(
queryParams
);
ctx
.
success
(
ret
);
}
}
module
.
exports
=
OptionController
;
app/middleware/mini_auth_v5.js
View file @
4e1c48c8
...
...
@@ -17,7 +17,7 @@ module.exports = (options, app) => {
}
const
openid
=
userInfo
.
openid
;
const
phone
=
userInfo
.
phone
;
const
authToken
=
ctx
.
headers
.
auth
_toke
n
;
const
authToken
=
ctx
.
headers
.
auth
orizatio
n
;
if
(
ctx
.
helper
.
md5
(
uuid
+
openid
+
phone
+
'jbwl'
)
!==
authToken
)
{
ctx
.
failed
(
'login auth error'
);
}
...
...
app/model/class/v5/courseBanner.js
View file @
4e1c48c8
...
...
@@ -4,7 +4,7 @@
const
moment
=
require
(
'moment'
);
module
.
exports
=
app
=>
{
const
{
STRING
,
INTEGER
,
DATE
,
ENUM
}
=
app
.
Sequelize
;
const
{
STRING
,
INTEGER
,
DATE
}
=
app
.
Sequelize
;
const
CourseBanner
=
app
.
classModel
.
define
(
'course_banner'
,
{
id
:
{
...
...
@@ -17,7 +17,7 @@ module.exports = app => {
url
:
STRING
,
link
:
STRING
,
sort
:
INTEGER
,
status
:
ENUM
(
'offline'
,
'online'
)
,
status
:
INTEGER
,
is_deleted
:
INTEGER
,
created_time
:
{
type
:
DATE
,
...
...
app/model/class/v5/courseBannerType.js
View file @
4e1c48c8
...
...
@@ -4,7 +4,7 @@
const
moment
=
require
(
'moment'
);
module
.
exports
=
app
=>
{
const
{
STRING
,
INTEGER
,
DATE
,
ENUM
}
=
app
.
Sequelize
;
const
{
STRING
,
INTEGER
,
DATE
}
=
app
.
Sequelize
;
const
CourseBannerType
=
app
.
classModel
.
define
(
'course_banner_type'
,
{
id
:
{
...
...
@@ -14,7 +14,7 @@ module.exports = app => {
},
title
:
STRING
,
alias
:
STRING
,
status
:
ENUM
(
'offline'
,
'online'
)
,
status
:
INTEGER
,
is_deleted
:
INTEGER
,
created_time
:
{
type
:
DATE
,
...
...
app/model/class/v5/courseV5Category.js
View file @
4e1c48c8
...
...
@@ -17,7 +17,6 @@ module.exports = app => {
name
:
STRING
,
selected_icon
:
STRING
,
unselected_icon
:
STRING
,
color
:
STRING
,
status
:
INTEGER
,
is_deleted
:
INTEGER
,
sort
:
INTEGER
,
...
...
app/router/course_v5.js
View file @
4e1c48c8
...
...
@@ -9,4 +9,11 @@ module.exports = app => {
router
.
post
(
'third'
,
'/login/wechat'
,
'course.v5.user.loginByWX'
);
// 微信登录
router
.
post
(
'third'
,
'/user/register_user'
,
miniAuth
,
'course.v5.user.registerUserInfo'
);
// 授权后注册用户
router
.
get
(
'third'
,
'/user/info'
,
miniAuth
,
'course.v5.user.getUserInfo'
);
// 获取用户信息
router
.
get
(
'third'
,
'/category/all'
,
'course.v5.option.getCategoryList'
);
// 获取分类列表
router
.
get
(
'third'
,
'/banner/all'
,
'course.v5.option.getBannerList'
);
// 获取banner列表
router
.
get
(
'third'
,
'/class/all'
,
'course.v5.institution.getClassList'
);
// 获取课程列表
router
.
get
(
'third'
,
'/class/:class_id'
,
'course.v5.institution.getClassInfo'
);
// 获取课程详情
};
app/service/course/v5/institution.js
View file @
4e1c48c8
...
...
@@ -8,662 +8,98 @@ const moment = require('moment');
const
sequelize
=
require
(
'sequelize'
);
class
InstitutionSubService
extends
Service
{
// 获取分类
async
getCats
()
{
const
{
ctx
}
=
this
;
const
AllCats
=
await
ctx
.
classModel
.
V4
.
CourseCat
.
findAll
({
where
:
{
status
:
1
,
is_deleted
:
0
}
});
const
rootCats
=
[];
let
ret
=
[];
// 先取出一级分类
for
(
const
v
of
AllCats
)
{
if
(
v
.
parent_id
===
0
)
{
rootCats
[
v
.
id
]
=
v
.
dataValues
;
rootCats
[
v
.
id
].
child
=
[{
id
:
0
,
value
:
v
.
id
,
name
:
'全部'
,
parent_id
:
0
,
image
:
'http://r.51gjj.com/webpublic/images/20191118/s6yRUsc5kclyu.png'
,
active_image
:
'http://r.51gjj.com/webpublic/images/20191118/zYHkYp85vxk5m.png'
,
color
:
''
,
tips
:
''
,
status
:
'online'
,
is_deleted
:
0
}];
}
}
// 放入二级分类
for
(
const
v
of
AllCats
)
{
if
(
v
.
parent_id
>
0
)
{
v
.
value
=
v
.
id
;
rootCats
[
v
.
parent_id
].
child
.
push
(
v
);
}
}
const
sort
=
function
(
a
,
b
)
{
return
a
.
sort
-
b
.
sort
;
};
// 整理
for
(
const
v
of
rootCats
)
{
if
(
!
ctx
.
isEmpty
(
v
))
{
v
.
child
=
R
.
sort
(
sort
)(
v
.
child
);
ret
.
push
(
v
);
}
}
ret
=
R
.
sort
(
sort
)(
ret
);
return
{
results
:
ret
};
}
// 获取机构详情
async
getInstitution
(
input
)
{
const
{
ctx
}
=
this
;
const
userUuid
=
ctx
.
userUuid
;
const
{
institution_id
}
=
input
;
const
lat
=
ctx
.
isEmpty
(
input
.
lat
)
?
0
:
input
.
lat
;
const
lng
=
ctx
.
isEmpty
(
input
.
lng
)
?
0
:
input
.
lng
;
let
institution
=
await
ctx
.
classModel
.
V4
.
CourseInstitution
.
findOne
({
where
:
{
id
:
institution_id
,
status
:
'online'
,
is_deleted
:
0
}
});
if
(
ctx
.
isEmpty
(
institution
))
{
ctx
.
failed
(
'机构不存在'
);
}
institution
=
institution
.
dataValues
;
// 顶部相册
const
images
=
await
ctx
.
classModel
.
V4
.
CourseImages
.
findAll
({
where
:
{
type
:
1
,
type_id
:
institution_id
,
status
:
'online'
,
is_deleted
:
0
}
});
// 去重
const
checkList
=
[];
let
album
=
[];
for
(
const
v
of
images
)
{
if
((
v
.
is_video
===
0
&&
checkList
.
includes
(
v
.
image_url
))
||
(
v
.
is_video
===
1
&&
checkList
.
includes
(
v
.
video_url
)))
{
continue
;
}
album
.
push
(
v
);
}
// 排序,视频在前
const
albumSort
=
function
(
a
,
b
)
{
if
(
a
.
is_video
===
b
.
is_video
)
{
return
a
.
sort
-
b
.
sort
;
}
return
b
.
is_video
-
a
.
is_video
;
};
album
=
R
.
sort
(
albumSort
)(
album
);
// 学习成果
const
student_video
=
await
ctx
.
classModel
.
V4
.
CourseStudentVideo
.
findAll
({
where
:
{
institution_id
,
status
:
'online'
,
is_deleted
:
0
},
order
:
[[
'sort'
,
'asc'
]]
});
// 教师
const
teachers
=
await
ctx
.
classModel
.
V4
.
CourseTeacher
.
findAll
({
where
:
{
institution_id
,
status
:
'online'
,
is_deleted
:
0
},
raw
:
true
});
// 课程
const
classes
=
await
ctx
.
classModel
.
V4
.
CourseClass
.
findAll
({
where
:
{
institution_id
,
status
:
'online'
,
is_deleted
:
0
},
raw
:
true
});
// 处理课程封面图
const
classHandle
=
[];
if
(
classes
.
length
>
0
)
{
for
(
const
v
of
classes
)
{
classHandle
.
push
(
ctx
.
classModel
.
V4
.
CourseImages
.
findOne
({
where
:
{
type
:
2
,
type_id
:
v
.
id
,
status
:
'online'
,
is_deleted
:
0
},
order
:
[[
'sort'
,
'asc'
]]
}));
}
const
classImages
=
await
Promise
.
all
(
classHandle
).
then
(
result
=>
{
return
result
;
}).
catch
(
error
=>
{
ctx
.
failed
(
error
);
});
for
(
const
i
in
classes
)
{
classes
[
i
].
image
=
classImages
[
i
];
}
}
// 校区
let
areas
=
await
ctx
.
classModel
.
V4
.
CourseArea
.
findAll
({
where
:
{
institution_id
,
status
:
'online'
,
is_deleted
:
0
},
raw
:
true
});
const
areaHandle
=
[];
if
(
areas
.
length
>
0
)
{
for
(
const
v
of
areas
)
{
areaHandle
.
push
(
this
.
formatArea
(
v
,
{
lng
,
lat
}));
}
areas
=
await
Promise
.
all
(
areaHandle
).
then
(
result
=>
{
return
result
;
}).
catch
(
error
=>
{
ctx
.
failed
(
error
);
});
}
areas
=
_
.
orderBy
(
areas
,
[
'distance'
],
[
'asc'
]);
// 是否已收藏
const
userCollect
=
await
ctx
.
classModel
.
V4
.
CourseUserCollection
.
findOne
({
where
:
{
type
:
1
,
type_id
:
institution_id
,
user_uuid
:
userUuid
,
is_deleted
:
0
}
});
// 获取所有标签
const
allTags
=
await
ctx
.
classModel
.
V4
.
CourseTag
.
findAll
({
where
:
{
status
:
'online'
,
is_deleted
:
0
}
});
const
tagList
=
[];
for
(
const
v
of
allTags
)
{
tagList
[
v
.
id
]
=
v
;
}
let
tags
=
await
ctx
.
classModel
.
V4
.
CourseInstitutionToTag
.
findAll
({
where
:
{
institution_id
:
institution
.
id
,
status
:
'online'
,
is_deleted
:
0
}
});
tags
=
_
.
orderBy
(
tags
,
[
'sort'
],
[
'asc'
]);
institution
.
tags
=
[];
for
(
const
v
of
tags
)
{
institution
.
tags
.
push
(
tagList
[
v
.
tag_id
]);
}
institution
.
phone
=
areas
.
length
>
0
?
areas
[
0
].
phone
:
''
;
institution
.
distance
=
areas
.
length
>
0
?
String
(
areas
[
0
].
distance
)
+
'km'
:
'无法计算'
;
institution
.
travel_method
=
areas
.
length
>
0
?
areas
[
0
].
travel_method
:
''
;
institution
.
travel_tips
=
areas
.
length
>
0
?
areas
[
0
].
travel_tips
:
''
;
const
ret
=
{
album
,
detail
:
institution
,
student_video
,
teachers
,
classes
,
areas
,
is_collected
:
ctx
.
isEmpty
(
userCollect
)
?
0
:
1
,
};
return
ret
;
}
// 处理校区
async
formatArea
(
area
,
location
)
{
const
{
ctx
,
service
}
=
this
;
if
(
ctx
.
isEmpty
(
area
))
{
return
{};
}
const
distance
=
await
service
.
course
.
v4
.
lbs
.
getDistance
({
lng
:
location
.
lng
,
lat
:
location
.
lat
},
{
lng
:
area
.
lng
,
lat
:
area
.
lat
});
// 暂定3公里以内步行
area
.
travel_method
=
distance
<
3000
?
'walking'
:
'driving'
;
const
lbsResult
=
await
service
.
course
.
v4
.
lbs
.
getLBSDistance
(
area
.
travel_method
,
{
lng
:
location
.
lng
,
lat
:
location
.
lat
},
[{
lng
:
area
.
lng
,
lat
:
area
.
lat
}]);
if
(
lbsResult
.
results
.
length
>
0
)
{
area
.
distance
=
parseFloat
((
lbsResult
.
results
[
0
].
distance
/
1000
).
toFixed
(
1
));
area
.
duration
=
lbsResult
.
results
[
0
].
duration
;
const
minute
=
area
.
travel_method
===
'walking'
?
Math
.
ceil
(
area
.
distance
/
0.08
)
:
Math
.
ceil
(
area
.
duration
/
60
);
area
.
travel_tips
=
area
.
travel_method
===
'walking'
?
`距我
${
area
.
distance
}
km,步行
${
minute
}
分钟`
:
`距我
${
area
.
distance
}
km,开车
${
minute
}
分钟`
;
}
else
{
area
.
distance
=
999999
;
area
.
duration
=
0
;
area
.
travel_tips
=
''
;
}
return
area
;
}
// 机构列表
async
getInstitutions
(
input
)
{
// 课程列表
async
getClassList
(
input
)
{
const
{
ctx
}
=
this
;
const
userUuid
=
ctx
.
userUuid
;
const
{
cat_id
,
age
,
address
}
=
input
;
const
lat
=
ctx
.
isEmpty
(
input
.
lat
)
?
0
:
input
.
lat
;
const
lng
=
ctx
.
isEmpty
(
input
.
lng
)
?
0
:
input
.
lng
;
// 保存定位记录
if
(
address
&&
lat
&&
lng
)
{
ctx
.
classModel
.
V4
.
CourseLogUserGps
.
create
({
user_uuid
:
userUuid
,
address
,
lat
,
lng
,
created_time
:
moment
().
format
(
'YYYY-MM-DD HH:mm:ss'
)
});
}
let
institutionList
=
[];
let
institutionCats
=
[];
const
filter
=
{
where
:
{
status
:
'online'
,
is_deleted
:
0
}
};
// 年龄筛选
if
(
Number
(
age
)
>
0
)
{
filter
.
where
.
min_age
=
{
$lte
:
age
};
filter
.
where
.
max_age
=
{
$gte
:
age
};
}
// 分类筛选
if
(
Number
(
cat_id
)
>
0
)
{
// 如果是一级分类,则需要加入该分类下所有子分类
const
cats
=
await
ctx
.
classModel
.
V4
.
CourseCat
.
findAll
({
where
:
{
parent_id
:
cat_id
,
status
:
'online'
,
is_deleted
:
0
}
});
const
catIds
=
R
.
pluck
(
'id'
,
cats
);
catIds
.
push
(
Number
(
cat_id
));
institutionCats
=
await
ctx
.
classModel
.
V4
.
CourseInstitutionToCat
.
findAll
({
where
:
{
status
:
'online'
,
is_deleted
:
0
,
cat_id
:
{
$in
:
catIds
}
}
});
const
institutionIds
=
R
.
pluck
(
'institution_id'
,
institutionCats
);
filter
.
where
.
id
=
{
$in
:
institutionIds
};
}
institutionList
=
await
ctx
.
classModel
.
V4
.
CourseInstitution
.
findAll
(
filter
);
institutionList
=
R
.
pluck
(
'dataValues'
,
institutionList
);
const
ret
=
await
this
.
formatInstitutionList
(
institutionList
,
input
);
return
ret
;
}
// 格式化机构列表
async
formatInstitutionList
(
institutionList
,
input
)
{
const
{
ctx
,
service
}
=
this
;
const
userUuid
=
ctx
.
userUuid
;
const
distance
=
Number
(
input
.
distance
)
||
0
;
const
page
=
Number
(
input
.
page
)
||
1
;
const
limit
=
Number
(
input
.
limit
)
||
10
;
const
{
lng
,
lat
}
=
input
;
let
institutionCats
=
[];
let
institutionIds
=
R
.
pluck
(
'id'
,
institutionList
);
// 获取机构对应的校区
const
areaList
=
await
ctx
.
classModel
.
V4
.
CourseArea
.
findAll
({
where
:
{
status
:
'online'
,
is_deleted
:
0
,
institution_id
:
{
$in
:
institutionIds
}
}
});
// 计算校区对应的距离
const
areaHandle
=
[];
for
(
const
v
of
areaList
)
{
areaHandle
.
push
(
service
.
course
.
v4
.
lbs
.
getDistance
({
lat
,
lng
},
{
lat
:
v
.
lat
,
lng
:
v
.
lng
}));
}
const
areaDistanceCalcResult
=
await
Promise
.
all
(
areaHandle
).
then
(
result
=>
{
return
result
;
}).
catch
(
error
=>
{
ctx
.
failed
(
error
);
});
for
(
const
i
in
areaList
)
{
areaList
[
i
].
distance
=
areaDistanceCalcResult
[
i
];
}
// 选出最短距离的校区
for
(
const
v
of
areaList
)
{
for
(
const
i
in
institutionList
)
{
if
(
institutionList
[
i
].
id
===
v
.
institution_id
)
{
if
(
ctx
.
isEmpty
(
institutionList
[
i
].
area
)
||
(
institutionList
[
i
].
area
.
distance
>
v
.
distance
))
{
institutionList
[
i
].
area
=
v
;
}
}
}
}
// 格式化机构距离
for
(
const
i
in
institutionList
)
{
institutionList
[
i
].
distance
=
ctx
.
isEmpty
(
institutionList
[
i
].
area
)
?
999999.0
:
institutionList
[
i
].
area
.
distance
;
}
institutionList
=
_
.
orderBy
(
institutionList
,
[
'distance'
],
[
'asc'
]);
// 距离筛选
if
(
Number
(
distance
)
>
0
)
{
for
(
const
i
in
institutionList
)
{
if
(
institutionList
[
i
].
distance
>
Number
(
distance
))
{
institutionList
=
institutionList
.
slice
(
0
,
i
);
break
;
}
}
}
// 分页
const
ret
=
{
results
:
[],
count
:
institutionList
.
length
,
};
institutionList
=
institutionList
.
slice
(
Number
(
page
-
1
)
*
Number
(
limit
),
Number
(
page
)
*
Number
(
limit
));
institutionIds
=
R
.
pluck
(
'id'
,
institutionList
);
// 获取所有分类
const
allCats
=
await
ctx
.
classModel
.
V4
.
CourseCat
.
findAll
({
where
:
{
status
:
'online'
,
is_deleted
:
0
}
});
const
catList
=
[];
for
(
const
v
of
allCats
)
{
catList
[
v
.
id
]
=
v
;
}
institutionCats
=
await
ctx
.
classModel
.
V4
.
CourseInstitutionToCat
.
findAll
({
where
:
{
status
:
'online'
,
is_deleted
:
0
,
institution_id
:
{
$in
:
institutionIds
}
}
});
// 获取所有标签
const
allTags
=
await
ctx
.
classModel
.
V4
.
CourseTag
.
findAll
({
where
:
{
status
:
'online'
,
is_deleted
:
0
}
});
const
tagList
=
[];
for
(
const
v
of
allTags
)
{
tagList
[
v
.
id
]
=
v
;
}
// 用户已收藏机构列表
const
userInstitutions
=
await
ctx
.
classModel
.
V4
.
CourseUserCollection
.
findAll
({
where
:
{
type
:
1
,
is_deleted
:
0
,
user_uuid
:
userUuid
}
});
const
userInstitutionIds
=
R
.
pluck
(
'type_id'
,
userInstitutions
);
// 机构图片及格式化
for
(
const
i
in
institutionList
)
{
// 格式化机构分类(展示一级分类)
let
cats
=
[];
for
(
const
v
of
institutionCats
)
{
if
(
v
.
institution_id
===
institutionList
[
i
].
id
&&
catList
[
v
.
cat_id
])
{
if
(
catList
[
v
.
cat_id
].
parent_id
===
0
)
{
cats
.
push
(
v
.
cat_id
);
}
else
{
cats
.
push
(
catList
[
v
.
cat_id
].
parent_id
);
}
}
}
// 去重
cats
=
_
.
uniq
(
cats
);
institutionList
[
i
].
cats
=
[];
for
(
const
v
of
cats
)
{
institutionList
[
i
].
cats
.
push
(
catList
[
v
]);
}
// 标签
let
tags
=
await
ctx
.
classModel
.
V4
.
CourseInstitutionToTag
.
findAll
({
where
:
{
institution_id
:
institutionList
[
i
].
id
,
status
:
'online'
,
is_deleted
:
0
}
});
tags
=
_
.
orderBy
(
tags
,
[
'sort'
],
[
'asc'
]);
institutionList
[
i
].
tags
=
[];
for
(
const
v
of
tags
)
{
institutionList
[
i
].
tags
.
push
(
tagList
[
v
.
tag_id
]);
}
// 优先获取机构详情图
let
institutionImages
=
await
ctx
.
classModel
.
V4
.
CourseImages
.
findAll
({
where
:
{
type
:
1
,
type_id
:
institutionList
[
i
].
id
,
status
:
'online'
,
is_deleted
:
0
},
order
:
[[
'sort'
,
'asc'
]],
limit
:
3
});
if
(
institutionImages
.
length
<
3
)
{
const
defaultImages
=
await
ctx
.
classModel
.
V4
.
CourseImages
.
findAll
({
where
:
{
type
:
4
,
type_id
:
{
$in
:
cats
},
status
:
'online'
,
is_deleted
:
0
},
limit
:
3
-
institutionImages
.
length
});
institutionImages
=
institutionImages
.
concat
(
defaultImages
);
}
institutionList
[
i
].
images
=
institutionImages
;
institutionList
[
i
].
distance
=
String
((
institutionList
[
i
].
distance
/
1000
).
toFixed
(
1
))
+
'km'
;
institutionList
[
i
].
phone
=
institutionList
[
i
].
area
.
length
>
0
?
institutionList
[
i
].
area
[
0
].
phone
:
''
;
// 是否已收藏
institutionList
[
i
].
is_collected
=
userInstitutionIds
.
includes
(
institutionList
[
i
].
id
)
?
1
:
0
;
ret
.
results
.
push
(
institutionList
[
i
]);
}
return
ret
;
}
// 搜索
async
search
(
input
)
{
const
{
ctx
}
=
this
;
const
{
cat_id
,
age
,
search
}
=
input
;
const
userUuid
=
ctx
.
userUuid
;
// 保存搜索记录
if
(
search
)
{
const
searchInfo
=
await
ctx
.
classModel
.
V4
.
CourseSearch
.
findOne
({
where
:
{
content
:
search
,
is_deleted
:
0
}
});
if
(
searchInfo
)
{
await
ctx
.
classModel
.
V4
.
CourseSearch
.
update
({
count
:
searchInfo
.
count
+
1
},
{
where
:
{
id
:
searchInfo
.
id
}
});
}
else
{
await
ctx
.
classModel
.
V4
.
CourseSearch
.
create
({
content
:
search
,
sort
:
0
,
count
:
1
,
is_hot
:
0
,
status
:
'online'
,
is_deleted
:
0
,
created_time
:
moment
().
format
(
'YYYY-MM-DD HH:mm:ss'
),
updated_time
:
moment
().
format
(
'YYYY-MM-DD HH:mm:ss'
)
});
}
await
ctx
.
classModel
.
V4
.
CourseUserSearch
.
create
({
user_uuid
:
userUuid
,
content
:
search
,
status
:
'online'
,
created_time
:
moment
().
format
(
'YYYY-MM-DD HH:mm:ss'
),
updated_time
:
moment
().
format
(
'YYYY-MM-DD HH:mm:ss'
)
});
}
let
institutionList
=
[];
let
institutionCats
=
[];
let
institutionIds
=
[];
const
filter
=
{
where
:
{
status
:
'online'
,
is_deleted
:
0
},
row
:
true
};
const
classFilter
=
{
where
:
{
status
:
'online'
,
is_deleted
:
0
,
name
:
{
$like
:
'%'
+
search
+
'%'
}
},
attributes
:
[
'id'
,
'institution_id'
,
'name'
,
'status'
,
'is_deleted'
],
row
:
true
};
const
page_size
=
Number
(
input
.
page_size
)
||
10
;
const
offset
=
(
page
-
1
)
*
page_size
;
const
attributes
=
[
'id'
,
'institution_id'
,
'name'
,
'logo'
,
'age'
,
'price'
,
'price_type'
,
'mode'
,
'time'
,
'class_amount'
,
'multi_classes'
,
'cycle'
,
'description'
,
'sort'
];
const
filter
=
{
where
:
{
status
:
1
,
is_deleted
:
0
},
order
:
[[
'sort'
,
'asc'
],
[
'id'
,
'desc'
]],
page_size
,
offset
,
attributes
};
let
filterIds
=
[];
let
flag
=
false
;
// 年龄筛选
if
(
Number
(
age
)
>
0
)
{
filter
.
where
.
min_age
=
{
$lte
:
age
};
filter
.
where
.
max_age
=
{
$gte
:
age
};
}
// 分类筛选
if
(
Number
(
cat_id
)
>
0
)
{
// 如果是一级分类,则需要加入该分类下所有子分类
const
cats
=
await
ctx
.
classModel
.
V4
.
CourseCat
.
findAll
({
where
:
{
parent_id
:
cat_id
,
status
:
'online'
,
is_deleted
:
0
}
});
const
catIds
=
R
.
pluck
(
'id'
,
cats
);
catIds
.
push
(
Number
(
cat_id
));
institutionCats
=
await
ctx
.
classModel
.
V4
.
CourseInstitutionToCat
.
findAll
({
where
:
{
status
:
'online'
,
is_deleted
:
0
,
cat_id
:
{
$in
:
catIds
}
}
});
institutionIds
=
R
.
pluck
(
'institution_id'
,
institutionCats
);
if
(
!
ctx
.
isEmpty
(
input
.
age
))
{
const
filterByAge
=
await
ctx
.
classModel
.
CourseV5ClassToAge
.
findAll
({
where
:
{
age_id
:
input
.
age
,
status
:
1
,
is_deleted
:
0
},
attributes
:
[
'class_id'
]
});
filterIds
=
R
.
pluck
(
'class_id'
,
filterByAge
);
flag
=
true
;
}
if
(
institutionIds
.
length
>
0
)
{
filter
.
where
.
id
=
{
$in
:
institutionIds
};
classFilter
.
where
.
institution_id
=
{
$in
:
institutionIds
};
}
const
institutionFilter
=
filter
;
institutionFilter
.
where
.
name
=
{
$like
:
'%'
+
search
+
'%'
};
institutionList
=
await
ctx
.
classModel
.
V4
.
CourseInstitution
.
findAll
(
institutionFilter
);
const
ids
=
R
.
pluck
(
'id'
,
institutionList
);
// 课程搜索
const
classList
=
await
ctx
.
classModel
.
V4
.
CourseClass
.
findAll
(
classFilter
);
// 去除已经搜到的机构
const
classInstitutionIds
=
_
.
difference
(
R
.
pluck
(
'institution_id'
,
classList
),
ids
);
if
(
classInstitutionIds
.
length
>
0
)
{
filter
.
where
.
id
=
{
$in
:
classInstitutionIds
};
const
classInstitutionList
=
await
ctx
.
classModel
.
V4
.
CourseInstitution
.
findAll
(
filter
);
institutionList
=
institutionList
.
concat
(
classInstitutionList
);
}
institutionList
=
R
.
pluck
(
'dataValues'
,
institutionList
);
const
ret
=
await
this
.
formatInstitutionList
(
institutionList
,
input
);
return
ret
;
}
// 获取热搜
async
getHotSearch
()
{
const
{
ctx
}
=
this
;
const
search
=
await
ctx
.
classModel
.
V4
.
CourseSearch
.
findAll
({
where
:
{
status
:
'online'
,
is_deleted
:
0
,
is_hot
:
1
},
order
:
[[
'sort'
,
'asc'
]]
});
const
ret
=
{
results
:
R
.
pluck
(
'content'
,
search
),
count
:
search
.
length
,
};
return
ret
;
}
// 获取用户搜索历史
async
getUserSearch
()
{
const
{
ctx
}
=
this
;
const
userUuid
=
ctx
.
userUuid
;
const
search
=
await
ctx
.
classModel
.
V4
.
CourseUserSearch
.
findAll
({
where
:
{
status
:
'online'
,
user_uuid
:
userUuid
},
limit
:
10
,
order
:
[[
'id'
,
'desc'
]]
});
const
result
=
_
.
uniq
(
R
.
pluck
(
'content'
,
search
));
const
ret
=
{
results
:
result
,
count
:
result
.
length
,
};
return
ret
;
}
// 删除用户搜索历史
async
deleteUserSearch
()
{
const
{
ctx
}
=
this
;
const
userUuid
=
ctx
.
userUuid
;
await
ctx
.
classModel
.
V4
.
CourseUserSearch
.
update
({
status
:
'offline'
},
{
where
:
{
user_uuid
:
userUuid
,
status
:
'online'
}
});
return
;
}
// 评论列表
async
getComments
(
input
)
{
const
{
ctx
}
=
this
;
const
page
=
Number
(
input
.
page
)
||
1
;
const
limit
=
Number
(
input
.
limit
)
||
10
;
const
offset
=
(
page
-
1
)
*
limit
;
const
institution_id
=
Number
(
input
.
institution_id
)
||
0
;
const
comments
=
await
ctx
.
classModel
.
V4
.
CourseComment
.
findAndCountAll
({
where
:
{
institution_id
,
status
:
'online'
,
is_deleted
:
0
},
offset
,
limit
,
order
:
[[
'id'
,
'desc'
]]
});
comments
.
rows
=
R
.
pluck
(
'dataValues'
,
comments
.
rows
);
const
ret
=
{
results
:
await
this
.
formatComments
(
comments
.
rows
),
count
:
comments
.
count
,
};
return
ret
;
}
// 格式化评论列表
async
formatComments
(
comments
)
{
const
{
ctx
}
=
this
;
if
(
ctx
.
isEmpty
(
comments
))
{
return
[];
// 科目类型
if
(
!
ctx
.
isEmpty
(
input
.
cat_id
))
{
const
filterByCategory
=
await
ctx
.
classModel
.
CourseV5ClassToCat
.
findAll
({
where
:
{
cat_id
:
input
.
cate_id
,
status
:
1
,
is_deleted
:
0
},
attributes
:
[
'class_id'
]
});
filterIds
=
flag
?
_
.
intersection
(
filterIds
,
R
.
pluck
(
'class_id'
,
filterByCategory
))
:
R
.
pluck
(
'class_id'
,
filterByCategory
);
flag
=
true
;
}
const
ids
=
R
.
pluck
(
'id'
,
comments
);
const
images
=
await
ctx
.
classModel
.
V4
.
CourseImages
.
findAll
({
where
:
{
type
:
3
,
type_id
:
{
$in
:
ids
},
status
:
'online'
,
is_deleted
:
0
}
});
const
ret
=
[];
for
(
const
v
of
comments
)
{
// 评论图片
let
commentImages
=
[];
for
(
const
j
of
images
)
{
if
(
j
.
type_id
===
v
.
id
)
{
commentImages
.
push
(
j
);
}
}
commentImages
=
_
.
orderBy
(
commentImages
,
[
'sort'
],
[
'asc'
]);
ret
.
push
({
id
:
v
.
id
,
institution_id
:
v
.
institution_id
,
user_uuid
:
v
.
user_uuid
,
nickname
:
v
.
nickname
,
avatar
:
v
.
avatar
,
content
:
v
.
content
,
has_image
:
v
.
has_image
,
images
:
commentImages
,
created_time
:
v
.
created_time
,
});
// 课程状态
if
(
!
ctx
.
isEmpty
(
input
.
mode
))
{
filter
.
where
.
mode
=
input
.
mode
;
}
return
ret
;
}
// 搜索关联
async
getSuggestSearch
(
input
)
{
const
{
ctx
}
=
this
;
const
{
search
}
=
input
;
let
results
=
[];
if
(
!
ctx
.
isEmpty
(
search
))
{
const
institutions
=
await
ctx
.
classModel
.
V4
.
CourseInstitution
.
findAll
({
where
:
{
status
:
'online'
,
is_deleted
:
0
,
name
:
{
$like
:
'%'
+
search
+
'%'
}
},
limit
:
10
,
attributes
:
[
'id'
,
'name'
,
'status'
,
'is_deleted'
]
});
results
=
R
.
pluck
(
'name'
,
institutions
);
// 课程类型
if
(
!
ctx
.
isEmpty
(
input
.
price_type
))
{
filter
.
where
.
price_type
=
input
.
price_type
;
}
const
ret
=
{
results
,
count
:
results
.
length
,
};
return
ret
;
}
// 教师详情
async
getTeacher
(
id
)
{
const
{
ctx
}
=
this
;
let
teacher
=
await
ctx
.
classModel
.
V4
.
CourseTeacher
.
findOne
({
where
:
{
id
,
status
:
'online'
,
is_deleted
:
0
}
});
if
(
ctx
.
isEmpty
(
teacher
))
{
ctx
.
failed
(
'数据不存在'
);
if
(
flag
)
{
filter
.
where
.
id
=
{
$in
:
filterIds
};
}
teacher
=
teacher
.
dataValues
;
teacher
.
point_tags
=
teacher
.
point
?
teacher
.
point
.
split
(
','
)
:
[];
teacher
.
work_experience_tags
=
teacher
.
work_experience
?
teacher
.
work_experience
.
split
(
';'
)
:
[];
const
institution
=
await
ctx
.
classModel
.
V4
.
CourseInstitution
.
findOne
({
where
:
{
id
:
teacher
.
institution_id
}
});
teacher
.
institution_name
=
institution
.
name
;
return
teacher
;
}
const
classList
=
await
ctx
.
classModel
.
CourseV5Class
.
findAndCountAll
(
filter
);
// 教师列表
async
getTeachers
(
input
)
{
const
{
ctx
}
=
this
;
const
page
=
Number
(
input
.
page
)
||
1
;
const
limit
=
Number
(
input
.
limit
)
||
10
;
const
offset
=
(
page
-
1
)
*
limit
;
const
institutionId
=
Number
(
input
.
institution_id
)
||
0
;
const
teachers
=
await
ctx
.
classModel
.
V4
.
CourseTeacher
.
findAndCountAll
({
where
:
{
institution_id
:
institutionId
,
status
:
'online'
,
is_deleted
:
0
},
raw
:
true
,
offset
,
limit
});
const
ret
=
{
results
:
teachers
.
rows
,
count
:
teachers
.
count
,
};
return
ret
;
}
// 课程列表
async
getClasses
(
input
)
{
const
{
ctx
}
=
this
;
const
page
=
Number
(
input
.
page
)
||
1
;
const
limit
=
Number
(
input
.
limit
)
||
10
;
const
offset
=
(
page
-
1
)
*
limit
;
const
institutionId
=
Number
(
input
.
institution_id
)
||
0
;
const
inputClassIds
=
input
.
classIds
||
[];
const
attributes
=
[
'id'
,
'institution_id'
,
'name'
,
'type'
,
'class_price'
,
'min_age'
,
'max_age'
,
'status'
,
'is_deleted'
];
let
classes
=
{
rows
:
[],
count
:
0
};
if
(
institutionId
>
0
)
{
classes
=
await
ctx
.
classModel
.
V4
.
CourseClass
.
findAndCountAll
({
where
:
{
institution_id
:
institutionId
,
status
:
'online'
,
is_deleted
:
0
},
raw
:
true
,
offset
,
limit
,
attributes
});
}
else
if
(
inputClassIds
.
length
>
0
)
{
classes
=
await
ctx
.
classModel
.
V4
.
CourseClass
.
findAndCountAll
({
where
:
{
id
:
{
$in
:
inputClassIds
},
status
:
'online'
,
is_deleted
:
0
},
raw
:
true
,
offset
,
limit
,
attributes
});
}
const
classIds
=
R
.
pluck
(
'id'
,
classes
.
rows
);
// 课程图片
const
classImages
=
await
ctx
.
classModel
.
V4
.
CourseImages
.
findAll
({
where
:
{
type
:
2
,
type_id
:
{
$in
:
classIds
},
status
:
'online'
,
is_deleted
:
0
},
raw
:
true
});
// 用户收藏的课程
const
userCollection
=
await
ctx
.
classModel
.
V
4
.
CourseUserCollection
.
findAll
({
where
:
{
user_uuid
:
ctx
.
userUuid
,
is_deleted
:
0
,
type
:
2
},
raw
:
true
});
const
userCollection
=
await
ctx
.
classModel
.
V
5
.
CourseUserCollection
.
findAll
({
where
:
{
user_uuid
:
ctx
.
userUuid
,
is_deleted
:
0
,
type
:
3
},
raw
:
true
});
const
collectedIds
=
R
.
pluck
(
'type_id'
,
userCollection
);
for
(
const
i
in
classes
.
rows
)
{
let
images
=
[];
for
(
const
v
of
classImages
)
{
if
(
v
.
type_id
===
classes
.
rows
[
i
].
id
)
{
images
.
push
(
v
);
}
}
images
=
_
.
orderBy
(
images
,
[
'sort'
],
[
'asc'
]);
classes
.
rows
[
i
].
image
=
images
.
length
>
0
?
images
[
0
]
:
{};
classes
.
rows
[
i
].
is_collected
=
collectedIds
.
includes
(
classes
.
rows
[
i
].
id
)
?
1
:
0
;
classes
.
rows
[
i
].
age
=
classes
.
rows
[
i
].
min_age
===
0
&&
classes
.
rows
[
i
].
max_age
===
0
?
''
:
`
${
classes
.
rows
[
i
].
min_age
}
-
${
classes
.
rows
[
i
].
max_age
}
岁`
;
classes
.
rows
[
i
].
class_price
=
classes
.
rows
[
i
].
class_price
||
'到店咨询'
;
for
(
const
i
in
classList
.
rows
)
{
classList
.
rows
[
i
].
is_collected
=
collectedIds
.
includes
(
classList
.
rows
[
i
].
id
)
?
1
:
0
;
}
const
ret
=
{
results
:
classes
.
rows
,
count
:
classes
.
count
,
list
:
classList
.
rows
,
total_count
:
classList
.
count
,
page
,
page_size
,
};
return
ret
;
}
// 课程详情
async
getClass
(
input
)
{
async
getClass
Info
(
id
)
{
const
{
ctx
}
=
this
;
const
classInfo
=
await
ctx
.
classModel
.
V4
.
CourseClass
.
findOne
({
where
:
{
id
:
input
.
id
,
status
:
'online'
,
is_deleted
:
0
},
raw
:
true
});
const
attributes
=
[
'id'
,
'institution_id'
,
'name'
,
'logo'
,
'age'
,
'price'
,
'price_type'
,
'mode'
,
'time'
,
'class_amount'
,
'multi_classes'
,
'cycle'
,
'description'
,
'sort'
];
const
classInfo
=
await
ctx
.
classModel
.
V5
.
CourseV5Class
.
findOne
({
where
:
{
id
,
status
:
1
,
is_deleted
:
0
},
attributes
,
raw
:
true
});
if
(
ctx
.
isEmpty
(
classInfo
))
{
ctx
.
failed
(
'数据不存在'
);
}
// 课程图片
let
images
=
await
ctx
.
classModel
.
V4
.
CourseImages
.
findAll
({
where
:
{
type
:
2
,
type_id
:
input
.
id
,
status
:
'online'
,
is_deleted
:
0
},
raw
:
true
});
// 去重
images
=
_
.
uniqBy
(
images
,
function
(
v
)
{
return
(
v
.
is_image
===
1
?
v
.
image_url
:
v
.
video_url
);
});
images
=
_
.
orderBy
(
images
,
[
'sort'
],
[
'asc'
]);
classInfo
.
images
=
images
;
classInfo
.
class_price
=
ctx
.
isEmpty
(
classInfo
.
class_price
)
?
''
:
classInfo
.
class_price
+
'元/课时'
;
input
.
institution_id
=
classInfo
.
institution_id
;
const
institution
=
await
this
.
getInstitution
(
input
);
classInfo
.
institution
=
ctx
.
isEmpty
(
institution
)
?
{}
:
institution
.
detail
;
classInfo
.
area
=
ctx
.
isEmpty
(
institution
)
||
ctx
.
isEmpty
(
institution
.
areas
)
?
{}
:
institution
.
areas
[
0
];
const
isCollected
=
await
ctx
.
classModel
.
V4
.
CourseUserCollection
.
findOne
({
where
:
{
user_uuid
:
ctx
.
userUuid
,
type
:
2
,
type_id
:
input
.
id
,
is_deleted
:
0
}
});
const
isCollected
=
await
ctx
.
classModel
.
V5
.
CourseUserCollection
.
findOne
({
where
:
{
user_uuid
:
ctx
.
userUuid
,
type
:
3
,
type_id
:
id
,
is_deleted
:
0
}
});
classInfo
.
is_collected
=
ctx
.
isEmpty
(
isCollected
)
?
0
:
1
;
return
classInfo
;
}
// 额外字段
const
classColumns
=
await
ctx
.
classModel
.
V5
.
CourseV5ClassToColumn
.
findAll
({
where
:
{
class_id
:
id
,
status
:
1
,
is_deleted
:
0
}
});
let
columnList
=
await
ctx
.
classModel
.
V5
.
CourseV5Column
.
findAll
({
where
:
{
id
:
{
$in
:
R
.
pluck
(
'column_id'
,
classColumns
)
},
status
:
1
,
is_deleted
:
0
},
attributes
:
[
'name'
]
});
columnList
=
_
.
groupBy
(
columnList
,
'id'
);
// 用户收藏机构列表
async
getUserCollectedInstitutions
(
input
)
{
const
{
ctx
}
=
this
;
const
userUuid
=
ctx
.
userUuid
;
const
userCollection
=
await
ctx
.
classModel
.
V4
.
CourseUserCollection
.
findAll
({
where
:
{
user_uuid
:
userUuid
,
is_deleted
:
0
,
type
:
1
},
raw
:
true
});
const
institutionIds
=
R
.
pluck
(
'type_id'
,
userCollection
);
const
institutionList
=
await
ctx
.
classModel
.
V4
.
CourseInstitution
.
findAll
({
where
:
{
id
:
{
$in
:
institutionIds
},
status
:
'online'
,
is_deleted
:
0
},
raw
:
true
});
const
columns
=
[];
for
(
const
v
of
classColumns
)
{
if
(
!
ctx
.
isEmpty
(
columnList
[
v
.
column_id
]))
{
columns
.
push
({
id
:
v
.
column_id
,
key
:
columnList
[
v
.
column_id
][
0
].
name
,
value
:
v
.
value
,
});
}
}
classInfo
.
columns
=
columns
;
const
ret
=
await
this
.
formatInstitutionList
(
institutionList
,
input
);
return
ret
;
return
classInfo
;
}
// 用户收藏课程列表
async
getUserCollectedClasses
(
input
)
{
const
{
ctx
}
=
this
;
const
userUuid
=
ctx
.
userUuid
;
const
userCollection
=
await
ctx
.
classModel
.
V
4
.
CourseUserCollection
.
findAll
({
where
:
{
user_uuid
:
userUuid
,
is_deleted
:
0
,
type
:
2
},
raw
:
true
});
const
userCollection
=
await
ctx
.
classModel
.
V
5
.
CourseUserCollection
.
findAll
({
where
:
{
user_uuid
:
userUuid
,
is_deleted
:
0
,
type
:
2
},
raw
:
true
});
const
classIds
=
R
.
pluck
(
'type_id'
,
userCollection
);
input
.
classIds
=
classIds
;
...
...
@@ -671,220 +107,7 @@ class InstitutionSubService extends Service {
return
ret
;
}
// 获取指定分类及子分类的选课指南
async
getArticlesByCat
(
input
)
{
const
{
ctx
}
=
this
;
const
page
=
Number
(
input
.
page
)
||
1
;
const
limit
=
Number
(
input
.
limit
)
||
2
;
const
offset
=
(
page
-
1
)
*
limit
;
const
catId
=
Number
(
input
.
cat_id
)
||
0
;
let
catIds
=
[];
const
filter
=
{
where
:
{
status
:
'online'
,
is_deleted
:
0
},
order
:
[[
'sort'
,
'asc'
],
[
'id'
,
'desc'
]],
limit
,
offset
};
// 获取子分类
if
(
catId
>
0
)
{
const
cats
=
await
ctx
.
classModel
.
V4
.
CourseCat
.
findAll
({
where
:
{
parent_id
:
catId
,
status
:
'online'
,
is_deleted
:
0
}
});
catIds
=
R
.
pluck
(
'id'
,
cats
);
catIds
.
push
(
catId
);
filter
.
where
.
cat_id
=
{
$in
:
catIds
};
}
// 获取分类
const
cats
=
await
ctx
.
classModel
.
V4
.
CourseCat
.
findAll
({
where
:
{
status
:
'online'
,
is_deleted
:
0
}
});
const
catMap
=
new
Map
();
for
(
const
v
of
cats
)
{
catMap
.
set
(
v
.
id
,
v
);
}
const
articles
=
await
ctx
.
classModel
.
V4
.
CourseArticle
.
findAndCountAll
(
filter
);
const
ret
=
[];
// 用户点赞列表
const
userLikes
=
await
ctx
.
classModel
.
V4
.
CourseLike
.
findAll
({
where
:
{
user_uuid
:
ctx
.
userUuid
,
type
:
1
,
is_deleted
:
0
}
});
const
userLikeIds
=
R
.
pluck
(
'type_id'
,
userLikes
);
for
(
const
v
of
articles
.
rows
)
{
ret
.
push
({
id
:
v
.
id
,
type
:
v
.
type
,
cat_id
:
v
.
cat_id
,
cat_title
:
catMap
.
has
(
v
.
cat_id
)
?
catMap
.
get
(
v
.
cat_id
).
name
:
''
,
title
:
v
.
title
,
description
:
v
.
description
,
content
:
v
.
content
,
image
:
v
.
image
,
source
:
v
.
source
,
like_count
:
v
.
like_count
,
read_count
:
v
.
read_count
,
sort
:
v
.
sort
,
is_like
:
userLikeIds
.
includes
(
v
.
id
)
?
1
:
0
,
created_time
:
v
.
created_time
,
});
}
return
{
results
:
ret
,
count
:
articles
.
count
,
page
};
}
// 获取选课指南
async
getArticle
(
id
)
{
const
{
ctx
}
=
this
;
const
article
=
await
ctx
.
classModel
.
V4
.
CourseArticle
.
findOne
({
where
:
{
id
,
status
:
'online'
,
is_deleted
:
0
}
});
if
(
ctx
.
isEmpty
(
article
))
{
ctx
.
failed
(
'数据不存在'
);
}
await
ctx
.
classModel
.
V4
.
CourseArticle
.
update
({
read_count
:
sequelize
.
literal
(
'`read_count` + 1'
)
},
{
where
:
{
id
}
});
// 用户是否点赞
const
userLike
=
await
ctx
.
classModel
.
V4
.
CourseLike
.
findOne
({
where
:
{
user_uuid
:
ctx
.
userUuid
,
type
:
1
,
type_id
:
id
,
is_deleted
:
0
}
});
// 获取分类
const
cats
=
await
ctx
.
classModel
.
V4
.
CourseCat
.
findAll
({
where
:
{
status
:
'online'
,
is_deleted
:
0
}
});
const
catMap
=
new
Map
();
for
(
const
v
of
cats
)
{
catMap
.
set
(
v
.
id
,
v
);
}
// 获取关联列表
let
relations
=
[];
if
(
!
ctx
.
isEmpty
(
article
.
relations
))
{
const
ids
=
article
.
relations
.
split
(
','
);
relations
=
await
ctx
.
classModel
.
V4
.
CourseArticle
.
findAll
({
where
:
{
id
:
{
$in
:
ids
},
status
:
'online'
,
is_deleted
:
0
},
order
:
[[
'sort'
,
'asc'
],
[
'id'
,
'desc'
]],
attributes
:
[
'id'
,
'title'
,
'type'
,
'image'
,
'read_count'
]
});
}
const
ret
=
{
id
:
article
.
id
,
type
:
article
.
type
,
cat_id
:
article
.
cat_id
,
cat_title
:
catMap
.
has
(
article
.
cat_id
)
?
catMap
.
get
(
article
.
cat_id
).
name
:
''
,
title
:
article
.
title
,
description
:
article
.
description
,
content
:
article
.
content
,
image
:
article
.
image
,
source
:
article
.
source
,
like_count
:
article
.
like_count
,
read_count
:
article
.
read_count
,
sort
:
article
.
sort
,
relations
,
is_like
:
ctx
.
isEmpty
(
userLike
)
?
0
:
1
,
created_time
:
article
.
created_time
,
};
return
ret
;
}
// 点赞 1:选课指南;
async
like
(
input
)
{
const
{
ctx
}
=
this
;
const
type
=
Number
(
input
.
type
)
||
0
;
const
typeId
=
Number
(
input
.
type_id
)
||
0
;
let
tmp
=
{};
if
(
type
===
0
||
typeId
===
0
)
{
ctx
.
failed
(
'参数异常'
);
}
// 是否重复点赞
tmp
=
await
ctx
.
classModel
.
V4
.
CourseLike
.
findOne
({
where
:
{
user_uuid
:
ctx
.
userUuid
,
type
,
type_id
:
typeId
,
is_deleted
:
0
}
});
if
(
!
ctx
.
isEmpty
(
tmp
))
{
ctx
.
failed
(
'请勿重复点赞'
);
}
// 校验点赞对象是否存在
switch
(
type
)
{
case
1
:
tmp
=
await
ctx
.
classModel
.
V4
.
CourseArticle
.
findOne
({
where
:
{
id
:
typeId
,
status
:
'online'
,
is_deleted
:
0
}
});
if
(
ctx
.
isEmpty
(
tmp
))
{
ctx
.
failed
(
'数据不存在'
);
}
// 更新点赞数
await
ctx
.
classModel
.
V4
.
CourseArticle
.
update
({
like_count
:
sequelize
.
literal
(
'`like_count` + 1'
)
},
{
where
:
{
id
:
typeId
}
});
break
;
default
:
break
;
}
await
ctx
.
classModel
.
V4
.
CourseLike
.
create
({
user_uuid
:
ctx
.
userUuid
,
type
,
type_id
:
typeId
,
is_deleted
:
0
,
created_time
:
moment
().
format
(
'YYYY-MM-DD HH:mm:ss'
)
});
return
;
}
// 取消点赞
async
unlike
(
input
)
{
const
{
ctx
}
=
this
;
const
type
=
Number
(
input
.
type
)
||
0
;
const
typeId
=
Number
(
input
.
type_id
)
||
0
;
let
tmp
=
{};
if
(
type
===
0
||
typeId
===
0
)
{
ctx
.
failed
(
'参数异常'
);
}
// 是否重复点赞
const
userLike
=
await
ctx
.
classModel
.
V4
.
CourseLike
.
findOne
({
where
:
{
user_uuid
:
ctx
.
userUuid
,
type
,
type_id
:
typeId
,
is_deleted
:
0
}
});
if
(
ctx
.
isEmpty
(
userLike
))
{
ctx
.
failed
(
'尚未点赞'
);
}
// 校验点赞对象是否存在
switch
(
type
)
{
case
1
:
tmp
=
await
ctx
.
classModel
.
V4
.
CourseArticle
.
findOne
({
where
:
{
id
:
typeId
,
status
:
'online'
,
is_deleted
:
0
}
});
if
(
ctx
.
isEmpty
(
tmp
))
{
ctx
.
failed
(
'数据不存在'
);
}
// 更新点赞数
await
ctx
.
classModel
.
V4
.
CourseArticle
.
update
({
like_count
:
sequelize
.
literal
(
'`like_count` - 1'
)
},
{
where
:
{
id
:
typeId
}
});
break
;
default
:
break
;
}
await
ctx
.
classModel
.
V4
.
CourseLike
.
update
({
is_deleted
:
1
},
{
where
:
{
id
:
userLike
.
id
}
});
return
;
}
// 获取选课指南推荐列表
async
getArticlesByRecommend
(
input
)
{
const
{
ctx
}
=
this
;
const
page
=
Number
(
input
.
page
)
||
1
;
const
limit
=
Number
(
input
.
limit
)
||
2
;
const
offset
=
(
page
-
1
)
*
limit
;
const
articles
=
await
ctx
.
classModel
.
V4
.
CourseArticle
.
findAndCountAll
({
where
:
{
is_recommend
:
1
,
status
:
'online'
,
is_deleted
:
0
},
order
:
[[
'sort'
,
'asc'
],
[
'id'
,
'desc'
]],
limit
,
offset
});
// 获取分类
const
cats
=
await
ctx
.
classModel
.
V4
.
CourseCat
.
findAll
({
where
:
{
status
:
'online'
,
is_deleted
:
0
}
});
const
catMap
=
new
Map
();
for
(
const
v
of
cats
)
{
catMap
.
set
(
v
.
id
,
v
);
}
const
ret
=
[];
// 用户点赞列表
const
userLikes
=
await
ctx
.
classModel
.
V4
.
CourseLike
.
findAll
({
where
:
{
user_uuid
:
ctx
.
userUuid
,
type
:
1
,
is_deleted
:
0
}
});
const
userLikeIds
=
R
.
pluck
(
'type_id'
,
userLikes
);
for
(
const
v
of
articles
.
rows
)
{
ret
.
push
({
id
:
v
.
id
,
type
:
v
.
type
,
cat_id
:
v
.
cat_id
,
cat_title
:
catMap
.
has
(
v
.
cat_id
)
?
catMap
.
get
(
v
.
cat_id
).
name
:
''
,
title
:
v
.
title
,
description
:
v
.
description
,
content
:
v
.
content
,
image
:
v
.
image
,
source
:
v
.
source
,
like_count
:
v
.
like_count
,
read_count
:
v
.
read_count
,
sort
:
v
.
sort
,
is_like
:
userLikeIds
.
includes
(
v
.
id
)
?
1
:
0
,
created_time
:
v
.
created_time
,
});
}
return
{
results
:
ret
,
count
:
articles
.
count
,
page
};
}
//
}
module
.
exports
=
InstitutionSubService
;
app/service/course/v5/option.js
View file @
4e1c48c8
...
...
@@ -46,17 +46,27 @@ class OptionService extends Service {
return
options
;
}
async
getBanner
s
(
alias
)
{
async
getBanner
List
(
alias
)
{
const
{
ctx
}
=
this
;
const
bannerType
=
await
ctx
.
classModel
.
V5
.
CourseBannerType
.
findOne
({
where
:
{
alias
,
status
:
'online'
,
is_deleted
:
0
},
row
:
true
});
const
bannerType
=
await
ctx
.
classModel
.
V5
.
CourseBannerType
.
findOne
({
where
:
{
alias
,
status
:
1
,
is_deleted
:
0
},
row
:
true
});
if
(
ctx
.
isEmpty
(
bannerType
))
{
ctx
.
failed
(
'数据不存在'
);
}
const
banners
=
await
ctx
.
classModel
.
V5
.
CourseBanner
.
findAll
({
where
:
{
type_id
:
bannerType
.
id
,
status
:
'online'
,
is_deleted
:
0
},
order
:
[[
'sort'
,
'asc'
]],
row
:
true
});
const
banners
=
await
ctx
.
classModel
.
V5
.
CourseBanner
.
findAll
({
where
:
{
type_id
:
bannerType
.
id
,
status
:
1
,
is_deleted
:
0
},
order
:
[[
'sort'
,
'asc'
]],
row
:
true
});
const
results
=
[];
for
(
const
v
of
banners
)
{
results
.
push
({
id
:
v
.
id
,
title
:
v
.
title
,
url
:
v
.
url
,
link
:
v
.
link
,
created_time
:
v
.
created_time
,
});
}
const
ret
=
{
results
:
banners
,
count
:
banners
.
length
,
list
:
results
,
};
return
ret
;
...
...
@@ -84,9 +94,19 @@ class OptionService extends Service {
parent_id
:
v
.
parent_id
,
name
:
v
.
name
,
selected_icon
:
v
.
selected_icon
,
unselected_icon
:
v
.
unselected_icon
,
sort
:
v
.
sort
,
});
}
const
ret
=
{
list
:
results
,
};
return
ret
;
}
}
module
.
exports
=
OptionService
;
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