gamecenter-xoa-旧版结构-stable

gamecenter-xoa-旧版结构-stable
1、renren-wap-fuxi-service-def
model和service(接口) 接口的粒度以实际业务为接口
不以单独的dao为接口,如userplay相关的业务为统一接口
如:

/**
* $Id: IUserPlayService.java 43455 2011-07-27 12:30:44Z zhanghua@XIAONEI.OPI.COM $
* Copyright 2009-2010 Oak Pacific Interactive. All rights reserved.
*/
package com.xiaonei.wap.fuxi.service;

import java.util.List;

import com.xiaonei.wap.fuxi.model.AppPageResult;
import com.xiaonei.wap.fuxi.model.UserPlayFlowResult;

//--------------------- Change Logs----------------------
// <p>@author wangqiao Initial Created at 2011-7-26<p>
//好友在玩相关接口初始化
//-------------------------------------------------------
public interface IUserPlayService {

/**
* 分页 取我的pageId list,包含总数
*
* @param userId
* @param pageNum
* @param pageSize
* @return
*/
AppPageResult getMyPlayPageList(int userId, int pageNum, int pageSize);

/**
* 取好友玩过的page列表,带总数 从库中取时根据过期天数expiredDays进行过滤,负数-1不过滤,os=-1不过滤
*
* @param userId
* @param os
* @param expiredDays
* @param pageNum
* @param pageSize
* @return
*/
AppPageResult getFriendPlayPageList(int userId, int os, int expiredDays, int pageNum,
int pageSize);

/**
* 获取某apppage的好友
*
* @param userId
* @param pageId
* @param expiredDays
* @return
*/
List<Integer> getFriendPlayByPageId(int userId, int pageId, int expiredDays);

/**
* 批量获取apppage的好友
*
* @param userId
* @param pageIds
* @param expiredDays
* @return
*/
List<UserPlayFlowResult> getFriendPlayByPageIds(int userId, List<Integer> pageIds,
int expiredDays);

}


2、renren-wap-fuxi-service-impl
DAO及impl、util
DAO多使用in函数实现对多条记录的查询,不过使用in则建立的mysql索引不起作用,sql只有在==时 索引才会起作用
如:

/**
* $Id$
* Copyright 2009-2010 Oak Pacific Interactive. All rights reserved.
*/
package com.xiaonei.wap.fuxi.service.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.Assert;

import com.xiaonei.wap.fuxi.dao.IUserPlayFlowDAO;
import com.xiaonei.wap.fuxi.model.AppPage;
import com.xiaonei.wap.fuxi.model.AppPageResult;
import com.xiaonei.wap.fuxi.model.UserPlayFlowResult;
import com.xiaonei.wap.fuxi.service.IUserPlayService;
import com.xiaonei.wap.fuxi.util.ComparatorAppPage;

