Commit b91309bd authored by 任国军's avatar 任国军

course add banner/serach

parent 317af482
Pipeline #16366 passed with stage
in 10 seconds
...@@ -10,10 +10,10 @@ class InstitutionSubController extends Controller { ...@@ -10,10 +10,10 @@ class InstitutionSubController extends Controller {
async institutionList() { async institutionList() {
const { ctx } = this; const { ctx } = this;
const input_params = ctx.request.query; const inputParams = ctx.request.query;
const results = await ctx.service.course.institutionSub.getInstitutions(input_params); const ret = await ctx.service.course.institutionSub.getInstitutions(inputParams);
ctx.success({ results }); ctx.success(ret);
} }
/** /**
...@@ -22,10 +22,10 @@ class InstitutionSubController extends Controller { ...@@ -22,10 +22,10 @@ class InstitutionSubController extends Controller {
async institutionInfo() { async institutionInfo() {
const { ctx } = this; const { ctx } = this;
let input_params = ctx.params; let inputParams = ctx.params;
const query = ctx.query; const query = ctx.query;
input_params = Object.assign(input_params, query); inputParams = Object.assign(inputParams, query);
const result = await ctx.service.course.institutionSub.getInstitution(input_params); const result = await ctx.service.course.institutionSub.getInstitution(inputParams);
ctx.success({ result }); ctx.success({ result });
} }
...@@ -36,8 +36,8 @@ class InstitutionSubController extends Controller { ...@@ -36,8 +36,8 @@ class InstitutionSubController extends Controller {
async classList() { async classList() {
const { ctx } = this; const { ctx } = this;
const input_params = ctx.request.body; const inputParams = ctx.request.body;
const results = await ctx.service.course.institutionSub.getClasses(input_params); const results = await ctx.service.course.institutionSub.getClasses(inputParams);
ctx.success({ results }); ctx.success({ results });
} }
...@@ -63,8 +63,8 @@ class InstitutionSubController extends Controller { ...@@ -63,8 +63,8 @@ class InstitutionSubController extends Controller {
async teacherList() { async teacherList() {
const { ctx } = this; const { ctx } = this;
const input_params = ctx.request.body; const inputParams = ctx.request.body;
const ret = await ctx.service.course.institutionSub.getTeachers(input_params); const ret = await ctx.service.course.institutionSub.getTeachers(inputParams);
ctx.success(ret); ctx.success(ret);
} }
...@@ -93,7 +93,15 @@ class InstitutionSubController extends Controller { ...@@ -93,7 +93,15 @@ class InstitutionSubController extends Controller {
ctx.success(ret); ctx.success(ret);
} }
// 搜索
async search() {
const { ctx } = this;
const inputParams = ctx.request.query;
const ret = await ctx.service.course.institutionSub.search(inputParams);
ctx.success(ret);
}
} }
module.exports = InstitutionSubController; module.exports = InstitutionSubController;
'use strict';
const Controller = require('egg').Controller;
class OptionSubController extends Controller {
/**
* 筛选项
*/
async getOptions() {
const { ctx } = this;
const results = await ctx.service.course.optionSub.getOptions();
ctx.success({ results });
}
async getBanners() {
const { ctx, service } = this;
const inputParams = ctx.request.query;
if (ctx.isEmpty(inputParams.alias)) {
ctx.failed('alias is empty');
}
const ret = await service.course.optionSub.getBanners(inputParams.alias);
ctx.success(ret);
}
}
module.exports = OptionSubController;
'use strict';
const moment = require('moment');
module.exports = app => {
const { STRING, INTEGER, DATE, ENUM } = app.Sequelize;
const CourseBanner = app.classModel.define('course_banner', {
id: {
type: INTEGER,
primaryKey: true,
autoIncrement: true,
},
type_id: INTEGER,
title: STRING,
url: STRING,
sort: INTEGER,
status: ENUM('offline', 'online'),
is_deleted: INTEGER,
created_time: {
type: DATE,
allowNull: true,
get() {
const date = this.getDataValue('created_time');
return date ? moment(date).format('YYYY-MM-DD HH:mm:ss') : undefined;
},
},
updated_time: {
type: DATE,
allowNull: true,
get() {
const date = this.getDataValue('updated_time');
return date ? moment(date).format('YYYY-MM-DD HH:mm:ss') : undefined;
},
},
}, {
timestamps: false,
tableName: 'course_banner',
});
return CourseBanner;
};
'use strict';
const moment = require('moment');
module.exports = app => {
const { STRING, INTEGER, DATE, ENUM } = app.Sequelize;
const CourseBannerType = app.classModel.define('course_banner_type', {
id: {
type: INTEGER,
primaryKey: true,
autoIncrement: true,
},
title: STRING,
alias: STRING,
status: ENUM('offline', 'online'),
is_deleted: INTEGER,
created_time: {
type: DATE,
allowNull: true,
get() {
const date = this.getDataValue('created_time');
return date ? moment(date).format('YYYY-MM-DD HH:mm:ss') : undefined;
},
},
updated_time: {
type: DATE,
allowNull: true,
get() {
const date = this.getDataValue('updated_time');
return date ? moment(date).format('YYYY-MM-DD HH:mm:ss') : undefined;
},
},
}, {
timestamps: false,
tableName: 'course_banner_type',
});
return CourseBannerType;
};
'use strict';
const moment = require('moment');
module.exports = app => {
const { STRING, INTEGER, DATE, ENUM } = app.Sequelize;
const CourseSearch = app.classModel.define('course_search', {
id: {
type: INTEGER,
primaryKey: true,
autoIncrement: true,
},
content: STRING,
count: INTEGER,
is_hot: INTEGER,
sort: INTEGER,
status: ENUM('offline', 'online'),
is_deleted: INTEGER,
created_time: {
type: DATE,
allowNull: true,
get() {
const date = this.getDataValue('created_time');
return date ? moment(date).format('YYYY-MM-DD HH:mm:ss') : undefined;
},
},
updated_time: {
type: DATE,
allowNull: true,
get() {
const date = this.getDataValue('updated_time');
return date ? moment(date).format('YYYY-MM-DD HH:mm:ss') : undefined;
},
},
}, {
timestamps: false,
tableName: 'course_search',
});
return CourseSearch;
};
...@@ -35,9 +35,10 @@ module.exports = app => { ...@@ -35,9 +35,10 @@ module.exports = app => {
// 版本二 // 版本二
router.get('third', '/sub/cats', 'course.institutionSub.getCats');// 分类 router.get('third', '/sub/cats', 'course.institutionSub.getCats');// 分类
router.get('third', '/sub/options', 'course.option.getOptions');// 筛选项 router.get('third', '/sub/options', 'course.optionSub.getOptions');// 筛选项
router.get('third', '/sub/banners', 'course.optionSub.getBanners');// banner
router.post('third', '/sub/address', miniAuth, 'course.location.getAddress');// 根据经纬度或ip获取地理位置信息 router.post('third', '/sub/address', miniAuth, 'course.location.getAddress');// 根据经纬度或ip获取地理位置信息
router.post('third', '/sub/institutions', miniAuth, 'course.institutionSub.institutionList');// 机构列表 router.get('third', '/sub/search', miniAuth, 'course.institutionSub.search');// 搜搜
router.get('third', '/sub/institutions', miniAuth, 'course.institutionSub.institutionList');// 机构列表 router.get('third', '/sub/institutions', miniAuth, 'course.institutionSub.institutionList');// 机构列表
router.get('third', '/sub/institution/:institution_id', miniAuth, 'course.institutionSub.institutionInfo');// 机构详情 router.get('third', '/sub/institution/:institution_id', miniAuth, 'course.institutionSub.institutionInfo');// 机构详情
router.post('third', '/sub/classes', miniAuth, 'course.institution.classList');// 课程列表 router.post('third', '/sub/classes', miniAuth, 'course.institution.classList');// 课程列表
......
...@@ -89,7 +89,8 @@ class InstitutionSubService extends Service { ...@@ -89,7 +89,8 @@ class InstitutionSubService extends Service {
const teachers = await ctx.classModel.CourseTeacher.findAll({ where: { institution_id, status: 'online', is_deleted: 0 } }); const teachers = await ctx.classModel.CourseTeacher.findAll({ where: { institution_id, status: 'online', is_deleted: 0 } });
// 课程 // 课程
const classes = await ctx.classModel.CourseClass.findAll({ where: { institution_id, status: 'online', is_deleted: 0 } }); let classes = await ctx.classModel.CourseClass.findAll({ where: { institution_id, status: 'online', is_deleted: 0 }, row: true });
classes = R.pluck('dataValues', classes);
// 处理课程封面图 // 处理课程封面图
const classHandle = []; const classHandle = [];
if (classes.length > 0) { if (classes.length > 0) {
...@@ -165,9 +166,9 @@ class InstitutionSubService extends Service { ...@@ -165,9 +166,9 @@ class InstitutionSubService extends Service {
// 机构列表 // 机构列表
async getInstitutions(input) { async getInstitutions(input) {
const { ctx, service } = this; const { ctx } = this;
const userUUID = ctx.userUUID; const userUUID = ctx.userUUID;
const { cat_id, age, distance, address, page, limit } = input; const { cat_id, age, address } = input;
const lat = ctx.isEmpty(input.lat) ? 0 : input.lat; const lat = ctx.isEmpty(input.lat) ? 0 : input.lat;
const lng = ctx.isEmpty(input.lng) ? 0 : input.lng; const lng = ctx.isEmpty(input.lng) ? 0 : input.lng;
...@@ -176,7 +177,6 @@ class InstitutionSubService extends Service { ...@@ -176,7 +177,6 @@ class InstitutionSubService extends Service {
ctx.classModel.CourseLogUserGps.created({ user_uuid: userUUID, address, lat, lng, created_time: moment().format('YYYY-MM-DD HH:mm:ss') }); ctx.classModel.CourseLogUserGps.created({ user_uuid: userUUID, address, lat, lng, created_time: moment().format('YYYY-MM-DD HH:mm:ss') });
} }
let institutionIds = [];
let institutionList = []; let institutionList = [];
let institutionCats = []; let institutionCats = [];
const filter = { where: { status: 'online', is_deleted: 0 } }; const filter = { where: { status: 'online', is_deleted: 0 } };
...@@ -198,7 +198,24 @@ class InstitutionSubService extends Service { ...@@ -198,7 +198,24 @@ class InstitutionSubService extends Service {
institutionList = await ctx.classModel.CourseInstitution.findAll(filter); institutionList = await ctx.classModel.CourseInstitution.findAll(filter);
institutionList = R.pluck('dataValues', institutionList); institutionList = R.pluck('dataValues', institutionList);
institutionIds = R.pluck('id', 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.CourseArea.findAll({ where: { status: 'online', is_deleted: 0, institution_id: { $in: institutionIds } } }); const areaList = await ctx.classModel.CourseArea.findAll({ where: { status: 'online', is_deleted: 0, institution_id: { $in: institutionIds } } });
...@@ -294,6 +311,7 @@ class InstitutionSubService extends Service { ...@@ -294,6 +311,7 @@ class InstitutionSubService extends Service {
institutionList[i].images = institutionImages; institutionList[i].images = institutionImages;
institutionList[i].distance = (institutionList[i].distance / 1000).toFixed(1); institutionList[i].distance = (institutionList[i].distance / 1000).toFixed(1);
institutionList[i].phone = institutionList[i].area.length > 0 ? institutionList[i].area[0].phone : '';
// 是否已收藏 // 是否已收藏
institutionList[i].is_collected = userInstitutionIds.includes(institutionList[i].id) ? 1 : 0; institutionList[i].is_collected = userInstitutionIds.includes(institutionList[i].id) ? 1 : 0;
...@@ -302,6 +320,67 @@ class InstitutionSubService extends Service { ...@@ -302,6 +320,67 @@ class InstitutionSubService extends Service {
return ret; return ret;
} }
// 搜索
async search(input) {
const { ctx } = this;
const { cat_id, age, search } = input;
// 保存搜索记录
if (search) {
const searchInfo = await ctx.classModel.CourseSearch.findOne({ where: { content: search, is_deleted: 0 } });
if (searchInfo) {
await ctx.classModel.CourseSearch.update({ count: searchInfo.count + 1 }, { where: { id: searchInfo.id } });
} else {
ctx.classModel.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') });
}
}
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 };
// 年龄筛选
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.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.CourseInstitutionToCat.findAll({ where: { status: 'online', is_deleted: 0, cat_id: { $in: catIds } } });
institutionIds = R.pluck('institution_id', institutionCats);
}
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.CourseInstitution.findAll(institutionFilter);
const ids = R.pluck('id', institutionList);
// 课程搜索
const classList = await ctx.classModel.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.CourseInstitution.findAll(filter);
institutionList = institutionList.concat(classInstitutionList);
}
institutionList = R.pluck('dataValues', institutionList);
const ret = await this.formatInstitutionList(institutionList, input);
return ret;
}
} }
module.exports = InstitutionSubService; module.exports = InstitutionSubService;
...@@ -75,6 +75,21 @@ class OptionService extends Service { ...@@ -75,6 +75,21 @@ class OptionService extends Service {
return ret; return ret;
} }
async getBanners(alias) {
const { ctx } = this;
const bannerType = await ctx.classModel.CourseBannerType.findOne({ where: { alias, status: 'online', is_deleted: 0 }, row: true });
if (ctx.isEmpty(bannerType)) {
ctx.failed('数据不存在');
}
const banners = await ctx.classModel.CourseBanner.findAll({ where: { type_id: bannerType.id, status: 'online', is_deleted: 0 }, order: [[ 'sort', 'asc' ]], row: true });
const ret = {
results: banners,
count: banners.length,
};
return ret;
}
} }
module.exports = OptionService; module.exports = OptionService;
'use strict';
const Service = require('egg').Service;
const AGE_CATS = [
{ id: -2, name: '全部', value: 0 },
{ id: -3, name: '3岁以下', value: 3 },
{ id: -4, name: '4岁', value: 4 },
{ id: -5, name: '5岁', value: 5 },
{ id: -6, name: '6岁', value: 6 },
{ id: -7, name: '7岁', value: 7 },
{ id: -8, name: '8岁', value: 8 },
{ id: -9, name: '9岁', value: 9 },
{ id: -10, name: '10岁', value: 10 },
{ id: -11, name: '11岁', value: 11 },
{ id: -12, name: '12岁', value: 12 },
{ id: -13, name: '12岁以上', value: 13 },
];
const INSTITUTION_TYPE = [
{ id: -14, name: '全部', value: '' },
{ id: -15, name: '品牌', value: '品牌' },
];
const DISTANCES = [
{ id: -16, name: '全部', value: 0 },
{ id: -17, name: '500米以内', value: 500 },
{ id: -18, name: '1公里以内', value: 1000 },
{ id: -19, name: '2公里以内', value: 2000 },
{ id: -20, name: '3公里以内', value: 3000 },
{ id: -21, name: '5公里以内', value: 5000 },
];
class OptionSubService extends Service {
async getOptions() {
const { service } = this;
const cats = await service.course.institutionSub.getCats();
const options = {
cats,
ages: AGE_CATS,
institutions: INSTITUTION_TYPE,
distances: DISTANCES,
};
return options;
}
async getBanners(alias) {
const { ctx } = this;
const bannerType = await ctx.classModel.CourseBannerType.findOne({ where: { alias, status: 'online', is_deleted: 0 }, row: true });
if (ctx.isEmpty(bannerType)) {
ctx.failed('数据不存在');
}
const banners = await ctx.classModel.CourseBanner.findAll({ where: { type_id: bannerType.id, status: 'online', is_deleted: 0 }, order: [[ 'sort', 'asc' ]], row: true });
const ret = {
results: banners,
count: banners.length,
};
return ret;
}
}
module.exports = OptionSubService;
...@@ -18,7 +18,7 @@ module.exports = appInfo => { ...@@ -18,7 +18,7 @@ module.exports = appInfo => {
}; };
config.middleware = [ 'errorHandler', 'deviceLogin', 'deviceInit', 'responseSet' ]; config.middleware = [ 'errorHandler', 'deviceLogin', 'deviceInit', 'responseSet' ];
config.middleware = []; // config.middleware = [];
exports.multipart = { exports.multipart = {
// 不用steam用file // 不用steam用file
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment