|
@@ -1,7 +1,12 @@
|
|
|
package com.cloudcross.ssp.web.advertiser.main.ad.target;
|
|
|
|
|
|
import java.io.UnsupportedEncodingException;
|
|
|
+import java.text.ParseException;
|
|
|
+import java.text.SimpleDateFormat;
|
|
|
import java.util.ArrayList;
|
|
|
+import java.util.Arrays;
|
|
|
+import java.util.Collections;
|
|
|
+import java.util.Date;
|
|
|
import java.util.HashMap;
|
|
|
import java.util.LinkedHashMap;
|
|
|
import java.util.List;
|
|
@@ -9,18 +14,32 @@ import java.util.Map;
|
|
|
|
|
|
import javax.servlet.http.HttpServletRequest;
|
|
|
|
|
|
+import org.apache.commons.lang.StringUtils;
|
|
|
+import org.apache.ibatis.logging.LogFactory;
|
|
|
+import org.apache.log4j.Logger;
|
|
|
+import org.json.JSONArray;
|
|
|
+import org.json.JSONException;
|
|
|
+import org.json.JSONObject;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.stereotype.Controller;
|
|
|
import org.springframework.ui.Model;
|
|
|
+import org.springframework.web.bind.annotation.ModelAttribute;
|
|
|
import org.springframework.web.bind.annotation.RequestMapping;
|
|
|
import org.springframework.web.bind.annotation.RequestParam;
|
|
|
import org.springframework.web.bind.annotation.ResponseBody;
|
|
|
|
|
|
import com.cloudcross.ssp.base.web.SimpleController;
|
|
|
+import com.cloudcross.ssp.common.utils.AdvertiserSortByDate;
|
|
|
+import com.cloudcross.ssp.common.utils.Common;
|
|
|
import com.cloudcross.ssp.common.utils.Pager;
|
|
|
import com.cloudcross.ssp.common.utils.Pager1;
|
|
|
import com.cloudcross.ssp.model.Account;
|
|
|
+import com.cloudcross.ssp.model.AdGroup;
|
|
|
+import com.cloudcross.ssp.model.AdGroupPlace;
|
|
|
+import com.cloudcross.ssp.model.DayParting;
|
|
|
+import com.cloudcross.ssp.model.Direct;
|
|
|
import com.cloudcross.ssp.model.Location;
|
|
|
+import com.cloudcross.ssp.model.Log;
|
|
|
import com.cloudcross.ssp.model.Operator;
|
|
|
import com.cloudcross.ssp.model.Place;
|
|
|
import com.cloudcross.ssp.model.PlaceClassInformation;
|
|
@@ -28,8 +47,12 @@ import com.cloudcross.ssp.model.PlaceOperator;
|
|
|
import com.cloudcross.ssp.model.Wifi;
|
|
|
import com.cloudcross.ssp.model.Zone;
|
|
|
import com.cloudcross.ssp.model.pojo.CampaignPojo;
|
|
|
+import com.cloudcross.ssp.service.IAdGroupPlaceService;
|
|
|
+import com.cloudcross.ssp.service.IAdGroupService;
|
|
|
import com.cloudcross.ssp.service.ICampaignService;
|
|
|
+import com.cloudcross.ssp.service.IDirectService;
|
|
|
import com.cloudcross.ssp.service.ILocationService;
|
|
|
+import com.cloudcross.ssp.service.ILogService;
|
|
|
import com.cloudcross.ssp.service.IOperatorService;
|
|
|
import com.cloudcross.ssp.service.IPlaceClassInformationService;
|
|
|
import com.cloudcross.ssp.service.IPlaceOperatorService;
|
|
@@ -40,7 +63,7 @@ import com.cloudcross.ssp.service.IZoneService;
|
|
|
@Controller
|
|
|
@RequestMapping("/advertiser/main/ad/target/ad-group-alloperator")
|
|
|
public class AdGroupAlloperatorController extends SimpleController{
|
|
|
-
|
|
|
+ private static final Logger LOG = Logger.getLogger(AdGroupAlloperatorController.class);
|
|
|
@Autowired
|
|
|
private ICampaignService campaignService;
|
|
|
@Autowired
|
|
@@ -57,6 +80,12 @@ public class AdGroupAlloperatorController extends SimpleController{
|
|
|
private IWifiService wifiService;
|
|
|
@Autowired
|
|
|
private IZoneService zoneService;
|
|
|
+ @Autowired
|
|
|
+ private ILogService logService;
|
|
|
+ @Autowired
|
|
|
+ private IAdGroupService adGroupService;
|
|
|
+ @Autowired
|
|
|
+ private IDirectService directService;
|
|
|
|
|
|
@RequestMapping("create")
|
|
|
public String create(Model model, @RequestParam Long campaignId) {
|
|
@@ -87,7 +116,7 @@ public class AdGroupAlloperatorController extends SimpleController{
|
|
|
*/
|
|
|
@RequestMapping("chooseZone")
|
|
|
@ResponseBody
|
|
|
- public List<Zone> queryZoneByCondition(Model model,String operatorId,String position){
|
|
|
+ public List<Zone> queryZoneByCondition(String operatorId,String position){
|
|
|
Map<String,Object> condition = new HashMap<String,Object>();
|
|
|
//处理operatorID
|
|
|
if(operatorId != null && !"".equals(operatorId)){
|
|
@@ -201,21 +230,20 @@ public class AdGroupAlloperatorController extends SimpleController{
|
|
|
Map<String,Object> condition = new HashMap<String,Object>();
|
|
|
if( null != cnCity && !"".equals(cnCity)){
|
|
|
condition.put("cnCity", cnCity);
|
|
|
+ }else{
|
|
|
+ cnCity = "市";
|
|
|
}
|
|
|
if( null != cn && !"".equals(cn)){
|
|
|
condition.put("cn", cn);
|
|
|
+ }else{
|
|
|
+ cn = "省";
|
|
|
}
|
|
|
|
|
|
Integer count = this.wifiService.queryWifiCount(condition);
|
|
|
Pager pager = new Pager();
|
|
|
pager.setPage(page);
|
|
|
pager.setTotalRow(count);
|
|
|
- if(cn == null || "".equals(cn)){
|
|
|
- cn = "省";
|
|
|
- }
|
|
|
- if(cnCity == null || "".equals(cnCity)){
|
|
|
- cnCity = "市";
|
|
|
- }
|
|
|
+
|
|
|
condition.put("pager", pager);
|
|
|
List<Wifi> list = this.wifiService.queryWifi(condition);
|
|
|
model.addAttribute("pager", pager);
|
|
@@ -265,6 +293,7 @@ public class AdGroupAlloperatorController extends SimpleController{
|
|
|
return map;
|
|
|
}
|
|
|
|
|
|
+
|
|
|
/**
|
|
|
* 保存方法
|
|
|
* @param request
|
|
@@ -272,7 +301,239 @@ public class AdGroupAlloperatorController extends SimpleController{
|
|
|
* @return
|
|
|
*/
|
|
|
@RequestMapping("/save")
|
|
|
- public String save(HttpServletRequest request, Model model){
|
|
|
+ public String save(HttpServletRequest request, Model model,@ModelAttribute("form") AdGroup adGroup
|
|
|
+ ,@RequestParam String areas,@RequestParam Map<String, Object> paramMap) {
|
|
|
+ adGroup.setStatus(0);
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 在这里做时间定向的功能处理
|
|
|
+ */
|
|
|
+ //将前台转换的排期数据转换成需要存储的数据--选择的时间段,以及未选择时间段按照策略的曝光率
|
|
|
+ SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
|
|
|
+
|
|
|
+ //把投放日期进行转换
|
|
|
+ String activeTime = (String) paramMap.get("activeTime");
|
|
|
+ String[] tmpDate = activeTime.split("to");
|
|
|
+ String startDateFront = tmpDate[0].trim();
|
|
|
+ String endDateFront = tmpDate[1].trim();
|
|
|
+ try {
|
|
|
+ adGroup.setStartDate(sdf.parse(startDateFront));
|
|
|
+ } catch (ParseException e2) {
|
|
|
+ // TODO Auto-generated catch block
|
|
|
+ e2.printStackTrace();
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ adGroup.setEndDate(sdf.parse(endDateFront));
|
|
|
+ } catch (ParseException e2) {
|
|
|
+ // TODO Auto-generated catch block
|
|
|
+ e2.printStackTrace();
|
|
|
+ }
|
|
|
+
|
|
|
+ //先获得策略的投放周期
|
|
|
+ Date startDate = adGroup.getStartDate();
|
|
|
+ Date endDate = adGroup.getEndDate();
|
|
|
+ //获得前端传递过来的已选择时间段
|
|
|
+ String sdayParting = (String)paramMap.get("sdayParting");
|
|
|
+ //用来存储转换结果的JSONArray
|
|
|
+ JSONArray result = new JSONArray();
|
|
|
+ //用来存储传过来时间段信息集合
|
|
|
+ List<DayParting> dayList = new ArrayList<DayParting>();
|
|
|
+ //用来存储没选的时间段信息
|
|
|
+ List<DayParting> daySurplus = new ArrayList<DayParting>();
|
|
|
+ //默认24个时间点
|
|
|
+ String allHours = "0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23";
|
|
|
+
|
|
|
+ try {
|
|
|
+ //传过来已选择的时间JSONArray
|
|
|
+ JSONArray jsonArray = new JSONArray(sdayParting);
|
|
|
+ //当没选一个时间段时,默认从开始时间段到结束时间段都为默认曝光上限
|
|
|
+ if(jsonArray.length() == 0){
|
|
|
+ JSONObject object = new JSONObject();
|
|
|
+ object.put("startDate", sdf.format(startDate));
|
|
|
+ object.put("endDate", sdf.format(endDate));
|
|
|
+ object.put("dehours",allHours);
|
|
|
+ result.put(object);
|
|
|
+ }
|
|
|
+
|
|
|
+ for (int i = 0; i < jsonArray.length(); i++) {
|
|
|
+ JSONObject object = jsonArray.getJSONObject(i);
|
|
|
+ DayParting day = new DayParting();
|
|
|
+
|
|
|
+ //如果传过来的dehours是-1或空或者是空字符串,表示全选
|
|
|
+ if(null == object.get("dehours") || "-1".equals(String.valueOf(object.getString("dehours"))) ||
|
|
|
+ "".equals(String.valueOf(object.getString("dehours")))) {
|
|
|
+ day.setDehours(allHours);
|
|
|
+ } else {
|
|
|
+ day.setDehours(object.getString("dehours"));
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ day.setStartDate(sdf.parse(object.getString("startDate")));
|
|
|
+ day.setEndDate(sdf.parse(object.getString("endDate")));
|
|
|
+ } catch (ParseException e) {
|
|
|
+ // TODO Auto-generated catch block
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ dayList.add(day);
|
|
|
+ }
|
|
|
+
|
|
|
+ //按照开始时间的先后顺序给dayList进行排序,排序后,比较相邻的2个时间段,能够得出未选择的时间段
|
|
|
+ Collections.sort(dayList, new AdvertiserSortByDate());
|
|
|
+
|
|
|
+ for(int i = 0; i < dayList.size(); i++){
|
|
|
+ DayParting dayP = dayList.get(i);
|
|
|
+ JSONObject object = new JSONObject();
|
|
|
+ object.put("startDate", sdf.format(dayP.getStartDate()));
|
|
|
+ object.put("endDate", sdf.format(dayP.getEndDate()));
|
|
|
+ //将已选择的时间段放入result中
|
|
|
+ object.put("dehours",dayP.getDehours());
|
|
|
+ result.put(object);
|
|
|
+
|
|
|
+ //当只选择一个时间段时,无法对前后两段时间进行比较,需特殊处理
|
|
|
+ if(dayList.size() == 1){
|
|
|
+ //所选时间段在开始时间之后--在开始时间到所选时间段中间有空缺时间段
|
|
|
+ if(dayP.getStartDate().getTime() > startDate.getTime()){
|
|
|
+ DayParting dayS = new DayParting();
|
|
|
+ dayS.setStartDate(startDate);
|
|
|
+ //减一天
|
|
|
+ dayS.setEndDate(new Date(dayP.getStartDate().getTime() - 24*60*60*1000));
|
|
|
+ dayS.setDehours(allHours);
|
|
|
+ daySurplus.add(dayS);
|
|
|
+ }
|
|
|
+ //所选时间段在开始时间之前--在结束时间到所选时间段中间有空缺时间段
|
|
|
+ if(dayP.getEndDate().getTime() < endDate.getTime()){
|
|
|
+ DayParting dayS = new DayParting();
|
|
|
+ //加一天
|
|
|
+ dayS.setStartDate(new Date(dayP.getEndDate().getTime() + 24*60*60*1000));
|
|
|
+ dayS.setEndDate(endDate);
|
|
|
+ dayS.setDehours(allHours);
|
|
|
+ daySurplus.add(dayS);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ //排序后的第一条记录,与开始时间比较,得出在开始时间到第一条记录之间是否有空缺时间段
|
|
|
+ if(i==0){
|
|
|
+ //第一条记录的开始时间大于策略开始时间
|
|
|
+ if(dayP.getStartDate().getTime() > startDate.getTime()){
|
|
|
+ DayParting dayS = new DayParting();
|
|
|
+ dayS.setStartDate(startDate);
|
|
|
+ dayS.setEndDate(new Date(dayP.getStartDate().getTime() - 24*60*60*1000));
|
|
|
+ dayS.setDehours(allHours);
|
|
|
+ //添加第一条记录开始时间到策略开始时间的空缺段到daySurplus中
|
|
|
+ daySurplus.add(dayS);
|
|
|
+ //与后面的一条记录做比较,前一条记录的结束时间小于后一条记录的开始时间,中间有空缺时间段
|
|
|
+ DayParting nextDay = dayList.get(i + 1);
|
|
|
+ if(dayP.getEndDate().getTime() < nextDay.getStartDate().getTime() - 24*60*60*1000){
|
|
|
+ DayParting dayS2 = new DayParting();
|
|
|
+ dayS2.setStartDate(new Date(dayP.getEndDate().getTime() + 24*60*60*1000));
|
|
|
+ dayS2.setEndDate(new Date(nextDay.getStartDate().getTime() - 24*60*60*1000));
|
|
|
+ dayS2.setDehours(allHours);
|
|
|
+ daySurplus.add(dayS2);
|
|
|
+ }
|
|
|
+ }else{
|
|
|
+ //与后面的一条记录做比较,前一条记录的结束时间小于后一条记录的开始时间,中间有空缺时间段
|
|
|
+ DayParting nextDay = dayList.get(i + 1);
|
|
|
+ if(dayP.getEndDate().getTime() < nextDay.getStartDate().getTime() - 24*60*60*1000){
|
|
|
+ DayParting dayS = new DayParting();
|
|
|
+ dayS.setStartDate(new Date(dayP.getEndDate().getTime() + 24*60*60*1000));
|
|
|
+ dayS.setEndDate(new Date(nextDay.getStartDate().getTime() - 24*60*60*1000));
|
|
|
+ dayS.setDehours(allHours);
|
|
|
+ daySurplus.add(dayS);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }else if(i == dayList.size() - 1){
|
|
|
+ //最后一条记录的结束时间小于策略结束时间,中间有空缺时间段
|
|
|
+ if(dayP.getEndDate().getTime() < endDate.getTime()){
|
|
|
+ DayParting dayS = new DayParting();
|
|
|
+ dayS.setStartDate(new Date(dayP.getEndDate().getTime() + 24*60*60*1000));
|
|
|
+ dayS.setEndDate(endDate);
|
|
|
+ dayS.setDehours(allHours);
|
|
|
+ daySurplus.add(dayS);
|
|
|
+ }
|
|
|
+ } else{
|
|
|
+ DayParting nextDay = dayList.get(i + 1); //与后面的一条记录做比较,前一条记录的结束时间小于后一条记录的开始时间,中间有空缺时间段
|
|
|
+ if(dayP.getEndDate().getTime() < nextDay.getStartDate().getTime() - 24*60*60*1000){
|
|
|
+ DayParting dayS = new DayParting();
|
|
|
+ dayS.setStartDate(new Date(dayP.getEndDate().getTime() + 24*60*60*1000));
|
|
|
+ dayS.setEndDate(new Date(nextDay.getStartDate().getTime() - 24*60*60*1000));
|
|
|
+ dayS.setDehours(allHours);
|
|
|
+ daySurplus.add(dayS);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //将空缺时间段添加到result中
|
|
|
+ for(int i = 0; i < daySurplus.size(); i++){
|
|
|
+ DayParting dayP = daySurplus.get(i);
|
|
|
+ JSONObject object = new JSONObject();
|
|
|
+ object.put("startDate", sdf.format(dayP.getStartDate()));
|
|
|
+ object.put("endDate", sdf.format(dayP.getEndDate()));
|
|
|
+ object.put("dehours",dayP.getDehours());
|
|
|
+ result.put(object);
|
|
|
+ }
|
|
|
+
|
|
|
+ //将已处理的时间段存储起来
|
|
|
+ paramMap.put("dayParting", result.toString());
|
|
|
+ } catch (JSONException e) {
|
|
|
+ // TODO Auto-generated catch block
|
|
|
+ LOG.info("@@@@@@@@排期日期解析错误");
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ // 千次转换
|
|
|
+ if (adGroup.getMaxImpression() != null) {
|
|
|
+ adGroup.setMaxImpression(adGroup.getMaxImpression() * 1000);
|
|
|
+ }
|
|
|
+ if (adGroup.getDailyMaxImpression() != null) {
|
|
|
+ adGroup.setDailyMaxImpression(adGroup.getDailyMaxImpression() * 1000);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ if (adGroup.getId() == null) {
|
|
|
+ try {
|
|
|
+ if (getLoginUser().getOperatorId()!=0) {
|
|
|
+ adGroup.setOperatorId(getLoginUser().getOperatorId());
|
|
|
+ }else{
|
|
|
+ adGroup.setOperatorId(new Long(0));
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ // TODO: handle exception
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+
|
|
|
+ adGroupService.saveAllOperator(adGroup, paramMap);
|
|
|
+ /**
|
|
|
+ * 新增投放成功后同时会新增地域定向,时段定向,wifi定向以及下面的场景
|
|
|
+ * 所以这里的日志新增记录应该把这些都加进去
|
|
|
+ */
|
|
|
+ /**
|
|
|
+ * 先做投放的新增记录
|
|
|
+ */
|
|
|
+ Log log = new Log();
|
|
|
+ //对应模块
|
|
|
+ log.setModule("AdGroup");
|
|
|
+ //对应表名
|
|
|
+ log.setTableName("t_adgroup");
|
|
|
+ //增加对应的投放id
|
|
|
+ log.setRecordId(adGroup.getId());
|
|
|
+ //对应操作类型
|
|
|
+ log.setActionType("新增");
|
|
|
+ //对应的操作
|
|
|
+ String str = "新增一个投放为:"+adGroup.getAdGroupName();
|
|
|
+ /*String place = String.valueOf(paramMap.get("place"));
|
|
|
+ if(place != null && !"".equals(place)){
|
|
|
+ str = str + ";添加了场景为:"+place;
|
|
|
+ }*/
|
|
|
+ log.setAction(str);
|
|
|
+ //下面这几个字段目前后端数据没有得到。所以仅作测试用!
|
|
|
+ log.setActionTime("100");
|
|
|
+ log.setAccountId(new Long(getLoginUser().getId()));
|
|
|
+ log.setUserIp(Common.toIpAddr(request));
|
|
|
+ log.setAccountName(getLoginUser().getAccountName());
|
|
|
+ logService.add(log);
|
|
|
+ }
|
|
|
+
|
|
|
+ model.addAttribute("campaignId", adGroup.getCampaignId());
|
|
|
return OK;
|
|
|
}
|
|
|
|