//--------------------- Change Logs----------------------
//<p>@author zhanghua Initial Created at 2011-7-26<p>
//好友玩过的app增加os过滤条件,os=-1不过滤
//拆分接口
//-------------------------------------------------------
public class UserPlayServiceImpl extends BaseBusinessService implements IUserPlayService,
InitializingBean {

/**
* Logger for this class
*/
private static final Log logger = LogFactory.getLog(UserPlayServiceImpl.class);

private IUserPlayFlowDAO userPlayFlowDAO;

@Override
public AppPageResult getMyPlayPageList(int userId, int pageNum, int pageSize) {
if (pageNum <= 0 || userId <= 0 || pageSize <= 0) {
return null;
}
List<AppPage> pageList = null;
// 取我玩过的page id
List<Integer> pageIdList = getMyPlayPageIds(userId);
if (CollectionUtils.isNotEmpty(pageIdList)) {
// TODO 如果需要带好友玩过的信息,请用getPagesWithFriendPlay方法
pageList = getAppPagesByPageIds(pageIdList);
}
//封装返回值
AppPageResult appPageResult = new AppPageResult();
appPageResult.setCount(pageList == null ? 0 : pageList.size());
//分页
pageList = page(pageList, pageNum, pageSize);
appPageResult.setAppPageList(pageList);
return appPageResult;
}

@Override
public AppPageResult getFriendPlayPageList(int userId, int os, int expiredDays, int pageNum,
int pageSize) {
if (userId <= 0 || pageNum <= 0 || pageSize <= 0) {
return null;
}
//取所有好友玩过的信息
Map<String, List<Integer>> playedMap = getFriendPlayMap(userId, expiredDays);
if (logger.isDebugEnabled()) {
logger.debug("playedMap size: " + playedMap.size());
}
if (MapUtils.isEmpty(playedMap)) {
return null;
}
//进一步组装
List<AppPage> resultList = wrapAppPageList(playedMap);
if (logger.isDebugEnabled()) {
if (resultList != null) logger.debug("resultList size: " + resultList.size());
}
//根据os过滤
if (os >= 0) {
filterByOs(resultList, os);
}
if (CollectionUtils.isEmpty(resultList)) {
return null;
}
if (logger.isDebugEnabled()) {
if (resultList != null) logger.debug("os filter resultList size: " + resultList.size());
}
//按玩过的人数从多到少排序
sort(resultList, new ComparatorAppPage());
//封装返回值
AppPageResult appPageResult = new AppPageResult();
appPageResult.setCount(resultList == null ? 0 : resultList.size());
//分页
resultList = page(resultList, pageNum, pageSize);
appPageResult.setAppPageList(resultList);
return appPageResult;
}

@Override
public List<Integer> getFriendPlayByPageId(int userId, int pageId, int expiredDays) {
//取好友玩过的信息
Map<String, List<Integer>> playedMap = getFriendPlayMap(userId, expiredDays);
if (MapUtils.isEmpty(playedMap)) {
return null;
}
if(CollectionUtils.isNotEmpty(playedMap.get(pageId+""))){
return playedMap.get(pageId+"");
}
return null;
}

@Override
public List<UserPlayFlowResult> getFriendPlayByPageIds(int userId, List<Integer> pageIds,
int expiredDays) {
UserPlayFlowResult userPlayFlowResult;
List<UserPlayFlowResult> resultList = new ArrayList<UserPlayFlowResult>();
//取好友玩过的信息
Map<String, List<Integer>> playedMap = getFriendPlayMap(userId, expiredDays);
if (MapUtils.isEmpty(playedMap)) {
return null;
}
for(int pageId : pageIds){
if(CollectionUtils.isNotEmpty(playedMap.get(pageId+""))){
userPlayFlowResult = new UserPlayFlowResult();
userPlayFlowResult.setPageId(pageId);
userPlayFlowResult.setFriends(playedMap.get(pageId+""));
resultList.add(userPlayFlowResult);
}
}
return resultList;
}

@Override
public void afterPropertiesSet() throws Exception {
Assert.notNull(userPlayFlowDAO, "appCategoryDAO is required!");
Assert.notNull(friendsFacade, "friendsFacade is required!");
Assert.notNull(userLastPlayFlowDAO, "userLastPlayFlowDAO is required!");
}

@Autowired
public void setUserPlayFlowDAO(IUserPlayFlowDAO userPlayFlowDAO) {
this.userPlayFlowDAO = userPlayFlowDAO;
}


}


3、renren-wap-fuxi-xoa-client(xoa)
实现对xoa的调用,包括Delegate和XoaClientFactory(注册xoa和调用方法)
如FuxiXoaClientFactory
/**
* $Id$
* Copyright 2009-2010 Oak Pacific Interactive. All rights reserved.
*/
package com.xiaonei.wap.fuxi.xoa;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.apache.log4j.Logger;

import com.renren.xoa.ContentParseException;
import com.renren.xoa.Method;
import com.renren.xoa.StatusNotOkException;
import com.renren.xoa.XoaClient;
import com.renren.xoa.XoaResponse;
import com.renren.xoa.methods.XoaMethodName;
import com.renren.xoa.registry.impl.SimpleXoaRegistry;
import com.xiaonei.wap.fuxi.exception.ServiceTimeoutException;
import com.xiaonei.wap.fuxi.exception.ServiceUnableException;

