SpringMVC和jQuery的Ajax简单文件上传下载示例

准备工作: 
前端引入:1、jquery,我在这里用的是:jquery-1.10.2.min.js 
        2、ajaxfileupload.js 
这里可能会报一些错,所以在json判断那里修改为(网上也有): 
Js代码   收藏代码
  1. if ( type == "json" ){  
  2.    data = r.responseText;     
  3.    var start = data.indexOf(">");     
  4.    if(start != -1) {     
  5.       var end = data.indexOf("<", start + 1);     
  6.       if(end != -1) {     
  7.          data = data.substring(start + 1, end);     
  8.       }     
  9.    }   
  10.    eval( "data = " + data );  
  11. }  

末尾那里补充一段: 
Js代码   收藏代码
  1. handleError: function( s, xhr, status, e ) {  
  2.   if ( s.error ) {  
  3.        s.error.call( s.context || window, xhr, status, e );  
  4.   }  
  5.   if ( s.global ) {  
  6.      (s.context ? jQuery(s.context) : jQuery.event).trigger  ( "ajaxError", [xhr, s, e] );  
  7.   }  
  8. }  

后台导入spring的jar包,我这里用的是:spring3.0.5 
在spring.xml里配置如下: 
Xml代码   收藏代码
  1. <!-- SpringMVC上传文件时,需要配置MultipartResolver处理器 -->    
  2.    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">    
  3.        <property name="defaultEncoding" value="UTF-8"/>    
  4.        <!-- 指定所上传文件的总大小不能超过200KB。注意maxUploadSize属性的限制不是针对单个文件,而是所有文件的容量之和 -->    
  5.        <!-- 不在这里限制了,后台各自进行限制了  
  6.        <property name="maxUploadSize" value="2000000"/>   
  7.        -->   
  8.     </bean>   
  9.       
  10.     <!-- SpringMVC在超出上传文件限制时,会抛出org.springframework.web.multipart.MaxUploadSizeExceededException -->    
  11.    <!-- 该异常是SpringMVC在检查上传的文件信息时抛出来的,而且此时还没有进入到Controller方法中 -->    
  12.    <bean id="exceptionResolver" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">    
  13.        <property name="exceptionMappings">    
  14.            <props>    
  15.                <!-- 遇到MaxUploadSizeExceededException异常时,跳转到/page/html/errorGolbal.html页面 -->    
  16.                <prop key="org.springframework.web.multipart.MaxUploadSizeExceededException">/page/html/errorGolbal.html</prop>    
  17.            </props>    
  18.        </property>    
  19.    </bean>  

这里就充分利用框架的便利性帮你都做好了,如果你不在xml里配置这些,那么在controller那里,request.getInputStream()得到的这个流不全是文件流,还包含了其他,需要你自己编码去解析,当然,要解析的话还要知道http相关报文解析知识,所以这里可以充分利用框架的便利性,有兴趣的可以研究下  

好了,准备工作做好了,看下前端的具体代码: 
Html代码   收藏代码
  1. <div id="fileUpLoad" class="manage">  
  2.     添附文件  
  3.     <!-- 自定义 <input type="file"/> -->  
  4.     <input type="file" id="btnFile" name="btnFile" onchange="txtFoo.value=this.value;com.company.project.services.newCase.fileUpLoad()" hidden="hidden" />  
  5.     <input type="text" id="txtFoo" readonly="readonly" style="width: 300px" />           
  6.     <button onclick="btnFile.click()" style="height: 25px;">选择文件</button>  
  7. </div>  

