HRM项目-10

一 页面静态化消息分发 *****

1.1 生成者-PageService

**pom**
!-- 通过公共rabbitmq的模块引入mq的jar包-->
   <dependency>
       <groupId>cn.itsource</groupId>
       <artifactId>hrm-basic-rabbitmq</artifactId>
       <version>1.0-SNAPSHOT</version>
   </dependency>

**配置连接**
rabbitmq:
  host: 127.0.0.1
  port: 5672
  username: guest
  password: guest
  virtualHost: /

**RabbitTemplate**
PageConfigController
//页面静态化接口
    @PostMapping("/staticPage")
    AjaxResult staticPage(@RequestBody Map<String, String> map){
        String dataKey = map.get("dataKey");
        String pageName = map.get("pageName");
        try {
            pageConfigService.staticPage(dataKey,pageName);
            return AjaxResult.me();
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.me().setSuccess(false).setMessage("静态化失败!"+e.getMessage());
        }

    }
@Override
    public void staticPage(String dataKey, String pageName) {
        FileOutputStream os = null;
        InputStream is = null;
        try {
            //一 页面静态化
            Pager pager = pagerMapper
                    .selectList(new EntityWrapper<Pager>().eq("name", pageName)).get(0);
            String templateUrl = pager.getTemplateUrl(); //fastdfs地址 zip包的
            String templateName = pager.getTemplateName(); //要执行模板文件

            //1.1 下载fastdfs上面压缩包
            Response response =
                    fastDfsClient.download(templateUrl); //通过fastdfs下载压缩包
            is = response.body().asInputStream();

            //1.2 所有静态化中间数据都写入临时目录
            //1)跨操作系统
            //2 操作系统会自动维护,不用删除
            String tmpdir=System.getProperty("java.io.tmpdir");
            System.out.println(tmpdir+"jjjjj.........");
            String zipPath = tmpdir+"/temp.zip"; //要下载zip包路径
            String unZipPath = tmpdir + "/temp/"; //解压到路径
            os = new FileOutputStream(zipPath);
            IOUtils.copy(is , os); //保存到本地

            ZipUtil.unzip(zipPath,unZipPath); // 解压缩

            //1.3 获取到模板
            String templatePath = unZipPath+"/"+templateName; //模板路径 temp/home.vm
            System.out.println(templatePath+"zz.........");
            //2 生成静态页面的路劲
            String templatePagePath = templatePath+".html"; //本地静态页面地址
            System.out.println(templatePagePath+"xxx.........");



            //3 生成数据
            String courseTypes =redisClient.get("courseTypes"); //redis数据
            List<CourseTypeDto> courseTypeDtos = JSONArray.parseArray(courseTypes,CourseTypeDto.class);
            Map<String, Object> modelMap = new HashMap<>(); //封装两个参数作为一个对象传入进去
            modelMap.put("staticRoot", unZipPath);
            modelMap.put("courseTypes", courseTypeDtos);


            //4 做页面静态化
            VelocityUtils.staticByTemplate(modelMap,templatePath,templatePagePath); //进行页面静态化

            // 5 传递到fastdfs
            String pageUrl = fastDfsClient.upload(
                    new CommonsMultipartFile(createFileItem(new File(templatePagePath),"file")));
            //二 PageConfig 并且进行保存
            PageConfig config = new PageConfig();
            config.setTemplateUrl(templateUrl);
            config.setTemplateName(templateName);
            config.setDataKey(dataKey);
            config.setPhysicalPath(pager.getPhysicalPath());
            config.setDfsType(0L); //0表示fastDfs
            config.setPageUrl(pageUrl);
            config.setPageId(pager.getId());
            pageConfigMapper.insert(config);
            //三 往消息队列放入消息
            String routingKey = siteMapper
                    .selectList(new EntityWrapper<Site>().eq("id", pager.getSiteId())).get(0).getSn();
            System.out.println(routingKey+"ddh......");
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("fileSysType",0);
            jsonObject.put("staticPageUrl",pageUrl);
            jsonObject.put("physicalPath",pager.getPhysicalPath());
            System.out.println(jsonObject.toJSONString()+"dbl.....");
            rabbitTemplate.convertAndSend(
                    RabbitmqConstants.EXCHANGE_DIRECT_INFORM,routingKey,jsonObject.toJSONString());
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if (os != null) {
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }


    /*
创建FileItem
 */
    private FileItem createFileItem(File file,String filedName) {
        FileItemFactory factory = new DiskFileItemFactory(16, null);
        FileItem item = factory.createItem(filedName, "text/plain", true, file.getName());
        int bytesRead = 0;
        byte[] buffer = new byte[8192];
        try {
            FileInputStream fis = new FileInputStream(file);
            OutputStream os = item.getOutputStream();
            while ((bytesRead = fis.read(buffer, 0, 8192)) != -1) {
                os.write(buffer, 0, bytesRead);
            }
            os.close();
            fis.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return item;
    }

1.2 消费者-PageAgent

1)基本环境搭建
**pom**
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>

    <!-- Eureka 客户端依赖 -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>

    <!--配置中心支持-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-config</artifactId>
    </dependency>

    <!-- 通过公共rabbitmq的模块引入mq的jar包-->
    <dependency>
        <groupId>cn.itsource</groupId>
        <artifactId>hrm-basic-rabbitmq</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>
    <!--        fastdfsclient支持-->
    <dependency>
        <groupId>cn.itsource</groupId>
        <artifactId>hrm-common-client</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
    <dependency>
        <groupId>commons-io</groupId>
        <artifactId>commons-io</artifactId>
        <version>2.4</version>
    </dependency>
    <!-- 给调用的模块来转换json-->
    <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson  调用者需要转换-->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
        <version>1.2.58</version>
    </dependency>
</dependencies>

  **配置**
Bootstrap.yml
spring:
  profiles:
    active: dev
  cloud:
    config:
      name: application-page-agent #github上面名称
      profile: ${spring.profiles.active} #环境 java -jar -D xxx jar
      label: master #分支
      discovery:
        enabled: true #从eureka上面找配置服务
        service-id: hrm-config-server #指定服务名
      #uri: http://127.0.0.1:1299 #配置服务器 单机配置
eureka: #eureka不能放到远程配置中
  client:
    service-url:
      defaultZone: http://localhost:1010/eureka  #告诉服务提供者要把服务注册到哪儿 #单机环境
  instance:
    prefer-ip-address: true #显示客户端真实ip
feign:
  hystrix:
    enabled: true #开启熔断支持
  client:
    config:
      remote-service:           #服务名,填写default为所有服务
        connectTimeout: 3000
        readTimeout: 3000
hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 3000


配置库
server:
  port: 2040
spring:
  application:
    name: hrm-page-agent
rabbitmq:
  host: 127.0.0.1
  port: 5672
  username: guest
  password: guest
  virtualHost: /
  routingKey: hrmCourseSite

  **入口类**
创建模块
Pom
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>

    <!-- Eureka 客户端依赖 -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>

    <!--配置中心支持-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-config</artifactId>
    </dependency>

    <!-- 通过公共rabbitmq的模块引入mq的jar包-->
    <dependency>
        <groupId>cn.itsource</groupId>
        <artifactId>hrm-basic-rabbitmq</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>
    <!--        fastdfsclient支持-->
    <dependency>
        <groupId>cn.itsource</groupId>
        <artifactId>hrm-common-client</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
    <dependency>
        <groupId>commons-io</groupId>
        <artifactId>commons-io</artifactId>
        <version>2.4</version>
    </dependency>
    <!-- 给调用的模块来转换json-->
    <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson  调用者需要转换-->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
        <version>1.2.58</version>
    </dependency>
</dependencies>
配置
Bootstrap.yml
spring:
  profiles:
    active: dev
  cloud:
    config:
      name: application-page-agent #github上面名称
      profile: ${spring.profiles.active} #环境 java -jar -D xxx jar
      label: master #分支
      discovery:
        enabled: true #从eureka上面找配置服务
        service-id: hrm-config-server #指定服务名
      #uri: http://127.0.0.1:1299 #配置服务器 单机配置
eureka: #eureka不能放到远程配置中
  client:
    service-url:
      defaultZone: http://localhost:1010/eureka  #告诉服务提供者要把服务注册到哪儿 #单机环境
  instance:
    prefer-ip-address: true #显示客户端真实ip
feign:
  hystrix:
    enabled: true #开启熔断支持
  client:
    config:
      remote-service:           #服务名,填写default为所有服务
        connectTimeout: 3000
        readTimeout: 3000
hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 3000


配置库
server:
  port: 2040
spring:
  application:
    name: hrm-page-agent
rabbitmq:
  host: 127.0.0.1
  port: 5672
  username: guest
  password: guest
  virtualHost: /
  routingKey: hrmCourseSite

入口类
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients //feign处理
public class PageAgentApplication2040 {
    public static void main(String[] args) {
        SpringApplication.run(PageAgentApplication2040.class,args);
    }
}

package cn.itsource.config;

import cn.itsource.util.RabbitMqConstants;
import org.springframework.amqp.core.*;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class RabbitMqConfig {
    //队列
    public static final String QUEUE_PAGE_STATIC = "queue_page_static";
    //交换机名字
    public static final String EXCHANGE_TOPICS_PAGE = RabbitMqConstants.EXCHANGE_TOPICS_PAGE;

    @Value("${rabbitmq.routingKey}")
    private String routingKey;

    /**
     * 交换机配置
     * ExchangeBuilder提供了fanout、direct、topic、header交换机类型的配置
     *
     * @return the exchange
     */
    @Bean(EXCHANGE_TOPICS_PAGE) //spring中bean
    public Exchange EXCHANGE_TOPICS_INFORM() {
        //durable(true)持久化,消息队列重启后交换机仍然存在
        return ExchangeBuilder.topicExchange(EXCHANGE_TOPICS_PAGE).durable(true).build();
    }


    //声明队列
    @Bean(QUEUE_PAGE_STATIC)
    public Queue QUEUE_INFORM_SMS() {
        Queue queue = new Queue(QUEUE_PAGE_STATIC);
        return queue;
    }



    /**
     *
     * @param queue    the queue
     * @param exchange the exchange
     * @return the binding
     */
    @Bean
    public Binding BINDING_QUEUE_INFORM_SMS(@Qualifier(QUEUE_PAGE_STATIC) Queue queue, //通过名字从spring获取bean
                                            @Qualifier(EXCHANGE_TOPICS_PAGE) Exchange exchange) {
        //每个站点的routing可以是不一样的
        System.out.println(routingKey+"jjjjjjjjjjjjjjj");
        return BindingBuilder.bind(queue).to(exchange).with(routingKey).noargs();
    }

}


Handler
@Component
public class StaticPageHandler {
    @RabbitListener(queues = RabbitMqConfig.QUEUE_PAGE_STATIC)
    public void handle(String msg, Message message, Channel channel){
        System.out.println("接收消息:"+msg);
        Map map = JSONObject.parseObject(msg, Map.class);
        Integer fileSysType = (Integer) map.get(RabbitMqConstants.FILE_SYS_TYPE);
        String pageUrl = (String) map.get(RabbitMqConstants.PAGE_URL);
        String physicalPath = (String) map.get(RabbitMqConstants.PHYSICAL_PATH);
        //判断是那个文件系统,分别做处理

        switch(fileSysType){
            case 0 : //fastdfs
                downloadAndCopyOfFastDfs(pageUrl,physicalPath);
                break;
            case 1 : //hdfs
                downloadAndCopyOfHdfs(pageUrl,physicalPath);
                break;
        }
    }

    @Autowired
    private FastDfsClient fastDfsClient;
    //fastdfs支持
    private void downloadAndCopyOfFastDfs(String pageUrl, String physicalPath) {
        InputStream is = null;
        FileOutputStream os = null;
        try{
            //以pageUrl到fastdfs下载文件
            Response response = fastDfsClient.download(pageUrl);
            is = response.body().asInputStream();
            //放入特定文件
            System.out.println(physicalPath);
            os = new FileOutputStream(physicalPath);
            IOUtils.copy(is,os) ;
        }catch (Exception e){
            e.printStackTrace();
        }
        finally {

            if (os != null) {
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (is != null) {

                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }


    }

    //@TODO hdfs以后支持
    private void downloadAndCopyOfHdfs(String pageUrl, String physicalPath) {
    }
}



``
 1.3 数据发生改变重新页面静态化
    课程类型增删改

# 二 课程列表页 *****

  2.1 分析
     1)入口
	    搜索框 类型导航
	 2)分析
	    只有类型导航进来的才有面包屑,但是两者都是高级查询+分页
  2.2 实现
     1)入口实现
	     调整是携带参数,页面进行解析,如果是关键字可以做回显
	 2)面包屑
	    List<Map> 有序表示层级,Map里面要放自己和兄弟。
	    @Override
