javaee论坛
金科官网
关闭此广告

普通会员

1

帖子

0

回复

8

积分

楼主
发表于 2017-10-17 01:44:14 | 查看: 290 | 回复: 0

实训项目展示:

为大家简单介绍一个实训项目演示,该项目是我们小团队历时一个多礼拜共同努力的成果

开发环境+开发工具:Eclipse+Mysql+tomcat7.0+jdk1.7+svn+junit+maven4+redis+mongodb

项目用到的框架:Spring+SpringMvc+mybatis+bootstrap+shiro+activiti

项目介绍:

    该项目为网上云课堂的运营中心管理项目,主要用于对云课堂后台的管理,分为以下模块:如下模块图

01.png

接下来显示的是首页:

000.png

首页采用的是highchar报表展示的是用户对广告视频和广告图片的一个点击量的展示,通过highchar我们可以很直观的看到用户对广告的关注度。

接下来就是我们的轮播图的首页推广:如下所示:

0011.bmp

 推广模块主要用到了redis缓存服务器,首先将需要推广的数据从数据库中查询出来,选择要推广的内容,点击推广就会出现推广的预览样式,点击保存后将数据存储到redis服务器中,因为推广数据属于热数据,为了提高用户的体验度我们将要推广的数据放到redis中,这样能更好的做到,快速的查询和实时的更新提高了效率,主要用到的代码:

        @Resource(name="shardedJedisPool")

private ShardedJedisPool shardedJedisPool;

        

        @RequestMapping("saveRedisImg")

public void saveRedisImg(HttpServletRequest request){

ShardedJedis jedis = shardedJedisPool.getResource();

List<Slideshow> list = (List<Slideshow>) request.getSession().getAttribute("imgList");

jedis.del("indexImg");

for (Slideshow slideshow2 : list) {

jedis.lpush("indexImg", slideshow2.getLbtUrl().toString());

}

}

用户管理模块:

0001.png

用户模块主要功能是用户的修改功能,用户修改信息需要向后台管理人员发送短信或邮件进行确认修改,里面我们添加了发送邮件和发送短信功能,主要代码如下:

    

/**

* 验证码生成工具类

* @author 

*/

   //计算并获取checkSum

   public static String getCheckSum(String appSecret,String nonce,String curTime){

       return encode("SHA",appSecret+nonce+curTime);

   }


   private static String encode(String algorithm,String value){

       if(value==null){

           return null;

       }


       try {

           MessageDigest messageDigest=MessageDigest.getInstance(algorithm);

           messageDigest.update(value.getBytes());

           return getFormattedText(messageDigest.digest());

       } catch (Exception e) {

           throw new RuntimeException(e);

       }

   }


   private static String getFormattedText(byte[] bytes){

       int len=bytes.length;

       StringBuilder sb=new StringBuilder(len*2);

       for(int $i=0;$i<len;$i++){

           sb.append(HEX_DIGITS[(bytes[$i]>>4)&0x0f]);

           sb.append(HEX_DIGITS[bytes[$i]&0x0f]);

       }

       return sb.toString();

   }


   private static final char[] HEX_DIGITS={'0','1','2','3','4','5','6',

           '7','8','9','a','b','c','d','e','f'};


}

public class MobileMessageCheck {

private static final String SERVER_URL="https://api.netease.im/sms/verifycode.action";//校验验证码的请求路径URL

    private static final String APP_KEY="c94db88c55f3e5b3923f21bf2975481d";//账号

    private static final String APP_SECRET="a30f15a514da";//密钥

    private static final String NONCE="123456";//随机数


    public static String checkMsg(String phone,String sum) throws IOException {

        CloseableHttpClient httpclient = HttpClients.createDefault();

        HttpPost post = new HttpPost(SERVER_URL);


        String curTime=String.valueOf((new Date().getTime()/1000L));

        String checkSum=CheckSumBuilder.getCheckSum(APP_SECRET,NONCE,curTime);


        //设置请求的header

        post.addHeader("AppKey",APP_KEY);

        post.addHeader("Nonce",NONCE);

        post.addHeader("CurTime",curTime);

        post.addHeader("CheckSum",checkSum);

        post.addHeader("Content-Type","application/x-www-form-urlencoded;charset=utf-8");


        //设置请求参数

        List<NameValuePair> nameValuePairs =new ArrayList<>();

        nameValuePairs.add(new BasicNameValuePair("mobile",phone));

        nameValuePairs.add(new BasicNameValuePair("code",sum));

        

        post.setEntity(new UrlEncodedFormEntity(nameValuePairs,"utf-8"));


        //执行请求

        HttpResponse response=httpclient.execute(post);

        String responseEntity= EntityUtils.toString(response.getEntity(),"utf-8");


        //判断是否发送成功,发送成功返回true

        String code= JSON.parseObject(responseEntity).getString("code");

        if (code.equals("200")){

            return "success";

        }

        return "error";

    }

}