js代码为: 
Js代码   收藏代码
  1. if (!window.com) {  
  2.     window.com = {};  
  3. }  
  4. if (!window.com.company) {  
  5.     window.com.company= {};  
  6. }  
  7. if (!window.com.company.project) {  
  8.     window.com.company.project= {};  
  9. }  
  10. if (!window.com.company.project.services) {  
  11.     window.com.company.project.services = {};  
  12. }  
  13. if (!window.com.company.project.services.newCase) {  
  14.     window.com.company.project.services.newCase = {};  
  15. }  
  16.   
  17. //生成随机guid数(参考网上)  
  18. com.company.project.services.newCase.getGuidGenerator = function() {   
  19.     var S4 = function() {   
  20.        return (((1+Math.random())*0x10000)|0).toString(16).substring(1);   
  21.     };   
  22.     return (S4()+S4()+"-"+S4()+"-"+S4()+"-"+S4()+"-"+S4()+S4()+S4());   
  23. };  
  24.   
  25. //上传文件  
  26. com.company.project.services.newCase.fileUpLoad = function(){  
  27.     var fileName = $("#btnFile").val();//文件名  
  28.     fileName = fileName.split("\\");  
  29.     fileName = fileName[fileName.length-1];  
  30.     var guid = com.company.project.services.newCase.getGuidGenerator();//唯一标识guid  
  31.     var data = {guid:guid};  
  32.     jQuery.ajaxSettings.traditional = true;  
  33.     $.ajaxFileUpload({  
  34.         url : '/PROJECT/function.do?method=fileUpLoad',  
  35.         secureuri : false,//安全协议  
  36.         fileElementId:'btnFile',//id  
  37.         type : 'POST',  
  38.         dataType : 'json',  
  39.         data:data,  
  40.         async : false,  
  41.         error : function(data,status,e) {  
  42.             alert('Operate Failed!');  
  43.         },  
  44.         success : function(json) {  
  45.             if (json.resultFlag==false){  
  46.                 alert(json.resultMessage);  
  47.             }else{  
  48.                 alert('文件上传成功!');  
  49.                 var next = $("#fileUpLoad").html();  
  50.                 $("#fileUpLoad").html("<div id='"+guid+"'>"+"文件:"+fileName+"   <a href='#' οnclick='com.company.project.services.newCase.filedelete("+"\""+guid+"\""+","+"\""+fileName+"\""+")'>删除</a>"+"<br/></div>");  
  51.                 $("#fileUpLoad").append(next);  
  52.             }  
  53.         }  
  54.     });  
  55. };  
  56.   
  57. //文件删除  
  58. com.company.project.services.newCase.filedelete = function(guid,fileName){  
  59.     jQuery.ajaxSettings.traditional = true;  
  60.     var data = {guid:guid,fileName:fileName};  
  61.     $.ajax({  
  62.         url : '/PROJECT/function.do?method=filedelete',  
  63.         type : 'POST',  
  64.         dataType : 'json',  
  65.         data:data,  
  66.         async : false,  
  67.         error : function() {  
  68.             alert('Operate Failed!');  
  69.         },  
  70.         success : function(json) {  
  71.             if (json.resultFlag==false){  
  72.                 alert(json.resultMessage);  
  73.             }else{  
  74.                 alert('删除成功!');  
  75.                 $("#"+guid).remove();  
  76.             }  
  77.         }  
  78.     });  
  79. };  


---------------------------------------------------------------------------------- 

注:如果你对ajax不熟悉,或者由于浏览器等原因,致使上述方式提交出现各种问题,那么你可以用form表单形式提交,代码片段如下:  
Html代码   收藏代码
  1. <div id="fileUpLoad" class="manage">  
  2.     <form id="needHide" action="/工程/function.do?method=fileUpLoad" method="post" enctype="multipart/form-data" target = "hidden_frame">  
  3.     <!-- 自定义 <input type="file"/> -->  
  4.     <input type="file" id="btnFile" name="btnFile" onchange="txtFoo.value=this.value;com.company.project.services.newCase.fileUpLoad()" hidden="hidden"/>  
  5.     </form>  
  6.     添附文件  
  7.     <input type="text" id="txtFoo" readonly="readonly" style="width: 300px" />           
  8.     <button onclick="btnFile.click()" style="height: 25px;">选择文件</button>  
  9.     <iframe name='hidden_frame' id="hidden_frame" style='display: none' onload="com.company.project.services.newCase.statusCheck()"></iframe>  
  10. </div>  


js代码写为:  
Js代码   收藏代码
  1. var flag = true;  
  2. com.company.project.services.newCase.statusCheck = function(){  
  3.     if(flag == false){  
  4.         var status = hidden_frame.window.document.getElementById("hideForm").innerHTML;  
  5.         console.log(status);  
  6.     }  
  7.     flag = false;  
  8. };  
  9.   
  10. //上传文件  
  11. com.company.project.services.newCase.fileUpLoad = function(){  
  12.     $("#needHide").submit();  
  13. }  


