diff --git a/business/jxstore/cms/job.go b/business/jxstore/cms/job.go index beed5bb73..3796ef04b 100644 --- a/business/jxstore/cms/job.go +++ b/business/jxstore/cms/job.go @@ -116,6 +116,9 @@ func PublishJob(ctx *jxcontext.Context, jobExt *model.JobExt) (errCode string, e if job.FinishedAt.Sub(time.Now()) <= 0 { return errCode, fmt.Errorf("任务截止日期必须大于今天!") } + if job2, _ := dao.GetJobWithTitle(db, job.Title); job2 != nil { + return errCode, fmt.Errorf("任务标题重复,请重新输入!") + } if job.JobCityCode != model.JobCountrywideCode { _, _, job.JobCityCode, err = getAddressInfoFromCoord(db, job.JobLng, job.JobLat) } diff --git a/business/jxstore/cms/order.go b/business/jxstore/cms/order.go index 2ec468a20..dc0694604 100644 --- a/business/jxstore/cms/order.go +++ b/business/jxstore/cms/order.go @@ -158,3 +158,24 @@ func GetPayStatistics(ctx *jxcontext.Context, userID string, pop int, cityCodes ) return dao.GetPayStatistics(db, userID, pop, cityCodes, mobile, utils.Str2Time(fromTime), utils.Str2Time(toTime), consumeTypes) } + +func GetManageStatisticsImg(ctx *jxcontext.Context, cityCodes []int, fromTime, toTime string, jobIDs []int) (getManageStatistics []*dao.GetManageStatisticsResult, err error) { + var ( + db = dao.GetDB() + fromTimeT = utils.Str2Time(fromTime) + toTimeT = utils.Str2Time(toTime) + ) + for i := 1; i < utils.Float64TwoInt(toTimeT.Sub(fromTimeT).Hours()/24); i++ { + if getManageStatisticsResult, err := dao.GetManageStatistics(db, cityCodes, fromTimeT.AddDate(0, 0, i), jobIDs); err == nil { + getManageStatistics = append(getManageStatistics, getManageStatisticsResult) + } + } + return getManageStatistics, err +} + +func GetManageStatisticsJob(ctx *jxcontext.Context, cityCodes []int, fromTime, toTime string, jobIDs []int, offset, pageSize int) (paged *model.PagedInfo, err error) { + var ( + db = dao.GetDB() + ) + return dao.GetManageStatisticsJob(db, cityCodes, utils.Str2Time(fromTime), utils.Str2Time(toTime), jobIDs, offset, pageSize) +} diff --git a/business/model/dao/dao_job.go b/business/model/dao/dao_job.go index 3a65a86d4..c6bdd09f1 100644 --- a/business/model/dao/dao_job.go +++ b/business/model/dao/dao_job.go @@ -174,6 +174,15 @@ func GetJob(db *DaoDB, userIDs []string, categoryIDs, statuss, types []int, from return job, err } +func GetJobWithTitle(db *DaoDB, title string) (job *model.Job, err error) { + sql := ` + SELECT * FROM job WHERE title = ? AND deleted_at = ? AND status = ? + ` + sqlParams := []interface{}{title, utils.DefaultTimeValue, model.JobStatusDoing} + err = GetRow(db, &job, sql, sqlParams) + return job, err +} + func GetJobsNoPage(db *DaoDB, userIDs []string, categoryIDs, statuss, types []int, fromTime, toTime time.Time, span int, includeStep bool) (jobs []*GetJobsResult, err error) { sql := ` SELECT a.*, b.name diff --git a/business/model/dao/dao_order.go b/business/model/dao/dao_order.go index c3b12fce5..27cab3225 100644 --- a/business/model/dao/dao_order.go +++ b/business/model/dao/dao_order.go @@ -215,8 +215,9 @@ func getFromSql(orderType, status int, alies string, userID string, pop int, cit } } sql += ` - WHERE 1 = 1 + WHERE a.status = ? AND a.deleted_at = ? ` + sqlParams = append(sqlParams, model.UserStatusNormal, utils.DefaultTimeValue) if userID != "" { if pop == 1 { sql += " AND a.pop_user = ?" @@ -337,3 +338,163 @@ func GetPayStatistics(db *DaoDB, userID string, pop int, cityCodes []int, mobile getPayStatisticsResult.TotalIncome = getPayStatisticsResult.MemberIncome + getPayStatisticsResult.CashIncome return getPayStatisticsResult, err } + +type GetManageStatisticsResult struct { + Date time.Time `json:"date"` //日期 + BrowseCount int `json:"browseCount"` //点击次数 + AcceptCount int `json:"acceptCount"` //接受任务数 + FinishCount int `json:"finishCount"` //完成任务数 + CancelCount int `json:"cancelCount"` //取消任务数 + TotalCash int `json:"totalCash"` //返现总额 + InversionRate float64 `json:"inversionRate"` //转化率 +} + +func getFromSqlManage(status int, alies string, cityCodes []int, jobTime, endTime time.Time, jobIDs []int) (sql string, sqlParams []interface{}) { + sql += ` + (SELECT COUNT(b.id) count, + FROM job a + JOIN job_order b ON a.id = b.job_id + WHERE a.deleted_at = ? + ` + sqlParams = append(sqlParams, utils.DefaultTimeValue) + if status != 0 { + sql += " AND b.status = ?" + sqlParams = append(sqlParams, status) + } + if jobTime != utils.ZeroTimeValue { + sql += " AND a.created_at > ?" + sqlParams = append(sqlParams, jobTime) + } + if endTime != utils.ZeroTimeValue { + sql += " AND a.created_at < ?" + sqlParams = append(sqlParams, endTime) + } + if len(cityCodes) > 0 { + sql += ` AND a.job_city_code IN ` + GenQuestionMarks(len(cityCodes)) + `)` + sqlParams = append(sqlParams, cityCodes) + } + if len(jobIDs) > 0 { + sql += ` AND a.id IN ` + GenQuestionMarks(len(jobIDs)) + `)` + sqlParams = append(sqlParams, jobIDs) + } + sql += ") " + alies + return sql, sqlParams +} + +func getWhereSqlManage(cityCodes []int, jobTime, endTime time.Time, jobIDs []int) (sql string, sqlParams []interface{}) { + if jobTime != utils.ZeroTimeValue { + sql += " AND a.created_at > ?" + sqlParams = append(sqlParams, jobTime) + } + if endTime != utils.ZeroTimeValue { + sql += " AND a.created_at < ?" + sqlParams = append(sqlParams, endTime) + } + if len(cityCodes) > 0 { + sql += ` AND a.job_city_code IN ` + GenQuestionMarks(len(cityCodes)) + `)` + sqlParams = append(sqlParams, cityCodes) + } + if len(jobIDs) > 0 { + sql += ` AND a.id IN ` + GenQuestionMarks(len(jobIDs)) + `)` + sqlParams = append(sqlParams, jobIDs) + } + return sql, sqlParams +} + +func GetManageStatistics(db *DaoDB, cityCodes []int, jobTime time.Time, jobIDs []int) (getManageStatisticsResult *GetManageStatisticsResult, err error) { + endTime := jobTime.AddDate(0, 0, 1) + sqlParams := []interface{}{} + sql := ` + SELECT t1.count acceptCount, t2.count finish_count, t3.count cancel_count, t4.browse_count, t5.total_cash + FROM + ` + rSQL1, rSQLparams1 := getFromSqlManage(model.JobOrderStatusAccept, "t1", cityCodes, jobTime, endTime, jobIDs) + sql += rSQL1 + "," + sqlParams = append(sqlParams, rSQLparams1...) + rSQL2, rSQLparams2 := getFromSqlManage(model.JobOrderStatusFinish, "t2", cityCodes, jobTime, endTime, jobIDs) + sql += rSQL2 + "," + sqlParams = append(sqlParams, rSQLparams2...) + rSQL3, rSQLparams3 := getFromSqlManage(model.JobOrderStatusCancel, "t3", cityCodes, jobTime, endTime, jobIDs) + sql += rSQL3 + "," + sqlParams = append(sqlParams, rSQLparams3...) + sql += ` + (SELECT SUM(a.browse_count) browse_count + FROM job a + JOIN job_order b ON a.id = b.job_id + WHERE a.deleted_at = ? + ` + sqlParams = append(sqlParams, utils.DefaultTimeValue) + rSQL4, rSQLparams4 := getWhereSqlManage(cityCodes, jobTime, endTime, jobIDs) + sql += rSQL4 + sqlParams = append(sqlParams, rSQLparams4...) + sql += ` + ) t4 + ` + sql += ` + (SELECT COUNT(b.id) * a.avg_price total_cash + FROM job a + JOIN job_order b ON a.id = b.job_id + WHERE a.deleted_at = ? AND b.status = ? + ` + sqlParams = append(sqlParams, utils.DefaultTimeValue, model.JobOrderStatusFinish) + rSQL5, rSQLparams5 := getWhereSqlManage(cityCodes, jobTime, endTime, jobIDs) + sql += rSQL5 + sqlParams = append(sqlParams, rSQLparams5...) + sql += ` + ) t5 + ` + err = GetRow(db, &getManageStatisticsResult, sql, sqlParams) + getManageStatisticsResult.Date = jobTime + getManageStatisticsResult.InversionRate = float64(getManageStatisticsResult.FinishCount) / float64(getManageStatisticsResult.BrowseCount) + return getManageStatisticsResult, err +} + +type GetManageStatisticsJobResult struct { + BrowseCount int `json:"browseCount"` //点击次数 + AcceptCount int `json:"acceptCount"` //接受任务数 + FinishCount int `json:"finishCount"` //完成任务数 + CancelCount int `json:"cancelCount"` //取消任务数 + TotalCash int `json:"totalCash"` //返现总额 + InversionRate float64 `json:"inversionRate"` //转化率 + Title string `json:"title"` //任务标题 +} + +func GetManageStatisticsJob(db *DaoDB, cityCodes []int, fromTime, toTime time.Time, jobIDs []int, offset, pageSize int) (pageInfo *model.PagedInfo, err error) { + var ( + sqlParams = []interface{}{} + getManageStatisticsJobResult []*GetManageStatisticsJobResult + ) + sql := ` + SELECT t1.count acceptCount, t2.count finish_count, t3.count cancel_count, a.browse_count, a.title, a.browse_count / t2.count inversion_rate, t4.total_cash + FROM job a + JOIN (SELECT job_id, COUNT(*) count FROM job_order WHERE status = ? GROUP BY 1) t1 ON t1.job_id = a.id + JOIN (SELECT job_id, COUNT(*) count FROM job_order WHERE status = ? GROUP BY 1) t2 ON t2.job_id = a.id + JOIN (SELECT job_id, COUNT(*) count FROM job_order WHERE status = ? GROUP BY 1) t3 ON t3.job_id = a.id + ` + sql += ` + JOIN (SELECT COUNT(b.id) * a.avg_price total_cash, a.id + FROM job a + JOIN job_order b ON a.id = b.job_id AND b.status = ? + GROUP BY 2) t4 ON t4.id = a.id + ` + sqlParams = append(sqlParams, model.JobOrderStatusAccept, model.JobOrderStatusFinish, model.JobOrderStatusCancel) + sqlParams = append(sqlParams, utils.DefaultTimeValue, model.JobOrderStatusFinish) + sql += " WHERE a.deleted_at = ?" + sqlParams = append(sqlParams, utils.DefaultTimeValue) + rSQL, rSQLparams := getWhereSqlManage(cityCodes, fromTime, toTime, jobIDs) + sql += rSQL + sqlParams = append(sqlParams, rSQLparams...) + sql += " LIMIT ? OFFSET ?" + pageSize = jxutils.FormalizePageSize(pageSize) + sqlParams = append(sqlParams, pageSize, offset) + Begin(db) + defer Commit(db) + err = GetRows(db, &getManageStatisticsJobResult, sql, sqlParams) + if err == nil { + pageInfo = &model.PagedInfo{ + Data: getManageStatisticsJobResult, + TotalCount: GetLastTotalRowCount(db), + } + } + return pageInfo, err +} diff --git a/controllers/order_controller.go b/controllers/order_controller.go index 04ad757c2..3c8bc4510 100644 --- a/controllers/order_controller.go +++ b/controllers/order_controller.go @@ -125,3 +125,45 @@ func (c *OrderController) GetPayStatistics() { return retVal, "", err }) } + +// @Title 经营分析图表 +// @Description 经营分析图表 +// @Param token header string true "认证token" +// @Param cityCodes query string false "城市id列表" +// @Param fromTime query string false "开始时间" +// @Param toTime query string false "结束时间" +// @Param jobIDs query string false "任务IDs" +// @Success 200 {object} controllers.CallResult +// @Failure 200 {object} controllers.CallResult +// @router /GetManageStatisticsImg [get] +func (c *OrderController) GetManageStatisticsImg() { + c.callGetManageStatisticsImg(func(params *tOrderGetManageStatisticsImgParams) (retVal interface{}, errCode string, err error) { + var cityCodes, jobIDs []int + if err = jxutils.Strings2Objs(params.CityCodes, &cityCodes, params.JobIDs, &jobIDs); err == nil { + retVal, err = cms.GetManageStatisticsImg(params.Ctx, cityCodes, params.FromTime, params.ToTime, jobIDs) + } + return retVal, "", err + }) +} + +// @Title 经营分析任务列表 +// @Description 经营分析任务列表 +// @Param token header string true "认证token" +// @Param cityCodes query string false "城市id列表" +// @Param fromTime query string false "开始时间" +// @Param toTime query string false "结束时间" +// @Param jobIDs query string false "任务IDs" +// @Param offset query int false "门店列表起始序号(以0开始,缺省为0)" +// @Param pageSize query int false "门店列表页大小(缺省为50,-1表示全部)" +// @Success 200 {object} controllers.CallResult +// @Failure 200 {object} controllers.CallResult +// @router /GetManageStatisticsJob [get] +func (c *OrderController) GetManageStatisticsJob() { + c.callGetManageStatisticsJob(func(params *tOrderGetManageStatisticsJobParams) (retVal interface{}, errCode string, err error) { + var cityCodes, jobIDs []int + if err = jxutils.Strings2Objs(params.CityCodes, &cityCodes, params.JobIDs, &jobIDs); err == nil { + retVal, err = cms.GetManageStatisticsJob(params.Ctx, cityCodes, params.FromTime, params.ToTime, jobIDs, params.Offset, params.PageSize) + } + return retVal, "", err + }) +} diff --git a/routers/commentsRouter_controllers.go b/routers/commentsRouter_controllers.go index 9e58d1deb..dd1f8cf79 100644 --- a/routers/commentsRouter_controllers.go +++ b/routers/commentsRouter_controllers.go @@ -628,6 +628,24 @@ func init() { Filters: nil, Params: nil}) + beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:OrderController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:OrderController"], + beego.ControllerComments{ + Method: "GetManageStatisticsImg", + Router: `/GetManageStatisticsImg`, + AllowHTTPMethods: []string{"get"}, + MethodParams: param.Make(), + Filters: nil, + Params: nil}) + + beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:OrderController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:OrderController"], + beego.ControllerComments{ + Method: "GetManageStatisticsJob", + Router: `/GetManageStatisticsJob`, + AllowHTTPMethods: []string{"get"}, + MethodParams: param.Make(), + Filters: nil, + Params: nil}) + beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:OrderController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:OrderController"], beego.ControllerComments{ Method: "GetOrders",