public class MobileMessageSend {

private static final String SERVER_URL="https://api.netease.im/sms/sendcode.action";//发送验证码的请求路径URL

    private static final String APP_KEY="c94db88c55f3e5b3923f21bf2975481d";//网易云信分配的账号

    private static final String APP_SECRET="a30f15a514da";//网易云信分配的密钥

    private static final String MOULD_ID="3094043";//模板ID

    private static final String NONCE="123456";//随机数


    public static String sendMsg(String phone) throws IOException {

        CloseableHttpClient httpclient = HttpClients.createDefault();

        HttpPost post = new HttpPost(SERVER_URL);


        String curTime=String.valueOf((new Date().getTime()/1000L));

        String checkSum=CheckSumBuilder.getCheckSum(APP_SECRET,NONCE,curTime);


        //设置请求的header

        post.addHeader("AppKey",APP_KEY);

        post.addHeader("Nonce",NONCE);

        post.addHeader("CurTime",curTime);

        post.addHeader("CheckSum",checkSum);

        post.addHeader("Content-Type","application/x-www-form-urlencoded;charset=utf-8");


        //设置请求参数

        List<NameValuePair> nameValuePairs =new ArrayList<>();

        nameValuePairs.add(new BasicNameValuePair("mobile",phone));

        nameValuePairs.add(new BasicNameValuePair("templateid",MOULD_ID));

        post.setEntity(new UrlEncodedFormEntity(nameValuePairs,"utf-8"));


        //执行请求

        HttpResponse response=httpclient.execute(post);

        String responseEntity= EntityUtils.toString(response.getEntity(),"utf-8");


        //判断是否发送成功,发送成功返回true

        String code= JSON.parseObject(responseEntity).getString("code");

        if (code.equals("200")){

            return "success";

        }

        return "error";

    }

}

权限管理:如下

333.png

222.png

权限管理用了五张表去实现,用户表,角色表,用户角色中间表,权限表,角色权限中间表,通过查询用户给用户赋相应的角色,然后通过角色赋角色相应的权限,实现了不同用户拥有不同的权限,这三个部分相互依存,密不可分,要实现完善的权限管理体系,必须考虑到每一个环节可行性与复杂程度甚至执行效率。

三级目录管理:如下图

444.png

三级目录实现:

1.点击一级目录展示二级目录,2.点击二级目录实现展开三级目录效果,3.可以对目录进项操作管理,4.每级目录都有对应的增三改查功能,相互之间通过中间表关联,其中删除操作删除的是中间表,通过中间表实现了个级目录之间的关联和去除关联。



审核管理模块:如下图

555.png


审核模块我们采用了简单的activiti工作流,初步实现了以个简单的用户注册审核流程,流程图如下

1>     流程图(画法)

2>     简单的流程实现

3>     排他网关的实现(表达式)

4>     个人任务指定的实现(三种)

Regiter.png


工作流的实现首先我们要在eclipse中下载安装activiti,进行配置需要在spring配置文件中加入