后台代码主要在最后变为:  
Java代码   收藏代码
  1. PrintWriter printWriter = response.getWriter();  
  2. printWriter.write("<div id='hideForm'>1111</div>");  

---------------------------------------------------------------------------------- 

后台对应java代码段为: 
Java代码   收藏代码
  1. @RequestMapping(params = "method=fileUpLoad")  
  2. //btnFile对应页面的name属性  
  3. public void fileUpLoad(@RequestParam MultipartFile[] btnFile, HttpServletRequest request, HttpServletResponse response){  
  4.     try{  
  5.         //文件类型:btnFile[0].getContentType()  
  6.         //文件名称:btnFile[0].getName()  
  7.         if(btnFile[0].getSize()>Integer.MAX_VALUE){//文件长度  
  8.             OutputUtil.jsonArrOutPut(response, JSONArray.fromObject("上传文件过大!"));  
  9.         }  
  10.         InputStream is = btnFile[0].getInputStream();//多文件也适用,我这里就一个文件  
  11.         //String fileName = request.getParameter("fileName");  
  12.         String guid = request.getParameter("guid");  
  13.         byte[] b = new byte[(int)btnFile[0].getSize()];  
  14.         int read = 0;  
  15.         int i = 0;  
  16.         while((read=is.read())!=-1){  
  17.             b[i] = (byte) read;  
  18.             i++;  
  19.         }  
  20.         is.close();  
  21.         OutputStream os = new FileOutputStream(new File("D://"+guid+"."+btnFile[0].getOriginalFilename()));//文件原名,如a.txt  
  22.         os.write(b);  
  23.         os.flush();  
  24.         os.close();  
  25.         OutputUtil.jsonOutPut(response, null);  
  26.     }catch (Exception e) {  
  27.         OutputUtil.errorOutPut(response, "系统异常");  
  28.     }  
  29. }  
  30.   
  31. @RequestMapping(params = "method=filedelete")  
  32. public void filedelete(HttpServletRequest request, HttpServletResponse response){  
  33.     try{  
  34.         String guid = request.getParameter("guid");  
  35.         String fileName = request.getParameter("fileName");  
  36.         File file = new File("D://"+guid+"."+fileName);  
  37.         boolean isDeleted = file.delete();  
  38.         if(!isDeleted){  
  39.             OutputUtil.errorOutPut(response, "文件删除失败");  
  40.         }  
  41.         OutputUtil.jsonArrOutPut(response, null);  
  42.     }catch (Exception e) {  
  43.         OutputUtil.errorOutPut(response, "系统异常");  
  44.     }  
  45. }  



另外:如果是图片上传的话,你也可以不保存在什么临时目录,可以用base64进行编解码,网上也有很多,简单介绍下: 
后台只要这么做: 
Java代码   收藏代码
  1. //得到byte数组后  
  2. BASE64Encoder base64e = new BASE64Encoder();  
  3.             JSONArray ja = new JSONArray();  
  4.             String base64Str = base64e.encode(b);  
  5.             ja.add(base64Str);  
  6.             OutputUtil.jsonArrOutPut(response, JSONArray.fromObject(ja));  


前台页面只要这么就可以拿到了: 
Html代码   收藏代码
  1. $("#fileUpLoad")  
  2. .append("<image src='"+"data:image/gif;base64,"+json.resultMessage[0]+"' >");  



对于json相关不大了解的可以参考我的博文: 
http://quarterlifeforjava.iteye.com/blog/2024336 


效果和iteye的相似: 
 

补充:如果要让表单提交后还是留在当前页面,除了Ajax还可以用iframe,代码如下: 
其实关键就是iframe和form中的target
 
Html代码   收藏代码
  1. <form target="actionframe" id="needHide" action="/项目名/project.do?method=fileUpLoad" method="post" enctype="multipart/form-data">  
  2.                             <input type="file" id="btnFile" name="btnFile" onchange="txtFoo.value=this.value;" hidden="hidden" />  
  3.                             <input type="text" id="txtFoo" disabled="disabled" style="width: 420px" />  
  4.                         </form>  
  5.                         <iframe width="0" height="0" name="actionframe"></iframe>  



