1 需求如下:
4. P0-奇迹后台
1. 奇迹后台页面语言切换为英语时:
a) 游戏列表-游戏名称,调用其游戏运营后台上对应的游戏英文名
b) 游戏列表-【筛选控件】游戏分类名称,调用其游戏运营后台上对应的游戏分类英文名;
2. 游戏列表-用户留存中1日LTV指标删除
3. (英文版需要支持英文翻译)部分需计算的数据支持悬浮公式的说明,如下图所示,当鼠标落于需计算的数据时,出现悬浮公式。
包括以下页面中的数据:
a) 支付统计-支付成功率:支付成功率=支付成功次数/支付页启动次数
b) 游戏报表-用户活跃度:活跃度=活跃用户数/总用户数,次均游玩时长=游玩时长/启动次数
c) 游戏报表-商店转化率:下载转化率=游戏的下载次数/游戏详情展示次数,安装转化率=游戏的安装次数/游戏的下载次数
d) 游戏报表-成就:占比=成就达成次数/成就达成总次数
e) 游戏报表-排行榜:榜单提交次数/排行榜接受提交总次数
1 需要注意的是一个数据库leftjoin的使用:如下
dict_tbl_game表:
dict_tbl_game_category
dict_tbl_game表中有个category_id 与 dict_tbl_game_category表中的id关联(SQL语句中无关联)。
当要在dict_tbl_game中查找dict_tbl_game_category表中的name,ename时,
1). 对于left join,不管on后面跟什么条件,左表的数据全部查出来,因此要想过滤需把条件放到where后面
2). 对于inner join,两表关键字相同时查出对应的两表的数据。(如满足on后的id相同时,才把第一个表firstName和第二个表address显示出来)满足on后面的条件表的数据才能查出,可以起到过滤作用。也可以把条件放到where后面。
1 @Select("select d.id,d.name,price,online_status as onlineStatus,last_update_time as lastUpdateTime,app_logo as logo,operation_type as operationType," + 2 "app_en_name as ename,app_package_size as packageSize,app_ver_name as version,total_rate as rate,app_desc as description," + 3 "app_tags as tags,discounted_price as discountedPrice,vip_discount as vipPrice,is_vip_not_free as vipNotFree," + 4 "c.name as categoryName,c.english_name as categoryEname,app_banner_logo as bannerLogo,pictures as imgList," + 5 "achievement_cnt as achievementCnt,rankinglist_cnt as rankinglistCnt,item_cnt as itemCnt " + 6 "from dict_tbl_game d left join sum_tbl_game s on d.id=s.id " + 7 "left join dict_tbl_game_category c on d.category_id = c.id " + 8 "where d.id=#{qpid}") 9 Game getGameDetail(long id);
c.name as categoryName,c.english_name as categoryEname这个字段在dict_tbl_game_category表中才有。
2 中英文切换的时候分别根据游戏的中英文名进行查询:
后台逻辑判断:
1 String tempName = null; 2 String ename = null; 3 String name = null; 4 5 if(StringUtils.hasText(game)) { 6 7 boolean autocomplete = false; 8 9 int startIndex = game.lastIndexOf("("); 10 int endIndex = game.lastIndexOf(")"); 11 if (startIndex > 0 && endIndex > startIndex && endIndex == game.length() - 1) { 12 try { 13 id = Long.parseLong(game.substring(startIndex + 1, endIndex)); 14 tempName = game.substring(0, startIndex); 15 autocomplete = true; 16 } catch (Exception e) { 17 } 18 } 19 20 if (!autocomplete) { 21 try { 22 id = Long.parseLong(game); 23 } catch (Exception e) { 24 tempName = game; 25 } 26 } 27 } 28 29 Locale locale = LocaleContextHolder.getLocale(); 30 if("zh_CN".equals(locale.toString())){ 31 name = tempName; 32 } 33 if("en_US".equals(locale.toString())){ 34 ename = tempName; 35 } 36 37 List<Game> list = gameMapper.getGameList(id, name, ename, operationType, onlineStatus, categoryId);
当为中文页面的时候,ename 就为null;英文页面的时候 name 就为 null。
这样在SQL中就可以直接查找这两个,而不用分别去处理:
1 <select id="getGameList" resultType="com.iqiyi.tvgame.nvreport.domain.Game"> 2 select d.id,name,app_en_name as ename,online_status as onlineStatus,price,last_update_time as lastUpdateTime, 3 acc_install_device_cnt as accInstallDeviceCnt,acc_uninstall_device_cnt as accUninstallDeviceCnt, 4 acc_breakdown_cnt as accBreakdownCnt,acc_anr_cnt as accAnrCnt,acc_start_cnt as accStartCnt, 5 achievement_cnt as achievementCnt,rankinglist_cnt as rankinglistCnt,total_money as totalMoney, 6 operation_type as operationType,developer_name as developerName 7 from dict_tbl_game d left join sum_tbl_game s on d.id=s.id 8 <include refid="whereClause" /> 9 </select> 10 11 <sql id="whereClause"> 12 <where> 13 <if test="id != null"> 14 d.id=#{id} 15 </if> 16 <if test="name != null"> 17 and name=#{name} 18 </if> 19 <if test="ename != null"> 20 and app_en_name=#{ename} 21 </if> 22 <if test="onlineStatus != null"> 23 and online_status=#{onlineStatus} 24 </if> 25 <if test="operationType != null"> 26 and operation_type=#{operationType} 27 </if> 28 <if test="categoryId != null"> 29 and category_id=#{categoryId} 30 </if> 31 </where> 32 </sql>
前台页面显示的时候,要用<c:if test="">分别去判断显示:
1 <c:forEach items="${list}" var="item"> 2 <tr> 3 <td><c:out value="${item.id}" /></td> 4 <td> 5 <c:if test="${pageContext.response.locale == 'zh_CN'}"> 6 <c:out value="${item.name}" /> 7 </c:if> 8 <c:if test="${pageContext.response.locale == 'en_US'}"> 9 <c:out value="${item.ename}" /> 10 </c:if> 11 </td>
3
前台页面获取下拉框数据categoryId时:
1 <select class="form-control" name="categoryId"> 2 <option value=""><fmt:message key="game.categoryAllType"/></option> 3 <c:forEach items="${categoryList}" var="categoryItem"> 4 <option value="${categoryItem.id}" <c:if test="${categoryItem.id == param.categoryId}">selected="selected"</c:if>> 5 <c:if test="${pageContext.response.locale == 'zh_CN'}"> 6 <c:out value="${categoryItem.name}" /> 7 </c:if> 8 <c:if test="${pageContext.response.locale == 'en_US'}"> 9 <c:out value="${categoryItem.englishName}" /> 10 </c:if> 11 </option> 12 </c:forEach> 13 </select>
先将category对应的sql表封装成一个Category对象,
categoryId,categoryItem.name categoryItem.englishName都是Category的属性。
1 package com.iqiyi.tvgame.nvreport.domain; 2 3 public class Category { 4 5 private int id; 6 private String name; 7 private String englishName; 8 9 public int getId() { 10 return id; 11 } 12 13 public void setId(int id) { 14 this.id = id; 15 } 16 17 public String getName() { 18 return name; 19 } 20 21 public void setName(String name) { 22 this.name = name; 23 } 24 25 public String getEnglishName() { 26 return englishName; 27 } 28 29 public void setEnglishName(String englishName) { 30 this.englishName = englishName; 31 } 32 }
封装成对象后,直接在SQL查询得到category的中英文的List<Category>对象列表,然后直接传送到前台,前台中进行判断解析:
1 @Select("select id,name,english_name as englishName from dict_tbl_game_category") 2 List<Category> getCategoryList();
注意这里不用distinct。及时用了也无效。distinct只对一列值有效,作用在3列时表示只有这三个列值都相同时才排除,显然是不可能的,最后返回的结果自然是所有的值。
再直接返回数据。
List<Category> categoryList = gameMapper.getCategoryList();
前台即可以解析:
1 <select class="form-control" name="categoryId"> 2 <option value=""><fmt:message key="game.categoryAllType"/></option> 3 <c:forEach items="${categoryList}" var="categoryItem"> 4 <option value="${categoryItem.id}" <c:if test="${categoryItem.id == param.categoryId}">selected="selected"</c:if>> 5 <c:if test="${pageContext.response.locale == 'zh_CN'}"> 6 <c:out value="${categoryItem.name}" /> 7 </c:if> 8 <c:if test="${pageContext.response.locale == 'en_US'}"> 9 <c:out value="${categoryItem.englishName}" /> 10 </c:if> 11 </option> 12 </c:forEach> 13 </select>
4 提示:
使用title属性:
1 <th title="<fmt:message key='game.successPaymentRate'/>=<fmt:message key='game.successPayment'/>/<fmt:message key='game.paymentPageActivation'/>"> 2 <fmt:message key="game.successPaymentRate"></fmt:message> 3 </th>