<!-- 加载ProcessEngineConfiguration -->

    <bean id="processEngineConfiguration"  

        class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">  

        <property name="dataSource" ref="dataSource" />  

        <property name="databaseType" value="mysql"/>  

        <property name="databaseSchemaUpdate" value="true" />  

        <property name="jobExecutorActivate" value="false" />  

    </bean>  

      

    <bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean">  

        <property name="processEngineConfiguration" ref="processEngineConfiguration" />  

    </bean>  

        <!-- 生成流程图的字体 -->

        <!-- <property name="activityFontName" value="微软雅黑"/>

        <property name="labelFontName" value="微软雅黑"/>

        <property name="processDefinitionCacheLimit" value="10"/> -->

        

    <bean id="repositoryService" factory-bean="processEngine" factory-method="getRepositoryService"/>

    <bean id="runtimeService" factory-bean="processEngine" factory-method="getRuntimeService"/>

    <bean id="formService" factory-bean="processEngine" factory-method="getFormService"/>

    <bean id="identityService" factory-bean="processEngine" factory-method="getIdentityService"/>

    <bean id="taskService" factory-bean="processEngine" factory-method="getTaskService"/>

    <bean id="historyService" factory-bean="processEngine" factory-method="getHistoryService"/>

    <bean id="managementService" factory-bean="processEngine" factory-method="getManagementService"/>

pom.xml文件中需要添加

    <dependency>  

        <groupId>org.activiti</groupId>  

        <artifactId>activiti-engine</artifactId>  

        <version>5.15.1</version>  

    </dependency>  

    <dependency>  

        <groupId>org.activiti</groupId>  

        <artifactId>activiti-spring</artifactId>  

        <version>5.15.1</version>  

    </dependency>  

    <dependency>  

            <groupId>org.activiti</groupId>  

            <artifactId>activiti-bpmn-model</artifactId>  

            <version>5.15.1</version>  

        </dependency>  

        <dependency>  

            <groupId>org.activiti</groupId>  

            <artifactId>activiti-bpmn-converter</artifactId>  

            <version>5.15.1</version>  

        </dependency>  

        <dependency>  

            <groupId>org.activiti</groupId>  

            <artifactId>activiti-process-validation</artifactId>  

            <version>5.15.1</version>  

        </dependency>  

<dependency>  

            <groupId>commons-io</groupId>  

            <artifactId>commons-io</artifactId>  

            <version>2.4</version>  

        </dependency> 

配置好配置文件后通过如下代码进行流程处理:

        @ResponseBody

public void applyProcess(UserTwo user,HttpServletRequest request){

//发布流程

String uuid = UUID.randomUUID().toString();

applyService.reposityProcess(uuid);

//开启流程

String startProcess = applyService.startProcess(uuid);

//添加数据到业务表t_login_record

LoginRecord loginRecord = new LoginRecord();

loginRecord.setCreateDate(new Date());

loginRecord.setLoginId(user.getUserId());

loginRecord.setProcessId(startProcess);

loginRecord.setStatus(1);//1表示审核中

loginRecord.setTenantId(uuid);

loginRecord.setUserId(user.getUserId());

userService.addRecord(loginRecord);

//修改账号中的流程状态(userProcessStatus=1)

user.setUserStatus(1);

userService.updateUserStatus(user);

//完成当前任务

applyService.startTask(uuid);

}

/**

* 查看自己的流程审核情况

*/

@RequestMapping("queryPersonalProcess")

@ResponseBody

public JSONObject queryPersonalProcess(HttpServletRequest request){

User deng = (User) request.getSession().getAttribute("gdsLogin");

Integer userId = deng.getUserId();

List<LoginRecord> list = applyService.queryPersonalProcess();

JSONObject jsonStr = new JSONObject();

jsonStr.put("rows", list);

jsonStr.put("total", list.size());

return jsonStr;

}

//审批人查询自己的任务

@RequestMapping("MyApplyProcess")

@ResponseBody

public JSONObject MyApplyProcess(HttpServletRequest request){

HttpSession session = request.getSession();

User user = (User) session.getAttribute("gdsLogin");

//查询本人的任务列表

List<Task> list = applyService.queryMyApplyProcess(user.getUserId());

List<LoginRecord> listArr = new ArrayList<>();

for (Task task : list) {

String tenantId = task.getTenantId();

LoginRecord loginRecord = applyService.queryRecordByTenantId(tenantId);

listArr.add(loginRecord);

}

System.out.println(listArr);

JSONObject jsonObj = new JSONObject();

jsonObj.put("rows", listArr);

jsonObj.put("total", listArr.size());

return jsonObj;

}

//审批人审核流程

@RequestMapping("applyProcess")

@ResponseBody