另外关于excel的导入导出可以参考下面的博客:http://xiaoxiong-it.iteye.com/blog/1433131 
简单介绍下: 
前台页面: 
Html代码   收藏代码
  1.                     <form id="that_excel_submit" action="/项目名/translate.do?method=excelInput" method="post">  
  2.                             <input id="fileName" type="file" style="font-size: 10;height: 22px;width: 120px;"/>  
  3.                             <input type="button" style="font-size: 15;height: 23px;width: 120px;color:#FFFFFF;background:url(../images/button1.png);border-radius:2px;border-style:none;" onclick="com.compay.project.services.translate.excelInput()" value="EXCEL文件导入"/>  
  4.                         </form>  
  5. <!-- -------------------------------------------------- -->  
  6.                     <form id="this_excel_submit" action="/项目名/translate.do?method=excelExport" method="post">  
  7.                             <input type="hidden" name="searchInfo" id="input_searchInfo"/>  
  8.                             <input type="hidden" name="type" id="input_type"/>  
  9.                             <input type="hidden" name="addStartDate" id="input_addStartDate"/>  
  10.                             <input type="hidden" name="addEndDate" id="input_addEndDate"/>  
  11.                             <input type="hidden" name="modStartDate" id="input_modStartDate"/>  
  12.                             <input type="hidden" name="modEndDate" id="input_modEndDate"/>  
  13.                             <input type="hidden" name="pageIndex" id="input_pageIndex"/>  
  14.                             <input type="radio" id="exportCheck" value="0" name="exportCheck" checked="checked"/>当前页  
  15.                             <input type="radio" id="exportCheck" value="1" name="exportCheck"/>所有  
  16.                             <input type="button" style="font-size: 15;height: 23px;width: 120px;color:#FFFFFF;background:url(../images/button1.png);border-radius:2px;border-style:none;" onclick="com.company.project.services.translate.excelExport()" value="EXCEL文件导出"/>  
  17.                         </form>  

js那里的话就是:$("#ID").submit(); 
后台如下: 
Java代码   收藏代码
  1. @Controller  
  2. @RequestMapping("/translate.do")  
  3. public class Test {  
  4.       
  5.     @RequestMapping(params = "method=excelExport")  
  6.          @Transactional(rollbackFor = Exception.class)  
  7.     public void excelExport(HttpServletRequest request, HttpServletResponse response){  
  8.         try {  
  9.             JSONArray ja = new JSONArray();//从数据库中查出  
  10.             response.reset();  
  11.             response.setContentType("application/octet-stream");  
  12.             response.addHeader("Content-Disposition","attachment;filename="+URLEncoder.encode("新建文件""UTF-8")+".xlsx");//excel文件名  
  13.             OutputStream out = response.getOutputStream();//new FileOutputStream("D:"+File.separator+"a.xlsx");//文件本地存储地址  
  14.             //创建一个新的excel  
  15.             XSSFWorkbook wb = new XSSFWorkbook();//XSSFWorkbook  
  16.             //创建sheet页  
  17.             XSSFSheet sheet = wb.createSheet("术语及解释");//sheet名  
  18.             //创建行数  
  19.             XSSFRow[] row = new XSSFRow[ja.size()+1];  
  20.             //设置第一行为头  
  21.             row[0] = sheet.createRow(0);  
  22.             for(int i=0;i<14;i++){  
  23.                 XSSFCell headerCell = row[0].createCell(i);//在第一行创建14列  
  24.                 headerCell.setCellValue(new XSSFRichTextString("分类"+i));//分别在14列插入数据  
  25.             }  
  26.             //第i行插入数据  
  27.             for (int i = 1; i < row.length; i++) {//从1开始,因为第一行已经设置过了  
  28.                 row[i] = sheet.createRow(i);  
  29.                 sheet.setDefaultColumnWidth(30);//设置列的长度  
  30.                 @SuppressWarnings("unchecked")  
  31.                 Map<String,Object> m = (Map<String,Object>)(ja.get(i-1));  
  32.                 XSSFCell[] headerCell = new XSSFCell[15];//15列  
  33.                 for(int j=0;j<15;j++){  
  34.                     headerCell[j] = row[i].createCell(j);  
  35.                     headerCell[j].setCellValue(new XSSFRichTextString((String)m.get("数据库里对应字段(key值)")));  
  36.                 }  
  37.             }  
  38.             wb.write(out);  
  39.             out.flush();  
  40.             out.close();  
  41.         } catch (Exception e) {  
  42.             //异常 e.printStackTrace();  
  43. throw new RuntimeException(new String());  
  44.         }  
  45.     }  
  46.       
  47.     @RequestMapping(params = "method=excelInput")  
  48.          @Transactional(rollbackFor = Exception.class)  
  49.     public void excelInput(HttpServletRequest request, HttpServletResponse response){  
  50.         try{  
  51.             //String filePath = request.getParameter("filePath");  
  52.             InputStream fis = request.getInputStream();;     
  53.             //创建工作薄  
  54.             HSSFWorkbook hwb = new HSSFWorkbook(new POIFSFileSystem(fis));     
  55.             //得到sheet  
  56.             for (int i = 0; i < hwb.getNumberOfSheets(); i++) {  
  57.                 System.out.println("1");  
  58.             }  
  59.             //XSSFSheet sheet = hwb.getSheetAt(0);     
  60.             OutputUtil.jsonArrOutPut(response, null);  
  61.         }catch (Exception e) {  
  62.                 OutputUtil.errorOutPut(response, JtmaConstants.SYSTEM_ERRCODE);//异常  
  63. throw new RuntimeException(new String());  
  64.         }  
  65.     }  
  66.       
  67. }  