/**
* Xoa的Client工厂定义
*
* 将服务器端异常直接捕获,从而不需要再使用者捕获异常。 对于无法获取到数据的接口,Object但对象返回为null 集合对象返回的是空的集合
*
*/
public class FuxiXoaClientFactory {

private static final Logger logger = Logger.getLogger(FuxiXoaClientFactory.class);

public static final String pubdate = "110513";

private static final String SERVICE_ID = "fuxi.xoa.renren.com";

public static final String XOA_SERVICE_URL = "xoa://" + SERVICE_ID;

//TODO 需要修改 当前是测试ip
private static final String SERVER_HOST = "10.3.19.200";

//TODO 需要修改 当前是测试端口
private static final int SERVER_PORT = 8388;

/** 超时设置 3秒 */
public static final int XOA_GET_TIMEOUT = 3000;

/** 超时设置 5秒 */
public static final int XOA_POST_TIMEOUT = 5000;

private static XoaClient client = null;

/**
* 取一个可用的客户端
*
* @return
*/
public static XoaClient getXoaClient() {
if (client != null) {
return client;
}
synchronized (SERVICE_ID) {
//此处的SERVICE_ID指出client会调用哪个服务器上的server端
SimpleXoaRegistry reg = new SimpleXoaRegistry();
reg.register(SERVICE_ID, SERVER_HOST, SERVER_PORT);
// reg.register(SERVICE_ID, "10.3.19.157", 8388);
// reg.register(SERVICE_ID, "10.3.18.204", 8188);
// reg.register(SERVICE_ID, "10.3.18.210", 8188);
// reg.register(SERVICE_ID, "10.3.19.189", 8188);
// reg.register(SERVICE_ID, "10.3.19.163", 8188);
client = new XoaClient(reg);
}
return client;
}

/**
* 执行无返回的方法,异常将会被直接拦截掉
*
* @param method
*/
public static void execute(Method method) {
long startTime = System.currentTimeMillis();
method.setParam("v", pubdate);
try {
getXoaClient().execute(method);
} catch (Exception e) {
logger.error("execute," + method.getName() + " error:", e);
} finally {
long used = (System.currentTimeMillis() - startTime);
logger.info(method.getName() + "|" + method.getPath() + "|" + used);
}
}

/**
* 直接得到返回,按照默认超时时间返回结果
*
* @param method
* @return
*/
public static XoaResponse getResponse(Method method) {
int timeout = XOA_GET_TIMEOUT;
if (!XoaMethodName.GET.equals(method.getName())) {
timeout = XOA_POST_TIMEOUT;
}
return getResponse(method, timeout);
}

/**
* 直接得到返回
*
* @param method
* @return
*/
private static XoaResponse getResponse(Method method, int timeout) {
long startTime = System.currentTimeMillis();
method.setParam("v", pubdate);
Future<XoaResponse> fs = getXoaClient().submit(method);
try {
return fs.get(timeout, TimeUnit.MILLISECONDS);
} catch (ContentParseException e) {
logger.error("XOA.getResponse ContentParseException", e);
throw new ServiceUnableException();
} catch (InterruptedException e) {
logger.error("XOA.getResponse InterruptedException", e);
throw new ServiceUnableException();
} catch (ExecutionException e) {
logger.error("XOA.getResponse ExecutionException", e);
throw new ServiceUnableException();
} catch (TimeoutException e) {
logger.error("XOA.getResponse TimeoutException", e);
throw new ServiceTimeoutException();
} finally {
long used = (System.currentTimeMillis() - startTime);
logger.info(method.getName() + "|" + method.getPath() + "|" + used);
}
}

/**
* 直接得到转换后的结果
*
* @param <T>
* @param method
* @param klass
* @return
*/
public static <T> T getContent(Method method, Class<T> klass, int timeout) {
try {
return getResponse(method, timeout).getContentAs(klass);
} catch (ContentParseException e) {
logger.error("request:" + method.getName() + "|" + method.getPath() + " error", e);
return null;
} catch (ServiceUnableException sue) {
logger.error("request:" + method.getName() + "|" + method.getPath() + " error", sue);
return null;
} catch (ServiceTimeoutException ste) {
logger.error("request:" + method.getName() + "|" + method.getPath() + " error", ste);
return null;
} catch (StatusNotOkException e) {
logger.error("request:" + method.getName() + "|" + method.getPath() + " error", e);
return null;
} catch (Exception e) {
logger.error("request:" + method.getName() + "|" + method.getPath() + " error", e);
return null;
}
}

/**
* 直接得到转换后的结果列表
*
* @param <T>
* @param method
* @param klass
* @return
*
*/
public static <T> List<T> getList(Method method, Class<T[]> t, int timeout) {
T[] array = getContent(method, t, timeout);
List<T> listEntity = new ArrayList<T>();
if (array != null) {
listEntity = Arrays.asList(array);
}
return listEntity;
}
}