public void applyProcess(String remark,Integer num,String tenantId,HttpServletRequest request){

//查询当前的用户

HttpSession session = request.getSession();

User user = (User) session.getAttribute("gdsLogin");

Task task = applyService.applyProcess(remark,num,tenantId,user.getUserId());

//通过tenantId 获取业务表

LoginRecord loginRecord = applyService.queryRecordByTenantId(tenantId);

//获取登录注册用户的对象

UserTwo user1 = new UserTwo();

user1.setUserId(loginRecord.getUserId());

if(num==2){

//驳回账号修改状态

loginRecord.setStatus(4);

applyService.updateStatus(loginRecord);

//驳回是修改

//能够登录的状态为4

user1.setUserStatus(3);

userService.updateUserStatus(user1);

}else if(num==1){

if(task==null){

loginRecord.setStatus(3);

applyService.updateStatus(loginRecord);

//能够登录的状态为2

user1.setUserStatus(2);

userService.updateUserStatus(user1);

}

}

}

@RequestMapping("myHistoryProcess")

@ResponseBody

public JSONObject myHistoryProcess(String processId){

List list = applyService.myHistoryProcess(processId);

JSONObject jsonStr = new JSONObject();

jsonStr.put("rows", list);

jsonStr.put("total", list.size());

return jsonStr;

}

订单管理模块,如下图:

666.png

用户订单管理存储在redis中,当用户下单后订单模板会生成相应的订单,用户提交后数据会储存到redis里随时对订单进行处理里面主要应用到的重要代码:

        @Override

public void saveOrder(HashMap<String, String> map) {

Jedis jedis = new Jedis("192.168.20.128", 6379);

jedis.auth("123456");

Long id= jedis.incr("order_ID_Sequenc");

map.put("order_id", id+"");

jedis.hmset("order_"+id, map);

jedis.lpush("order_id_List", id+"");

}

        

        @Override

public String queryOrder(Integer startIndex, Integer endIndex) {

Jedis jedis = new Jedis("192.168.20.128", 6379);

jedis.auth("123456");

Long count= jedis.llen("Order_id_List");

List<String> lrange = jedis.lrange("Order_id_List", startIndex, endIndex);

List<Map> list=new ArrayList<>();

for (String id : lrange) {

Map<String, String> hgetAll = jedis.hgetAll("Order_"+id);

hgetAll.put("Order_id", id);

list.add(hgetAll);

}

JSONObject json=new JSONObject();

json.put("total", count);

json.put("rows", list);

return json.toString();

}

微专业模块,如下图:

777.png

微专业模块主要内容和功能如下

1.微专业类型表   自关联  (类型名称, 类型标题 ,类型url )

2.微专业类型明细表(类型介绍,类型介绍图片,类型介绍视频,类型负责人,类型讲师)  对应系列课程

微专业的二级目录与上面介绍的三级目录差不多一样同样是点击微专业展开可以获取对应相关专业类型明细表,如下图:

888.png


名师推广模块,如下图:

999.png


名师推广模块与轮播推广相差不多,都是作为推广的模块去做,数据都是存在redis中


论坛模块管理,论坛主要是对用户对讲师和一些课程的互动评论,后台对其做出了相应的管理,将一些不良的不符合的评论进行管理,用户只有评论和追加评论的权限,讲师则有回复权限,后台会有相应的一个管理,评论我们存在mongodb中,相应的代码:

private MongoClient client = new MongoClient("192.168.74.128",27017);

@RequestMapping("queryForumBymentinfo")

@ResponseBody

public String queryForumBymentinfo(Integer cid,Integer mid , Integer pageSize,Integer start , String name) throws         ParseException{

MongoDatabase database = client.getDatabase("1703c"); //获取空间名

StringBuffer sb = new StringBuffer();

sb.append("Forum"+mid+"_"+cid);

MongoCollection<Document> table = database.getCollection(sb.toString()); //获取表

/**

*   mongoDB  时间差 8小时   将我们的时间设置标准时区

*/

SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

format.setCalendar(new GregorianCalendar(new SimpleTimeZone(0, "GMT")));

//总条件

Document ifDocument=new Document();

if(StringUtils.isNotEmpty(name)){

Pattern compile = Pattern.compile("^.*"+name+".*$",Pattern.CASE_INSENSITIVE);

ifDocument.put("forum_name", compile);

}

   FindIterable<Document> limit = table.find(ifDocument).skip(start).limit(pageSize);

long count = table.count(); //获取总条数

MongoCursor<Document> iterator = limit.iterator(); //迭代器

List<Map> list = new ArrayList<Map>();//定义一个用来存放map的集合

while (iterator.hasNext()) { //迭代循环

Document next = (Document) iterator.next();

Map<String,Object> map = new HashMap<String,Object>(); //定义用来存放数据的map

map.put("forumId", next.getString("forum_id"));

map.put("forumName", next.getString("forum_name"));

map.put("forumRank", next.getInteger("forum_rank"));

map.put("forumComment", next.getString("forum_comment"));

map.put("forumDate",format.format(next.getDate("forum_date")));

list.add(map);

}

JSONObject josn = new JSONObject(); //定义一个json对象用来返回到前台

josn.put("total",count);

josn.put("rows", list);

return JSON.toJSONString(josn);

}