关于文件上传下载建议用缓冲流来写,简单示例如下: 
Java代码   收藏代码
  1. @RequestMapping(params = "method=fileUpLoad")  
  2. //btnFile对应页面的name属性  
  3. public void fileUpLoad(@RequestParam MultipartFile[] btnFile, HttpServletRequest request, HttpServletResponse response){  
  4.     BufferedInputStream bis = null;  
  5.     BufferedOutputStream bos = null;  
  6.     try{  
  7.         //文件类型:btnFile[0].getContentType()  
  8.         //文件名称:btnFile[0].getName()  
  9.         //if(btnFile[0].getSize()>Integer.MAX_VALUE){//文件长度  
  10.         //  OutputUtil.jsonArrOutPut(response, JSONArray.fromObject("上传文件过大!"));  
  11.         //}  
  12.         String fileForCaseId = request.getParameter("fileForCaseId");  
  13.         InputStream is = btnFile[0].getInputStream();//多文件也适用,我这里就一个文件  
  14.         String filePath = Constants.FILE_ROOT_PATH+File.separator+fileForCaseId;  
  15.         File file = new File(filePath);  
  16.         if(!(file.exists())){  
  17.             file.mkdirs();//如果不存在该文件目录,则创建  
  18.         }/**else{//关于冗余文件的删除需再作详细考虑,因为涉及到还原操作 
  19.             String fileList[] = file.list(); 
  20.             for (int j = 0; j < fileList.length; j++) { 
  21.                 File delfile = new File(filePath + File.separator + fileList[j]);  
  22.                 delfile.delete(); 
  23.             } 
  24.         }*/  
  25.         File fullFilePath = new File(filePath+File.separator+btnFile[0].getOriginalFilename());//判断文件是否存在  
  26.         long fileSize = (long)btnFile[0].getSize();  
  27.         byte[] b = new byte[1024*1024*1];//缓冲区每次读1MB  
  28.         if(fileSize<=b.length){//连缓冲1M都达不到  
  29.             b = new byte[(int)fileSize];  
  30.         }  
  31.         int bLength = b.length;  
  32.         if(!(fullFilePath.exists())){  
  33.             bis = new BufferedInputStream(is);  
  34.             bos = new BufferedOutputStream(new FileOutputStream(fullFilePath,true));  
  35.             while(fileSize>0){  
  36.                 bis.read(b, 0, bLength);  
  37.                 bos.write(b, 0, bLength);  
  38.                 fileSize = fileSize - bLength;  
  39.             }  
  40.         }  
  41.         //PrintWriter printWriter = response.getWriter();    
  42.         //printWriter.write("<div id='hideForm'>1</div>");  
  43.         OutputUtil.jsonOutPut(response, null);  
  44.     }catch (Exception e) {  
  45.         /** 
  46.         try { 
  47.             PrintWriter printWriter = response.getWriter(); 
  48.             printWriter.write("<div id='hideForm'>0</div>");  
  49.         } catch (IOException e1) { 
  50.             OutputUtil.errorOutPut(response, "系统异常"); 
  51.         }  
  52.         */   
  53.         OutputUtil.errorOutPut(response, JtmaConstants.SYSTEM_ERRCODE);//异常  
  54.     }finally{  
  55.         try {  
  56.             if(bos!=null){  
  57.                 bos.close();  
  58.             }  
  59.             if(bis!=null){  
  60.                 bis.close();  
  61.             }  
  62.         } catch (IOException e) {  
  63.             OutputUtil.errorOutPut(response, JtmaConstants.SYSTEM_ERRCODE);//异常  
  64.         }  
  65.     }  
  66. }  