Delegate实现了接口,完成url的映射,带上相关的参数,如下:


/**
* $Id: UserPlayServiceDelegate.java 43518 2011-07-28 04:13:08Z zhanghua@XIAONEI.OPI.COM $
* Copyright 2009-2010 Oak Pacific Interactive. All rights reserved.
*/
package com.xiaonei.wap.fuxi.xoa.client;

import java.util.List;

import org.apache.commons.collections.CollectionUtils;

import com.renren.xoa.Method;
import com.xiaonei.wap.fuxi.model.AppPageResult;
import com.xiaonei.wap.fuxi.model.UserPlayFlowResult;
import com.xiaonei.wap.fuxi.service.IUserPlayService;
import com.xiaonei.wap.fuxi.xoa.FuxiXoaClientFactory;

//--------------------- Change Logs----------------------
// <p>@author anbingquan Initial Created at 2011-7-26<p>
//去掉没用的import
//-------------------------------------------------------
public class UserPlayServiceDelegate extends BaseDelegate implements IUserPlayService {

final static String _PREFIX_FRIENDPLAYED = FuxiXoaClientFactory.XOA_SERVICE_URL + "/friendplay";

final static String _MYPLAYLIST = _PREFIX_FRIENDPLAYED + "/myplaylist";

final static String _LIST = _PREFIX_FRIENDPLAYED + "/list";

final static String _FRIENDLIST = _PREFIX_FRIENDPLAYED + "/friendlist";

final static String _FRIENDLIST_BATCH = _PREFIX_FRIENDPLAYED + "/friendlistbatch";

@Override
public AppPageResult getMyPlayPageList(int userId, int pageNum, int pageSize) {
Method method = Method.get(_MYPLAYLIST);
method.setParam("userId", String.valueOf(userId));
method.setParam("pageNum", String.valueOf(pageNum));
method.setParam("pageSize", String.valueOf(pageSize));
return FuxiXoaClientFactory.getContent(method, AppPageResult.class, XOA_GET_TIMEOUT);
}

@Override
public AppPageResult getFriendPlayPageList(int userId, int os, int expiredDays, int pageNum,
int pageSize) {
Method method = Method.get(_LIST);
method.setParam("userId", String.valueOf(userId));
method.setParam("os", String.valueOf(os));
method.setParam("expiredDays", String.valueOf(expiredDays));
method.setParam("pageNum", String.valueOf(pageNum));
method.setParam("pageSize", String.valueOf(pageSize));
return FuxiXoaClientFactory.getContent(method, AppPageResult.class, XOA_GET_TIMEOUT);
}

@Override
public List<Integer> getFriendPlayByPageId(int userId, int pageId, int expiredDays) {
Method method = Method.get(_FRIENDLIST);
method.setParam("userId", String.valueOf(userId));
method.setParam("pageId", String.valueOf(pageId));
method.setParam("expiredDays", String.valueOf(expiredDays));
return FuxiXoaClientFactory.getList(method, Integer[].class, XOA_GET_TIMEOUT);
}

@Override
public List<UserPlayFlowResult> getFriendPlayByPageIds(int userId, List<Integer> pageIds,
int expiredDays) {
Method method = Method.get(_FRIENDLIST_BATCH);
method.setParam("userId", String.valueOf(userId));
method.setParam("expiredDays", String.valueOf(expiredDays));
if (CollectionUtils.isNotEmpty(pageIds)) {
for (Integer pageId : pageIds) {
method.setParam("pageIds", String.valueOf(pageId));
}
}
return FuxiXoaClientFactory.getList(method, UserPlayFlowResult[].class, XOA_GET_TIMEOUT);
}
}