public List<Map<String, Object>> getCrumbs(Long courseTypeId) {

    List<Map<String,Object>> result = new ArrayList<>();
    //1 获取path 1.2.3
    CourseType courseType = courseTypeMapper.selectById(courseTypeId);
    String path = courseType.getPath();

    //2 截取path中各个节点自己  1 2 3
    String[] paths = path.split("\\.");

    //3 获取自己节点兄弟封装Map,放入List中进行返回
    for (String ownerIdStr : paths) {
        Map<String,Object> map = new HashMap<>();
        Long ownerId = Long.valueOf(ownerIdStr);

        System.out.println(ownerId);
        //获取每个自己
        CourseType owner =  courseTypeMapper.selectById(ownerId);
        map.put("owner",owner);
        //查询兄弟
        //获取父亲所有儿子
        List<CourseType> allChildren = courseTypeMapper
                .selectList(new EntityWrapper<CourseType>().eq("pid",owner.getPid()));

        //干掉自己-边遍历边操作(正删改),要用迭代器
        Iterator<CourseType> iterator = allChildren.iterator();
        while (iterator.hasNext()){
            CourseType currentType = iterator.next();
            if (currentType.getId().longValue()==owner.getId().longValue()){
                iterator.remove();
                continue;
            }
        }
        map.put("otherCourseTypes",allChildren);
        result.add(map);
    }
    return result;
}

	 3)分页列表
	    dsl-基本结构
	