Java代码   收藏代码
  1. @RequestMapping(params = "method=fileDownLoad")  
  2. @Transactional(rollbackFor = Exception.class)  
  3. public void fileDownLoad(HttpServletRequest request, HttpServletResponse response){  
  4.     FileInputStream fos = null;  
  5.     ServletOutputStream sos = null;  
  6.     try{  
  7.         String caseId = request.getParameter("caseId");  
  8.         String fileName = URLDecoder.decode(request.getParameter("fileName"),"UTF-8");  
  9.         response.setHeader("Content-Disposition""attachment;filename=" + fileName);  
  10.         response.setContentType("application/octet-stream");               
  11.         response.setContentType("application/OCTET-STREAM;charset=UTF-8");  
  12.         byte b[] = new byte[1024*1024*1];//1M  
  13.         int read = 0;  
  14.         fos = new FileInputStream(new File(Constants.FILE_ROOT_PATH+File.separator+caseId+File.separator+fileName));   
  15.         sos = response.getOutputStream();  
  16.         while((read=fos.read(b))!=-1){  
  17.             sos.write(b,0,read);//每次写1M  
  18.         }  
  19.         //OutputUtil.jsonOutPut(response, null);  
  20.     }catch (Exception e) {  
  21.         throw new RuntimeException("");  
  22.     }finally{  
  23.         try {  
  24.             if(sos!=null){  
  25.                 sos.close();  
  26.             }  
  27.             if(fos!=null){  
  28.                 fos.close();  
  29.             }  
  30.         } catch (IOException e) {  
  31.             throw new RuntimeException("");  
  32.         }  
  33.     }  
  34. }  

关于邮件的发送,简单示例如下: 
Java代码   收藏代码
  1. 简单邮件发送:   
  2. Properties properties = new Properties();   
  3. //设置邮件服务器   
  4. properties.put("mail.smtp.host", SMTP_HOST);   
  5. //验证   
  6. properties.put("mail.smtp.auth""false");   
  7. //根据属性新建一个邮件会话   
  8. Session mailSession = Session.getInstance(properties);   
  9. mailSession.setDebug(true);   
  10. //建立消息对象   
  11. MimeMessage mailMessage = new MimeMessage(mailSession);   
  12. //发件人   
  13. mailMessage.setFrom(new InternetAddress(fromAddress));   
  14. //收件人   
  15. mailMessage.setRecipient(MimeMessage.RecipientType.TO, new InternetAddress(toAddress));   
  16. //主题   
  17. mailMessage.setSubject(title);   
  18. //内容   
  19. mailMessage.setText(message);   
  20. //发信时间   
  21. mailMessage.setSentDate(new Date());   
  22. mailMessage.setContent(message, "text/html;charset=gb2312" );   
  23. //存储信息   
  24. //mailMessage.saveChanges();   
  25. Transport trans = mailSession.getTransport("smtp");   
  26. //发送   
  27. trans.send(mailMessage);  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值