4、renren-wap-fuxi-xoa-server
通过@Get或@Post的映射关系,来调用service层内部接口中的方法

/**
* $Id$
* Copyright 2009-2010 Oak Pacific Interactive. All rights reserved.
*/
package com.xiaonei.wap.fuxi.controllers;

import java.util.List;

import net.paoding.rose.web.annotation.Param;
import net.paoding.rose.web.annotation.Path;
import net.paoding.rose.web.annotation.rest.Get;

import org.springframework.beans.factory.annotation.Autowired;

import com.xiaonei.wap.fuxi.model.AppPageResult;
import com.xiaonei.wap.fuxi.model.UserPlayFlowResult;
import com.xiaonei.wap.fuxi.service.IUserPlayService;

//--------------------- Change Logs----------------------
// <p>@author anbingquan Initial Created at 2011-7-26<p>
//-------------------------------------------------------

@Path("/friendplay")
public class FriendPlayController {

@Autowired
private IUserPlayService userPlayService;

final static String _MYPLAYLIST = "/myplaylist";

final static String _LIST = "/list";

final static String _FRIENDLIST = "/friendlist";

final static String _FRIENDLIST_BATCH = "/friendlistbatch";

/**
* 分页取自己玩过的page列表,带总数
*
* @param userId
* @param pageNum
* @param pageSize
* @return
*/
@Get(_MYPLAYLIST)
public AppPageResult getMyPlayPageList(@Param("userId") int userId,
@Param("pageNum") int pageNum, @Param("pageSize") int pageSize) {

return userPlayService.getMyPlayPageList(userId, pageNum, pageSize);
}

/**
* 分页取好友玩过的page列表,根据os过滤,带总数
*
* @param userId
* @param os
* @param expiredDays
* @param pageNum
* @param pageSize
* @return
*/
@Get(_LIST)
public AppPageResult getFriendPlayPageList(@Param("userId") int userId, @Param("os") int os,
@Param("expiredDays") int expiredDays, @Param("pageNum") int pageNum,
@Param("pageSize") int pageSize) {

return userPlayService.getFriendPlayPageList(userId, os, expiredDays, pageNum, pageSize);
}

/**
* 获取某apppage的好友
*
* @param userId
* @param pageId
* @param expiredDays
* @return
*/
@Get(_FRIENDLIST)
public List<Integer> getFriendPlayByPageId(@Param("userId") int userId,
@Param("pageId") int pageId, @Param("expiredDays") int expiredDays) {
return userPlayService.getFriendPlayByPageId(userId, pageId, expiredDays);
}

/**
* 批量获取apppage的好友
*
* @param userId
* @param pageIds
* @param expiredDays
* @return
*/
@Get(_FRIENDLIST_BATCH)
public List<UserPlayFlowResult> getFriendPlayByPageIds(@Param("userId") int userId,
@Param("pageIds") List<Integer> pageIds, @Param("expiredDays") int expiredDays) {
return userPlayService.getFriendPlayByPageIds(userId, pageIds, expiredDays);
}

}




5、renren-wap-fuxi(wap层)
调用client的delegate接口,实现分布式调用接口的目的

package com.renren.wap.fuxi.controller;

import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.math.NumberUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.util.CollectionUtils;
import org.springframework.web.servlet.ModelAndView;

import com.renren.wap.fuxi.vo.AppPageVO;
import com.xiaonei.platform.core.model.WUserCache;
import com.xiaonei.platform.core.opt.ice.WUserCacheAdapter;
import com.xiaonei.wap.fuxi.model.AppPage;
import com.xiaonei.wap.fuxi.model.AppPageResult;