广告管理,如下图:

3366.png

广告管理采用了批量添加,批量修改,批量删除的功能,方便了操作的,批量的操作实现主要是做好前台的传值操作,我们将所有的数据放入div中每次通过div的追加实现了批量,表单通过拼字符串去实现如下代码:

<script type="text/javascript">

function addAgain(){

var num = $("[name='addList']").length;

var strVar = "";

    strVar += "<div name=\"addList\">\n";

    strVar += " <table >\n";

    strVar += " <tr>\n";

    strVar += " <td>广告名称:<\/td>\n";

    strVar += " <td>\n";

    strVar += " <input class=\"easyui-validatebox\"     name=\"list["+num+"].advName\"   data-options=\"required:true,missingMessage:'不能为空'\" />\n";

    strVar += " <\/td>\n";

    strVar += " <\/tr>\n";

    strVar += " \n";

    strVar += " <tr>\n";

    strVar += " <td  > 广告介绍:<\/td>\n";

    strVar += " <td>\n";

    strVar += " <textarea class=\"easyui-kindeditor\"  name=\"list["+num+"].advIntro\" ><\/textarea>\n";

    strVar += " <\/td>\n";

    strVar += " <\/tr>\n";

    strVar += " \n";

    strVar += " <!--文件上传 -->\n";

    strVar += " <input type=\"hidden\"  name=\"list["+num+"].advUrl\" id=\"imgUrl"+num+"\">\n";

    strVar += " <input id=\"file_upload"+num+"\" type=\"file\" />\n";

    strVar += " <p>\n";

    strVar += " <a class=\"btn btn-success\" data-options=\"iconCls:'icon-ok'\"\n";

    strVar += " href=\"javascript:$('#file_upload"+num+"').uploadify('upload', '*')\">开始上传所有任务<\/a>\n";

    strVar += " <a class=\"btn btn-warning\" data-options=\"iconCls:'icon-lock'\"\n";

    strVar += " href=\"javascript:$('#file_upload"+num+"').uploadify('stopa')\">停止上传<\/a>\n";

    strVar += " <a class=\"btn btn-success\" data-options=\"iconCls:'icon-ok'\"\n";

    strVar += " href=\"javascript:$('#file_upload"+num+"').uploadify('upload')\">上传<\/a>\n";

    strVar += " <a class=\"btn btn-warning\" data-options=\"iconCls:'icon-lock'\"\n";

    strVar += " href=\"javascript:$('#file_upload"+num+"').uploadify('cancel')\">取消上传<\/a>\n";

    strVar += " <\/p>\n";

    strVar += " <!-- 文件序列的地方  -->\n";

    strVar += " <div id=\"filequence"+num+"\">\n";

    strVar += " <\/div>\n";

    strVar += " <div id=\"imgQuence"+num+"\">\n";

    strVar += " <\/div>\n";

    strVar += " \n";

    strVar += " <\/table>\n";

    strVar += " <\/div>\n";

    strVar += "<script type=\"text/javascript\">\n";

    strVar += "$(\"#file_upload"+num+"\").uploadify({\n";

    strVar += " 'swf'     : '${pageContext.request.contextPath}/js/uploadify/privateUpload/uploadify.swf',//按钮的动画\n";

    strVar += " 'uploader': '${pageContext.request.contextPath}/adv/buttonimgUploadUser.action',  // 后台请求路径\n";

    strVar += " 'cancelImg': 'image/uploadify', //uploaddify 图片\n";

    strVar += " 'queueID' :'filequence"+num+"',  //  存放序列的地方\n";

    strVar += " 'method'  : 'post', \n";

    strVar += " 'fileObjName' : 'advUrl',     //和后台的Action 属性驱动名字一样\n";

    strVar += " 'sizeLimit':30,\n";

    strVar += " 'progressData' :'percentage', //  设置上传进度显示方式,percentage显示上传百分比,speed显示上传速度\n";

    strVar += " 'auto':false,   //是否自动  上传\n";

    strVar += " 'multi': false,  //是否选择多个\n";

    strVar += " 'removeCompleted' : true,// 上传完是否自动删除任务\n";

    strVar += " 'fileSizeLimit': 0, // \"4MB\"  写0的话就是对 他不做限制\n";

    strVar += " 'buttonText' :  '请选择',\n";

    strVar += " 'buttonCursor': 'head', // 光标的样子\n";

    strVar += " 'fileTypeDesc' : 'mp4/avi/kux', // 你得告知  上传者    可以上传  什么类型的吧  与下面的那个属性连用\n";

    strVar += " 'fileTypeExts' : '*.gif;*.bmp;*.mp4;*.jpg;*.wmv;*.flv',//  告诉 uploadify可以上传  什么类型的\n";

    strVar += " 'uploadLimit': 1, //设置   上传时的上传文件数       超过就会触发 on\n";

    strVar += " //'onSelectError':uploadErrorMsg,\n";

    strVar += " 'onUploadSuccess': function (file,data,response){    //  上传成功后   将信息  给指定的位置\n";

    strVar += " //var fileData= eval(\"(\"+data+\")\");    //   字符串  转换成对象\n";

    strVar += " $(\"#imgUrl"+num+"\").val(data);\n";

    strVar += " var mark = data.indexOf(\".\");\n";

    strVar += " var uri = data.substring(mark);\n";

    strVar += " if (uri == \".mp4\") {\n";

    strVar += " $(\"#imgQuence"+num+"\").html(\n";

    strVar += " \"<br><br><video width='200' controls><source src='<%=request.getContextPath()%>\"\n";

    strVar += " + data + \"' type='video/mp4'><\/video>\");\n";

    strVar += " } else {\n";

    strVar += " $(\"#imgQuence"+num+"\").html(\n";

    strVar += " \"<br><br><img width='200' src='<%=request.getContextPath()%>\" + data + \"' >\");\n";

    strVar += " }\n";

    strVar += " },\n";

    strVar += " 'onUploadError' :function (file, errorCode, errorMsg, errorString){\n";

    strVar += " alert(\"只能上传一个\"); \n";

    strVar += " },\n";

    strVar += "\n";

    strVar += "}); \n";

    strVar += "<\/script>\n";

    

$("#addFood").append(strVar);

$.parser.parse($('#addFood').parent());

}