```java

@PostMapping("/queryCourses")
public PageList<Map<String,Object>> queryCourses(@RequestBody Map<String,Object> query){
    System.out.println(query);
    return courseService.queryCourses(query);
}


@Override
public PageList<Map<String, Object>> queryCourses(Map<String,Object> query) {
    return esCourseClient.query(query);
}

EsClient

@PostMapping("/query")
PageList<Map<String,Object>> query(@RequestBody Map<String, Object> params){

    return esCourseService.query(params);
}



@Override
public PageList<Map<String, Object>> query(Map<String, Object> params) {
    // keyword CourseyType brandId priceMin priceMax sortField sortType page rows
    String keyword = (String) params.get("keyword"); //查询
    String sortField = (String) params.get("sortField"); //排序
    String sortType = (String) params.get("sortType");//排序

    Long courseType = params.get("CourseType") !=null?Long.valueOf(params.get("CourseType").toString()):null;//过滤
    Long priceMin = params.get("priceMin") !=null?Long.valueOf(params.get("priceMin").toString())*100:null;//过滤
    Long priceMax = params.get("priceMax") !=null?Long.valueOf(params.get("priceMax").toString())*100:null;//过滤
    Long page = params.get("page") !=null?Long.valueOf(params.get("page").toString()):null; //分页
    Long rows = params.get("rows") !=null?Long.valueOf(params.get("rows").toString()):null;//分页

    //构建器
    NativeSearchQueryBuilder builder = new NativeSearchQueryBuilder();
    //设置查询条件=查询+过滤
    BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
    if (StringUtils.isNotBlank(keyword)){
        boolQuery.must(QueryBuilders.matchQuery("all", keyword));
    }
    List<QueryBuilder> filter = boolQuery.filter();
    if (courseType != null){ //类型
        System.out.println(courseType+"jjjjjjjjjjjjjjjjjjj");
        filter.add(QueryBuilders.termQuery("courseTypeId", courseType));
    }
    //最大价格 最小价格
    //minPrice <= priceMax && maxPrice>=priceMin
    if(priceMax!=null &&priceMin != null){
        filter.add(QueryBuilders.rangeQuery("price").gte(priceMin).lte(priceMax));
    }
    builder.withQuery(boolQuery);
    //排序
    SortOrder defaultSortOrder = SortOrder.DESC;
    if (StringUtils.isNotBlank(sortField)){//销量 新品 价格 人气 评论
        //如果传入的不是降序改为升序
        if (StringUtils.isNotBlank(sortType) && !sortType.equals(SortOrder.DESC)){
            defaultSortOrder = SortOrder.ASC;
        }
        // 价格  索引库有两个字段 最大,最小
        //如果用户按照升序就像买便宜的,就用最小价格,如果用户按照降序想买贵的,用最大价格
        if (sortField.equals("jg")){
            builder.withSort(SortBuilders.fieldSort("price").order(defaultSortOrder));
        }
    }
    //分页
    Long pageTmp = page-1; //从0开始
    builder.withPageable(PageRequest.of(pageTmp.intValue(), rows.intValue()));
    //截取字段 @TODO
    //封装数据
    Page<EsCourse> CourseDocs = repository.search(builder.build());
    List<Map<String,Object>> datas = esCourses2ListMap(CourseDocs.getContent());
    return new PageList<>(CourseDocs.getTotalElements(),datas);
}


/**
 * 数据转换
 * @param content
 * @return
 */
private List<Map<String,Object>> esCourses2ListMap(List<EsCourse> content) {
    List<Map<String,Object>> result = new ArrayList<>();
    for (EsCourse esCourse : content)
    {
        result.add(esCourse2Map(esCourse));
    }
    return result;
}
private Map<String,Object> esCourse2Map(EsCourse esCourse) {
    Map<String,Object> result = new HashMap<>();
    result.put("id", esCourse.getId());
    result.put("name", esCourse.getName());
    result.put("users", esCourse.getUsers());
    result.put("courseTypeId", esCourse.getCourseTypeId());
    result.put("courseTypeName", esCourse.getCourseTypeName());
    result.put("gradeId", esCourse.getGradeId());
    result.put("gradeName", esCourse.getGradeName());
    result.put("status", esCourse.getStatus());
    result.put("tenantId", esCourse.getTenantId());
    result.put("tenantName", esCourse.getTenantName());
    result.put("userId", esCourse.getUserId());
    result.put("userName", esCourse.getUserName());
    result.put("startTime", esCourse.getStartTime());
    result.put("endTime", esCourse.getEndTime());
    result.put("expires", esCourse.getExpires());
    result.put("priceOld", esCourse.getPriceOld());
    result.put("price", esCourse.getPrice());
    result.put("intro", esCourse.getIntro());
    result.put("qq", esCourse.getQq());
    result.put("resources", esCourse.getResources());
    return result;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
项目中使用的技术: 1、前端:jsp、css、javascript、jQuery(js框架)、jquery.form.js、HTML富文本编辑器、        My97时间控件(添加员工)2、后台:Struts2、动态代理、Mybatis框架、log4J日志框架、jstl 、jstl自定义分页标签、代码机器人、Dwr、POI(实现Excel文件的导入导出)等3、数据库:Mysql4、服务器:Tomcat项目中涉及的功能: 1、项目以及数据库搭建2、用户异步登录、退出3、拦截器功能实现以及整合动态代理4、公告模块的增加、修改、删除、查询以及预览功能实现、文件异步上传5、文档模块的增加、修改、删除、查询以及文档的上传下载6、员工信息的增加、修改、删除、查询以及员工头像异步上传、员工信息导出至Excel文件7、自定义分页标签实现(24种样式随意切换)8、代码机器人使用等等其他实战项目:java项目实战之电商系统全套(前台和后台)(java毕业设计ssm框架项目)https://edu.csdn.net/course/detail/25771 java项目之oa办公管理系统(java毕业设计)https://edu.csdn.net/course/detail/23008 java项目hrm人事管理项目(java毕业设计)https://edu.csdn.net/course/detail/23007 JavaWeb项目实战之点餐系统前台https://edu.csdn.net/course/detail/20543 JavaWeb项目实战之点餐系统后台https://edu.csdn.net/course/detail/19572 JavaWeb项目实战之宿舍管理系统(Java毕业设计含源码)https://edu.csdn.net/course/detail/26721 JavaWeb项目实战之点餐系统全套(前台和后台)https://edu.csdn.net/course/detail/20610 java项目实战之电子商城后台(java毕业设计SSM框架项目)https://edu.csdn.net/course/detail/25770 java美妆商城项目|在线购书系统(java毕业设计项目ssm版)https://edu.csdn.net/course/detail/23989 系统学习课程:JavaSE基础全套视频(环境搭建 面向对象 正则表达式 IO流 多线程 网络编程 java10https://edu.csdn.net/course/detail/26941 Java Web从入门到电商项目实战挑战万元高薪(javaweb教程)https://edu.csdn.net/course/detail/25976其他素材版(毕业设计或课程设计)项目:点击老师头像进行相关课程学习
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值