/**
* @author <a href="mailto:wp.anbingquan@opi-corp.com">安炳全</a>
* @createTime 2011-07-15 16:00:00
*/

public class FriendPlayedingController extends BaseController {

private static final Log logger = LogFactory.getLog(FriendPlayedingController.class);

private final String ATTRIBUTE_METHOD = "method";

private final String ATTRIBUTE_PAGEVO_LIST = "voList";

private final String ATTRIBUTE_PAGE_CURPAGE = "curpage";

private final String ATTRIBUTE_PAGE_SUM = "navCount";

private final String ATTRIBUTE_PAGE_ITEMPERSIZE = "itemPerPage";

private final int SHOW_FRIEND_COUNT = 2;

public ModelAndView list(HttpServletRequest request, HttpServletResponse response)
throws Exception {

if (logger.isDebugEnabled()) {
logger.debug("FriendPlayedingController begin......");
}
ModelAndView mav = new ModelAndView("/pages/wap/friendsplay");

//int hostId = getUserId(request);
int hostId = 1;
if(hostId==0){
//去登录
}
int os = NumberUtils.toInt(request.getParameter("os"), 0);
int curpage = NumberUtils.toInt(request.getParameter("curpage"), 0);

if (logger.isDebugEnabled()) {
logger.debug("hostId :" + hostId);
logger.debug("os :" + os);
logger.debug("currentPage :" + curpage);
logger.debug("itemPerPage :" + itemPerPage);
}

AppPageResult appPageResult = userPlayService.getFriendPlayPageList(hostId, os, EXPIRED_NO,
curpage, itemPerPage); //调delegate
//AppPageResult appPageResult = tempData(); 本地测试
if (logger.isDebugEnabled()) {
if (appPageResult != null && appPageResult.getAppPageList() != null) {
logger.debug("appPageResult count: " + appPageResult.getCount());
}
}
List<AppPageVO> voList = buildVOList(
(appPageResult != null) ? appPageResult.getAppPageList() : new ArrayList<AppPage>(),
(appPageResult != null) ? appPageResult.getCount() : 0);
mav.addObject(ATTRIBUTE_PAGE_CURPAGE, curpage);
mav.addObject(ATTRIBUTE_PAGE_SUM, (appPageResult != null) ? appPageResult.getCount() : 0);
mav.addObject(ATTRIBUTE_PAGE_ITEMPERSIZE, itemPerPage);
mav.addObject(ATTRIBUTE_PAGEVO_LIST, voList);
mav.addObject(ATTRIBUTE_METHOD, "list");
return mav;
}

private List<AppPageVO> buildVOList(List<AppPage> pageList, int count) {

List<AppPageVO> voList = new ArrayList<AppPageVO>();//封装了好友在玩(名字,数量)用于页面显示
AppPageVO vo;
for (AppPage page : pageList) {
vo = new AppPageVO();
vo.setId(page.getId());
vo.setPageName(page.getPageName());
vo.setCompany(page.getCompany());
vo.setIntroduction(page.getIntroduction());
vo.setWapLogoUrl(page.getWapLogoUrl());
vo.setShowText(getFriendNames(page));
vo.setPlayCount(count);
voList.add(vo);
}

return voList;
}

private String getFriendNames(AppPage page) {
String friendNames = "";
List<Integer> friendIds = String2List(page.getFriends());
List<WUserCache> users;
if (CollectionUtils.isEmpty(friendIds)) {
return null;
}
if (friendIds.size() > SHOW_FRIEND_COUNT) {
users = WUserCacheAdapter.getInstance().getUsersCacheList(
friendIds.subList(0, SHOW_FRIEND_COUNT));
} else {
users = WUserCacheAdapter.getInstance().getUsersCacheList(friendIds);
}
for (int i = 0; i < users.size(); i++) {
if (i < users.size() - 1) {
friendNames += users.get(i).getName();
} else {
friendNames += "," + users.get(i).getName();
}
}
return friendNames;
}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值