以上是我对项目的一个简单的介绍,后期有的功能还会继续去完善,通过做这个项目,大家都对ssm框架又有了一个熟悉的程度,对mysql+mongodb+redis数据库的操作也加深了练习,组员之间的分工合作更加的默契,相互之间在遇到问题时,从讨论中都有了不同的收获,

同时每个人都有自己单独的模块,在独立开发上也有了锻炼,再次也感谢老师的耐心指导,和所有组员的共同努力!


                                                                                -------金科教育,联系电话:010-8044-3291



                                                                                                                                                     -------金科教育,联系电话:010-8044-3291

普通会员

0

帖子

2

回复

8

积分
沙发
发表于 2017-10-17 11:08:44

写的很实用啊 大大解决了我的问题 !!!

普通会员

0

帖子

2

回复

8

积分
板凳
发表于 2017-10-17 11:09:50

批量操作这块 找了好久 终于找到了!!

普通会员

0

帖子

1

回复

2

积分
地板
发表于 2017-10-18 08:39:53

666666666666666666666666666666666666666666666

普通会员

1

帖子

2

回复

2

积分
4#
发表于 2017-10-18 08:40:08

很六,本人见过其项目演示,但是在我之下

普通会员

0

帖子

1

回复

0

积分
5#
发表于 2017-11-02 09:39:42

6666666666666666666666666666

您需要登录后才可以回帖 登录 | 立即注册

技术链接: csdneye51cto

技术支持 金科教育 V1.0 © 2016-2017

 京ICP备17040661号-2