`

uploadify Jquery 上传文件插件

 
阅读更多

 

<%@ page contentType="text/html; charset=UTF-8"%>
<%
	String contextPath = request.getContextPath();
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Excel</title>
<link rel="stylesheet" type="text/css" href="<%=request.getContextPath()%>/jeasyui/themes/gray/easyui.css">
<link rel="stylesheet" type="text/css" href="<%=request.getContextPath()%>/jeasyui/themes/icon.css">
<link rel="stylesheet" type="text/css" href="<%=request.getContextPath()%>/jeasyui/demo/demo.css">
<link rel="stylesheet" type="text/css" href="<%=request.getContextPath()%>/uploadify/uploadify.css">
<script type="text/javascript" src="<%=request.getContextPath()%>/jeasyui/jquery-1.8.0.min.js"></script>
<script type="text/javascript" src="<%=request.getContextPath()%>/jeasyui/jquery.easyui.min.js"></script>
<script type="text/javascript" src="<%=request.getContextPath()%>/uploadify/jquery.uploadify.js"></script>
<script type="text/javascript" src="<%=request.getContextPath()%>/uploadify/jquery.uploadify.min.js"></script>
<script type="text/javascript" src="<%=request.getContextPath()%>/pages/excel/excel.js"></script>
<script type="text/javascript" src="<%=request.getContextPath()%>/js/util.js"></script>
<script type="text/javascript" src="<%=request.getContextPath()%>/jeasyui/jquery.easyui.min.js"></script>
<script type="text/javascript" src="<%=request.getContextPath()%>/jeasyui/locale/easyui-lang-en.js"></script>

</head>
<body>
 <div class="container">  
    <input type="file" id="file_upload"  name="fileName">
    <div  id="uploadfileQueue" style="width: 500px;">
    </div> 
 </div>
 <h3>导入文 件列表:</h3>  
 <table id="datagrid" class="easyui-datagrid"  style="width: 100%; height: 100%" data-options="width:800,height:500,idField:'KEYID',
                      iconCls:'icon-tip',striped: true,fitColumns:true,singleSelect:true,
                      maximized:true,remoteSort: false,rownumbers:true">
		<thead>
			<tr>
				<th data-options="field:'fileName',width:10">文件名</th>
				<th data-options="field:'editFile',width:10">编辑</th>
			</tr>
		</thead>
	</table>  
</body>
</html>

 

/*function a (){
	$('#file_upload').uploadify({
        auto:false, 
        //接受true or false两个值,当为true时选择文件后会自动上传;为false时只会把选择的文件增加进队列但不会上传,这时只能使用upload的方法触发上传。不设置auto时默认为true
        buttonClass: "some-class", 
        //设置上传按钮的class
        buttonCursor: 'hand',
        //设置鼠标移到按钮上的开状,接受两个值'hand'和'arrow'(手形和箭头)
        buttonImage: 'img/browse-btn.png', 
        //设置图片按钮的路径(当你的按钮是一张图片时)。如果使用默认的样式,你还可以创建一个鼠标悬停状态,但要把两种状态的图片放在一起,并且默认的放上面,悬停状态的放在下面(原文好难表达啊:you can create a hover state for the button by stacking the off state above the hover state in the image)。这只是一个比较便利的选项,最好的方法还是把图片写在CSS里面。
        buttonText: '<div>选择文件</div>',
        //设置按钮文字。值会被当作html渲染,所以也可以包含html标签
        checkExisting: '/uploadify/check-exists.php',
        //接受一个文件路径。此文件检查正要上传的文件名是否已经存在目标目录中。存在时返回1,不存在时返回0(应该主要是作为后台的判断吧),默认为false
        debug: false,
        //开启或关闭debug模式
        fileObjName:'filedata',
        //设置在后台脚本使用的文件名。举个例子,在php中,如果这个选项设置为'the_files',你可以使用$_FILES['the_files']存取这个已经上传的文件。
        fileSizeLimit:'100MB',
        //设置上传文件的容量最大值。这个值可以是一个数字或者字符串。如果是字符串,接受一个单位(B,KB,MB,GB)。如果是数字则默认单位为KB。设置为0时表示不限制
        fileTypeExts: '*.*',
        //设置允许上传的文件扩展名(也就是文件类型)。但手动键入文件名可以绕过这种级别的安全检查,所以你应该始终在服务端中检查文件类型。输入多个扩展名时用分号隔开('*.jpg;*.png;*.gif')
        fileTypeDesc: 'All Files',
        //可选文件的描述。这个值出现在文件浏览窗口中的文件类型下拉选项中。(chrome下不支持,会显示为'自定义文件',ie and firefox下可显示描述)
        //formData: {
        //    timestamp: '<?php echo $timestamp;?>',
        //    token: '<?php echo md5('unique_salt' . $timestamp);?>'
       // },
        //通过get或post上传文件时,此对象提供额外的数据。如果想动态设置这些值,必须在onUploadStartg事件中使用settings的方法设置。在后台脚本中使用 $_GET or $_POST arrays (PHP)存取这些值。看官网参考写法:http://www.uploadify.com/documentation/uploadify/formdata/
        height: 30,
        //设置按钮的高度(单位px),默认为30.(不要在值里写上单位,并且要求一个整数,width也一样)
        width: 120,
        //设置按钮宽度(单位px),默认120
        itemTemplate:false,
        //模板对象。给增加到上传队列中的每一项指定特殊的html模板。模板格式请看官网http://www.uploadify.com/documentation/uploadify/itemtemplate/
        method:'post',
        //提交上传文件的方法,接受post或get两个值,默认为post
        multi: false,
        //设置是否允许一次选择多个文件,true为允许,false不允许
        overrideEvents: [],
        //重写事件,接受事件名称的数组作为参数。所设置的事件将可以被用户重写覆盖
        preventCaching:true,
        //是否缓存swf文件。默认为true,会给swf的url地址设置一个随机数,这样它就不会被缓存。(有些浏览器缓存了swf文件就会触发不了里面的事件--by rainweb)
        progressData: 'percentage',
        //设置文件上传时显示数据,有‘percentage’ or ‘speed’两个参数(百分比和速度)
        queueID: false,
        //设置上传队列DOM元素的ID,上传的项目会增加进这个ID的DOM中。设置为false时则会自动生成队列DOM和ID。默认为false
        queueSizeLimit: 999,
        //设置每一次上传队列中的文件数量。注意并不是限制总的上传文件数量(那是uploadLimit).如果增加进队列中的文件数量超出这个值,将会触发onSelectError事件。默认值为999
        removeCompleted: true,
        //是否移除掉队列中已经完成上传的文件。false为不移除
        removeTimeout: 3,
        //设置上传完成后删除掉文件的延迟时间,默认为3秒。如果removeCompleted为false的话,就没意义了
        requeueErrors: false,
        //设置上传过程中因为出错导致上传失败的文件是否重新加入队列中上传
        successTimeout: 30,
        //设置文件上传后等待服务器响应的秒数,超出这个时间,将会被认为上传成功,默认为30秒
        swf: 'uploadify.swf',
        //swf的相对路径,必写项
        //uploader: 'uploadify.php'
        //服务器端脚本文件路径,必写项
        uploadLimit: 999
        //上传文件的数量。达到或超出这数量会触发onUploadError方法。默认999
    })
}*/

$(function() {
	fuleUpdate2(); // 页面初始化
	loadFileName();//读取文件生成列表

});

function fuleUpdate1() {
	setTimeout(//设置setTimeout解决谷歌崩溃问题
			function() {
				$('#file_upload')
						.uploadify(
								{
									'swf' : '../../uploadify/uploadify.swf',
									'cancelImage' : '../../uploadify/uploadify-cancel.png',
									'swf' : '../../uploadify/uploadify.swf',
									'expressInstall' : '../../uploadify/expressInstall.swf',
									'uploader' : 'http://localhost:8080/gisTest2/log/test/saveExcel.do',
									'buttonText' : '上传',
									'width' : 50,
									'height' : 20,
									auto : true,
									'onUploadSuccess' : function(file, data,
											response) {
										alert('successfully uploaded ' + ':'
												+ data);
										$(".rr_peitu")
												.css("overflow", "hidden")
												.html(
														"<img src=\"" + data
																+ "\" />");
									}
								});
			}, 10);
}

function fuleUpdate2() {
	$("#file_upload")
			.uploadify(
					{
						debug : false,
						auto : true,// 是否自动上传
						height : 30,
						buttonText : '请选择文件上传',
						buttonClass: "some-class", 
						cancelImage : '../../uploadify/uploadify-cancel.png',
						swf : '../../uploadify/uploadify.swf',
						expressInstall : '../../uploadify/expressInstall.swf',
						uploader : 'http://localhost:8080/gisTest2/log/test/saveExcel.do', // 后台处理上传文件的action
						width : 150, //设置buttonText 宽度
						multi : false,// 是否允许多个文件上传
						queueID : 'uploadfileQueue',
						fileObjName : 'fileName', // 与后台Action中file属性一样
						formData : { // 附带值
							'userid' : '111',
							'username' : 'tom',
							'rnd' : '111'
						},
						successTimeout : 99999,// 上传超时时间
						overrideEvents : [ 'onDialogClose' ],
						fileTypeDesc : '上传文件支持的文件格式:jpg,jpge,gif,png',
						fileTypeExts : '*.*',// *.jpg;*.jpge;*.gif;*.png
						queueSizeLimit : 3,//
						// simUploadLimit:1,//一次可以上传1个文件
						fileSizeLimit : '20MB',// 上传文件最大值
						// 返回一个错误,选择文件的时候触发
						onSelectError : function(file, errorCode, errorMsg) {
							switch (errorCode) {
							case -100:
								alert("上传的文件数量已经超出系统限制的"
										+ $('#file_upload').uploadify(
												'settings', 'queueSizeLimit')
										+ "个文件!");
								break;
							case -110:
								alert("文件 ["
										+ file.name
										+ "] 大小超出系统限制的"
										+ $('#file_upload').uploadify(
												'settings', 'fileSizeLimit')
										+ "大小!");
								break;
							case -120:
								alert("文件 [" + file.name + "] 大小异常!");
								break;
							case -130:
								alert("文件 [" + file.name + "] 类型不正确!");
								break;
							}
						},
						// 每次更新上载的文件的进展
						onUploadProgress : function(file, bytesUploaded,
								bytesTotal, totalBytesUploaded, totalBytesTotal) {
							// alert(bytesUploaded);
							// 有时候上传进度什么想自己个性化控制,可以利用这个方法
							// 使用方法见官方说明
						},
						// 检测FLASH失败调用
						onFallback : function() {
							alert("您未安装FLASH控件,无法上传图片!请安装FLASH控件后再试。");
						},
						// 上传到服务器,服务器返回相应信息到data里
						onUploadSuccess : function(file, data, response) {
							var fileNameAndPath = data.split(",");
							var phtml = "<p><a href='#' onlick=downLoad('"
									+ fileNameAndPath[1]
									+ "')>"
									+ fileNameAndPath[0]
									+ "</a><img alt='删除' src='../../uploadify/uploadify-cancel.png' onclick=delFile(this)></p>";
							if ($("#uploadfileQueue p").length == 0) {
								$("#uploadfileQueue").html(phtml);
							} else {
								$("#uploadfileQueue p:last").after(phtml);
							}
							loadFileName();
							// alert(data+"上传成功");
						},
						onSelect : function(file) {
							// alert(file.name);
						},
						removeCompleted : true,// 上传的文件进度条是否消失
						requeueErrors : false,
						removeTimeout : 2,// 进度条消失的时间,默认为3
						progressData : "percentage",// 显示上传的百分比
						onUploadError : function(file, errorCode, errorMsg,
								errorString, swfuploadifyQueue) {
							$("#dialog-message").html(errorString);
						},
						onError : function(event, queueID, fileObj) {
							alert("文件:" + fileObj.name + " 上传失败");
						}
					});
}

function delFile(obj){
  var s  = $(obj).parent().text();//上传文件的文件名
  $(obj).parent().remove();
}

function gridDelFile(index,row,obj){
	$('#datagrid').datagrid('selectRow',index);
	
	var row = $('#datagrid').datagrid('getSelected');
	if (row){
		//var json = JSON.stringify(row.fileName);
		$.ajax({
			type: 'POST',
			url: "http://localhost:8080/gisTest2/log/test/delFile.do",
			data: {"jsonStr":row.fileName},
			dataType: 'text',
			success: function(data) {
				if(data.res = 'true'){
					alert('删除成功');
				}else{
					alert("删除失败");
				}
				loadFileName();
			},
			error: function(XMLHttpRequest, textStatus, errorThrown) {
			}
		});
	}
	//var s = $("#datagrid thead:eq(1) tr:eq(1) th:nth-child(1)").html();
	//var th = $("#datagrid thead:eq(0)");
	//alert(row.fileName);
	 //var tr = $('#datagrid').find("tr:eq(1)"); 
	// var tr = th.find("tr:eq(0)");  
	// var tmpId = tr.find("th:eq(0)").text();  
	//alert(index+" "+tmpId);
}

function loadFileName(){
	$('#datagrid').datagrid({
		url:"http://localhost:8080/gisTest2/log/test/readFileName.do",
		striped: true,
		collapsible: true,
		remoteSort: false,
		fit: true,
		fitColumns: true,
		singleSelect: true,
		pageNumber: 1,
		nowrap:false,
		pageSize: 10,
		pagination: false,
		columns : [ [  {
			field : 'fileName',
			title : '文件名',
			width : 10,
			align:'left',
			formatter : function(value, row, index) {
				return row.fileName;
			}
		}, {
			field : 'editFile',
			title : '编辑',
			width : 10,
			align:'left',
			formatter : function(value, row, index) {
				var fname = row.fileName;
				var obj = row;
				return '<a href="#" onclick="gridDelFile('+index+',this)">删除</a>';
			}
		}
		] ],
		rownumbers: true,
		onLoadSuccess: function(data){
		}
	});
}

 

@Controller  
@RequestMapping("/log/test")  
public class TestController {
	
	@RequestMapping(value = "/getTableData.do", method = RequestMethod.POST /*,produces = "text/plain;charset=utf-8"*/)
	@ResponseBody
    public String getTableData(@RequestBody String reqJsonStr, HttpServletRequest request){
		try {
			System.out.println("Str:"+reqJsonStr);
			JSONArray  jsonArray = JSONArray.fromObject(request.getParameter("jsonStr"));
			String[] arr=new String[jsonArray.size()];  
			 for(int i=0;i<jsonArray.size();i++){
				    //arr[i]=jsonArray.getString(i);  
				    JSONObject jsonObject =  jsonArray.getJSONObject(i);
				   // System.out.println(arr[i]);
				    String msg = StringUtils.trimToNull(jsonObject.getString("msg"));
				    String info = StringUtils.trimToNull(jsonObject.getString("info"));
				    String url = StringUtils.trimToNull(jsonObject.getString("url"));
				    System.out.println(msg+"\t"+info+"\t"+url);
			 }
		     
		    return "0";
		} catch (Exception e) {
			e.printStackTrace();
		}
		return "0";
    }
	
	@RequestMapping(value = "/repExcel.do", method = RequestMethod.GET )
    public String  repExcel(HttpServletRequest request){
		return "pages/excel/excel";
/*		   ModelAndView modelAndView = new ModelAndView();  
	       modelAndView.addObject("name", "xxx");  
	       modelAndView.setViewName("/pages/excel/excel");  
	       return modelAndView; */
    }
	
	@RequestMapping(value = "/saveExcel.do", method = RequestMethod.POST )
    public void saveExcel(HttpServletRequest request,PrintWriter out){
		System.out.println("saveExcel");
		MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
		Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();  
		MultipartFile multipartFile =null;
		String fileName = null;
		for (Map.Entry<String, MultipartFile> set : fileMap.entrySet()) {
			String filekey = set.getKey();
			multipartFile = set.getValue();
		}
		fileName = this.storeIOc(multipartRequest, multipartFile);
		           
		out.print(fileName);
    }
	
	@RequestMapping(value = "/readFileName.do", method = RequestMethod.POST )
	public void readFileName(HttpServletRequest request,HttpServletResponse response,PrintWriter out) throws IOException{
		System.out.println("Acton readFileName.do");
		JSONObject json = new JSONObject();
		JSONArray jsonArray = new JSONArray();
		JSONObject jsonObject;
		
		try {
			File file = new File("D:\\文件上传");
			File[] listFile = file.listFiles();
			
			for(File f : listFile){
				jsonObject = new JSONObject();
				jsonObject.put("fileName", f.getName());
				jsonArray.add(jsonObject);
			}
			json.put("rows", jsonArray);
			RiaUtils.writeJsonText2Page(json.toString(), response);
		} catch (Exception e) {
			System.out.println();
			json.put("error", "error");
			jsonArray.add(json);
			RiaUtils.writeJsonText2Page(json.toString(), response);
		}
	}
	
	@RequestMapping(value = "/delFile.do", method = RequestMethod.POST )
	public void delFile(HttpServletRequest request , HttpServletResponse response) throws IOException{
		String str = request.getParameter("jsonStr");
		System.out.println("Del" + str);
		boolean tag = false;
		File file = new File("D:\\文件上传" + File.separator + str);
		// 路径为文件且不为空则进行删除
		if (file.isFile() && file.exists()) {
			tag = file.delete();
		} 
		
		JSONObject json = new JSONObject();
		json.put("res", tag);
		RiaUtils.writeJsonText2Page(json.toString(), response);
	}
	
	
	private String storeIOc(HttpServletRequest request, MultipartFile file) {
		String realPath = request.getSession().getServletContext().getRealPath("dream_ioc");
		if (file == null) {
			return "dream_ioc" + File.separator + "headpic.jpg";
		}
		String fileName = "";
		String logImageName = "";
		if (file.isEmpty()) {
			System.out.println("文件未上传");
		} else {
			String _fileName = file.getOriginalFilename();
			String suffix = _fileName.substring(_fileName.lastIndexOf("."));
			// /**使用UUID生成文件名称**/
			logImageName = UUID.randomUUID().toString() + suffix;

			fileName = "D:\\文件上传" + File.separator + logImageName;
			//fileName = "D:\\文件上传" + File.separator + _fileName;
			System.out.println(fileName+" "+_fileName); //_fileName 原始文件名
			File restore = new File(fileName);
			try {
				file.transferTo(restore);
			} catch (Exception e) {
				throw new RuntimeException(e);
			}
		}
		//return "D:\\文件上传" + File.separator + logImageName; 返回服务器存放路径
		return file.getOriginalFilename(); //返回原始文件名
	}
	
	public static void main(String[] args){
		File file = new File("D:\\文件上传");
		File[] listFile = file.listFiles();
		
		for(File f : listFile){
			System.out.println(f.getName());
		}
	}
}

 

分享到:
评论

相关推荐

    jquery文件上传插件 jquery.uploadify.js

    《jQuery文件上传插件jQuery.uploadify.js:跨越浏览器限制的智能解决方案》 在Web开发中,文件上传功能是一项常见的需求,而jQuery.uploadify.js是一款高效且用户友好的文件上传插件,尤其对于需要兼容多种浏览器...

    uploadify jquery上传图片插件实例

    首先官方的实例可能看不到,反正我是访问不了的。 接着网上也有很多实例,有的也给出了代码,的确,不方便,因为在复制或者新建文件时还是很麻烦...可以本地列出列表,然后选择性上传,但是可能需要改动200k的上传限制

    jquery uploadify插件多文件上传(带代码)

    接着,我们需要为需要上传文件的元素(通常是`&lt;input type="file"&gt;`)添加Uploadify插件。以下是一个基本的配置示例: ```javascript $(document).ready(function() { $("#fileInput").uploadify({ 'swf': 'path/...

    jsp调用uploadify文件上传插件实现文件快速上传.rar

    jsp使用uploadify插件实现文件上传的示例,测试时将uploadify 直接导入myeclipse就能用了。  uploadify是一个与jquery和flash结合实现的上传程序,界面挺漂亮,用起来也方便,不过浏览器需要安装有Flash插件,好像...

    详解jQuery uploadify文件上传插件的使用方法

    本文主要介绍了jQuery uploadify文件上传插件的使用方法,uploadify这个插件是基于js里面的jquery库写的。结合了ajax和flash,实现了这个多线程上传的功能。具有很好的参考价值,需要的朋友一起来看下吧

    uploadify多文件上传插件

    Uploadify是一款广受欢迎的jQuery插件,主要用于实现网页上的多文件批量上传功能。这款插件以其易用性、高效性和自定义性强而受到开发者们的喜爱。在深入理解Uploadify之前,我们先要明白jQuery的基本概念。jQuery是...

    jquery文件上传插件 jquery.uploadify.js 不支持IE10现在经过修改

    在IT行业中,jQuery Uploadify.js是一款非常流行的前端文件上传插件,它允许用户通过异步方式上传文件到服务器,提供了一种友好的用户体验。然而,随着浏览器版本的更新,一些较旧的插件可能不再兼容新的浏览器,...

    Uploadify-3.2.1 jQuery文件上传插件

    Uploadify是一款基于jQuery的文件上传插件,版本为3.2.1,它极大地简化了在Web应用中实现异步无刷新多文件上传的过程。这个插件的核心特性是通过Ajax技术实现在后台处理文件上传,使得用户在上传过程中无需等待页面...

    .net jQuery上传插件Uploadify 文件 上传 实例,简单易懂

    在.NET开发中,文件上传是一项常见的任务,而jQuery Uploadify插件则为这一过程提供了便捷的解决方案。Uploadify是一款基于JavaScript和Flash的文件上传组件,它允许用户通过拖拽或选择文件的方式,实现多文件同时...

    JQuery uploadify 实现批量上传例子

    'queueSizeLimit': 5, // 最大上传文件数量 'simUploadLimit': 3, // 同时上传的最大文件数 'onSelectOnce': function(event, data) { // 用户选完一批文件后的回调 }, 'onUploadSuccess': function(file, ...

    批量上传文件(asp.net C#,Jquery,uploadify)

    使用Jquery的上传插件Uploadify,提供upload.ashx的C#源码和VB源码,方便直接使用,因为不会VB,所以只使用C#做了上传的示例。在web.config中配置上传的文件夹路径! 示例的主要功能是创建一个新的文件夹并将文件...

    JQUERY上传文件插件

    **jQuery上传文件插件**是一种基于JavaScript库jQuery的实用工具,用于在网页上实现便捷的文件上传功能。这种插件通常包含丰富的自定义选项和事件处理,使得文件上传过程更加用户友好,支持Ajax异步上传,提高用户...

    spring mvc uploadify上传文件

    Uploadify是一款基于jQuery的文件上传插件,它允许用户通过异步方式上传多个文件,并提供进度条显示、预览、取消等高级功能。使用uploadify,开发者可以自定义上传样式,设置上传参数,如文件类型限制、上传大小限制...

    Uploadify HTML5 版 / Jquery上传插件 全JS

    Uploadify是一款广受欢迎的jQuery上传插件,尤其在HTML5版本推出后,它极大地提升了文件上传的用户体验。这款插件允许用户实现多文件选择、进度条显示、预览功能,以及自定义上传事件处理,使得文件上传变得既简单又...

    uploadify异步文件上传插件

    通过创建FormData对象,将待上传文件添加到其中,然后通过XMLHttpRequest的FormData发送到服务器,服务器接收到请求后处理文件,最后返回处理结果。 2. **基本使用步骤**: - 引入必要的JS和CSS文件:Uploadify...

    jquery上传插件uploadify+php完美实现强大的文件上传功能实例+程序

    本实例将探讨如何利用jQuery上传插件Uploadify与PHP技术来构建一个强大的文件上传系统。Uploadify是一款广泛使用的前端插件,它使得文件上传过程更加直观、用户友好,并且支持批量上传和自定义样式,极大地提升了...

    使用jquery的uploadify插件实现文件上传

    这里`script`属性指定了服务器端处理文件的Action,`folder`是上传文件的目标目录,`fileExt`和`fileDesc`用于限制可选文件类型。 4. **事件处理**:uploadify插件提供了丰富的事件,如'onSelect'(文件被选中)、...

    uploadify多文件上传例子代码

    首先,uploadify是一个基于jQuery的插件,它的核心功能是通过Flash或HTML5技术提供了一种友好的用户界面,让用户能够选择并上传多个文件。在JavaScript端,uploadify提供了一系列的事件和配置选项,允许开发者自定义...

    MVC4下对话框中使用Uploadify上传多个文件

    在本文中,我们将深入探讨如何在ASP.NET MVC4框架下,利用JQuery Dialog插件创建一个弹出对话框,并在其中集成Uploadify组件实现多文件上传功能。这将涉及前端JavaScript库、后端C#处理逻辑以及数据库交互,旨在提供...

Global site tag (gtag.js) - Google Analytics