移动应用开发大作业报告

1 基本信息

1.1 系统名称

中华字典

1.2 开发运行环境

开发环境:Windows 10 专业版,JDK 1.8,AndroidStudio

运行环境:Java SE Runtime Environment (JRE) 8

1.3 使用的核心技术

JFrame:作为实现界面的窗体类,用于创建图形用户界面。

Random:用来产生随机数,为系统提供随机性支持。

Swing:用于构建丰富的图形用户界面组件。

JDBC:Java Database Connectivity,用于Java程序与数据库之间的连接。

SQL:结构化查询语言,用于管理和查询数据库。

2 系统功能设计

2.1 系统总体功能

中华字典是一款基于Java开发的字典查询系统。该系统旨在为用户提供便捷、准确的汉字、词语查询服务,支持拼音查询、部首查询等多种查询方式。同时,系统还提供了详细的词语解释、例句、同义词、反义词等扩展信息,帮助用户更深入地理解词语的含义和用法。

2.2 系统模块详细设计

2.2.1 拼音查询功能模块

用户通过输入拼音来查询对应的汉字或词语。系统根据输入的拼音在数据库中检索,并返回相关结果。结果页面将展示匹配的汉字或词语列表,并提供详细的解释、例句、同义词、反义词等信息。

2.2.2 部首查询模块功能模块

用户通过选择部首来查询含有该部首的汉字。系统根据选择的部首在数据库中检索,并返回相关结果。用户可进一步筛选查询结果,以便快速定位到所需汉字。

2.2.3 成语查询功能模块

用户通过输入成语或成语的关键词来查询相关的成语信息。系统根据输入的关键词在数据库中检索,并返回相关成语列表。用户可查看成语的解释、出处、用法示例等信息。

2.2.4 成语接龙小游戏功能模块

用户可参与成语接龙小游戏,通过输入成语的最后一个字来寻找下一个成语的开头字,以完成接龙。

3 系统实现

3.1 拼音查询 功能实现

3.1.1 功能描述

用户输入拼音后,系统通过调用后端接口进行数据库查询,并将查询结果返回给前端页面进行展示。前端页面提供输入框供用户输入拼音,同时展示查询结果列表和相关解释信息。

3.1.2 核心代码

java 复制代码
package com.example.dict;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;

import android.text.TextUtils;

import android.view.View;

import android.widget.ExpandableListView;

import com.example.dict.adapter.SearchLeftAdapter;

import com.example.dict.bean.PinBuBean;

import com.example.dict.bean.PinBuWordBean;

import com.example.dict.db.DBManager;

import com.example.dict.utils.AssetsUtils;

import com.example.dict.utils.CommonUtils;

import com.example.dict.utils.URLUtils;

import com.google.gson.Gson;

import com.handmark.pulltorefresh.library.PullToRefreshGridView;

import java.util.ArrayList;

import java.util.List;

public class SearchPinyinActivity extends BaseSearchActivity {

    String url;   //获取指定拼音对应的网址

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        //加载文件数据

       initData(CommonUtils.FILE_PINYIN,CommonUtils.TYPE_PINYIN);

        setExLvListener(CommonUtils.TYPE_PINYIN);

        exLv.expandGroup(0);   //默认展开第一组

        word = "a";     //默认进去时获取的是第一个 a

        url = URLUtils.getPinyinurl(word,page,pagesize);

        // 加载网络数据

        loadData(url);

       setGVListener(CommonUtils.TYPE_PINYIN);

    }

    /**

     * 网络获取失败时会调用的接口

     * 因为拼音查询和部首查询使用的获取数据的方法不一样,所以需要分开写。

     * 所以就把onError的方法写入到子类当中

     * */

    @Override

    public void onError(Throwable ex, boolean isOnCallback) {

        List<PinBuWordBean.ResultBean.ListBean> list = DBManager.queryPyWordFromPywordtb(word, page, pagesize);

        refreshDataByGV(list);

    }

}

3.1.3 运行截图

3.2 部首查询模块 功能实现

3.2.1 功能描述

用户通过选择部首来查询含有该部首的汉字。系统根据选择的部首在数据库中检索,并返回相关结果。用户可进一步筛选查询结果,以便快速定位到所需汉字。

3.2.2 核心代码

java 复制代码
package com.example.dict;

import android.os.Bundle;

import com.example.dict.bean.PinBuWordBean;

import com.example.dict.db.DBManager;

import com.example.dict.utils.CommonUtils;

import com.example.dict.utils.URLUtils;

import java.util.List;

public class SearchBuShouActivity extends BaseSearchActivity {

    String url;   //获取指定部首对应的网址

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        // 页面跳转,Title也要一起改变

        titleTv.setText(R.string.main_tv_bushou);

        //加载文件数据

       initData(CommonUtils.FILE_BUSHOU,CommonUtils.TYPE_BUSHOU);

        //开启部首的监听事件

        setExLvListener(CommonUtils.TYPE_BUSHOU);

        exLv.expandGroup(0);   //默认展开第一组

        word = "丨";     //默认进去时获取的是第一个

        url = URLUtils.getBushouurl(word,page,pagesize);

        // 加载网络数据

        loadData(url);

        setGVListener(CommonUtils.TYPE_BUSHOU);

    }

    @Override

    public void onError(Throwable ex, boolean isOnCallback) {

        List<PinBuWordBean.ResultBean.ListBean> list = DBManager.queryBsWordFromPywordtb(word, page, pagesize);

        refreshDataByGV(list);

    }

}

3.2.3 运行截图

3. 3 成语查询模块 功能实现

3.3.1 功能描述

3.3.2 核心代码

java 复制代码
package com.example.dict;

import android.content.Intent;

import android.os.Bundle;

import android.text.TextUtils;

import android.view.View;

import android.widget.ArrayAdapter;

import android.widget.ImageView;

import android.widget.TextView;

import android.widget.Toast;

import com.example.dict.bean.ChengyuBean;

import com.example.dict.db.DBManager;

import com.example.dict.utils.MyGridView;

import com.example.dict.utils.URLUtils;

import com.google.gson.Gson;

import java.util.ArrayList;

import java.util.List;

public class ChengyuInfoActivity extends BaseActivity {

    // 页面中的是个textView

    TextView ziTv1,ziTv2,ziTv3,ziTv4,pyTv,jsTv,fromTv,exampleTv,yufaTv,yinzhengTv,yinghangTv;

    MyGridView tyGv,fyGv;

    ImageView collectIv;

    private String chengyu;

    List<String> tongyiList,fanyinList;    //GridView的数据源

    ArrayAdapter<String> tyAdapter,fyAdapter;

    //    设置标志位,表示汉字是否被收藏

    boolean isCollect = false;

    boolean isExist = false;    //判断这个汉字是否已经存在

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_chengyu_info);

        initView();

        initAdapter();

//        获取上一个页面传递的数据

        Intent intent = getIntent();

        chengyu = intent.getStringExtra("chengyu");

        String url = URLUtils.getChengyuurl(chengyu);

        loadData(url);

        isExist = DBManager.isExistCyuInCollcyutb(chengyu);

        isCollect = isExist;

        setCollectIvStyle();

    }

    /* 根据收藏的状态,改变星星的颜色*/

    private void setCollectIvStyle() {

        if (isCollect) {

        collectIv.setImageResource(R.mipmap.ic_collection_fs);

        }else{

            collectIv.setImageResource(R.mipmap.ic_collection);

        }

    }

    /**

     *  为GridView设置加载数据的适配器和数据源

     */

    private void initAdapter() {

        tongyiList = new ArrayList<>();

        fanyinList = new ArrayList<>();

        tyAdapter = new ArrayAdapter<>(this, R.layout.item_word_jslv, R.id.item_wordlv_tv, tongyiList);

        fyAdapter = new ArrayAdapter<>(this, R.layout.item_word_jslv, R.id.item_wordlv_tv, fanyinList);

        tyGv.setAdapter(tyAdapter);

        fyGv.setAdapter(fyAdapter);

    }

    /** 网络数据加载成功时回调用的方法*/

    @Override

    public void onSuccess(String result) {

        // 使用Gson反序列化映射成为javaBean

        ChengyuBean bean = new Gson().fromJson(result, ChengyuBean.class);

        ChengyuBean.ResultBean cyBean = bean.getResult();

        if (cyBean!=null) {

//        因数据源当中不包括成语本身,但是后期要插入数据库,所以需要保存这个成语

            cyBean.setChengyu(chengyu);

            // 插入到数据库当中

            DBManager.insertCyToCyutb(cyBean);

            // 显示数据

            showDataToView(cyBean);

        }else{

            Toast.makeText(this,"此成语无法查到,请重新查询!",Toast.LENGTH_SHORT).show();

        }

    }

    /* 网络加载数据失败时,会调用的方法*/

    @Override

    public void onError(Throwable ex, boolean isOnCallback) {

//        获取数据库当中缓存的数据

        ChengyuBean.ResultBean bean = DBManager.queryCyFromCyutb(chengyu);

        if (bean!=null) {

            showDataToView(bean);

        }

    }

    /**

     * 将获取到的数据显示在View上

     * */

    private void showDataToView(ChengyuBean.ResultBean cyBean) {

        String chengyu = cyBean.getChengyu();

        ziTv1.setText(String.valueOf(chengyu.charAt(0)));

        ziTv2.setText(String.valueOf(chengyu.charAt(1)));

        ziTv3.setText(String.valueOf(chengyu.charAt(2)));

        ziTv4.setText(String.valueOf(chengyu.charAt(3)));

        pyTv.setText("拼音 : "+cyBean.getPinyin());

        jsTv.setText(cyBean.getChengyujs());

        fromTv.setText(cyBean.getFrom_());

        exampleTv.setText(cyBean.getExample());

        yufaTv.setText(cyBean.getYufa());

        yinzhengTv.setText(cyBean.getYinzhengjs());

        String ciyujs = cyBean.getCiyujs();

        if (!TextUtils.isEmpty(ciyujs)) {

            ciyujs = ciyujs.replace("]", "\n").replace("[", "").replace(":", "");

            yinghangTv.setText(ciyujs);

        }

        List<String> tList = cyBean.getTongyi();

//        判断是否有同义词

        if (tList!=null&&tList.size()!=0) {

            tongyiList.addAll(tList);

            tyAdapter.notifyDataSetChanged();

        }

        List<String> fList = cyBean.getFanyi();

        if (fList!=null&&fList.size()!=0) {

            fanyinList.addAll(fList);

            fyAdapter.notifyDataSetChanged();

        }

    }

    /**

     * 查找控件的方法

     * */

    private void initView() {

        ziTv1 = findViewById(R.id.cyinfo_tv_zi1);

        ziTv2 = findViewById(R.id.cyinfo_tv_zi2);

        ziTv3 = findViewById(R.id.cyinfo_tv_zi3);

        ziTv4 = findViewById(R.id.cyinfo_tv_zi4);

        pyTv = findViewById(R.id.cyinfo_tv_py);

        jsTv = findViewById(R.id.cyinfo_tv_js);

        fromTv = findViewById(R.id.cyinfo_tv_from);

        exampleTv = findViewById(R.id.cyinfo_tv_example);

        yufaTv = findViewById(R.id.cyinfo_tv_yufa);

        yinzhengTv = findViewById(R.id.cyinfo_tv_yinzheng);

        yinghangTv = findViewById(R.id.cyinfo_tv_yinghan);

        tyGv = findViewById(R.id.cyinfo_gv_tongyi);

        fyGv = findViewById(R.id.cyinfo_gv_fanyi);

        collectIv = findViewById(R.id.cyinfo_iv_collection);

    }

    public void onClick(View view) {

        switch (view.getId()) {

            case R.id.cyinfo_iv_back:

                finish();

                break;

            case R.id.cyinfo_iv_collection:

                isCollect = !isCollect;

                setCollectIvStyle();

                break;

        }

    }

    protected void onDestroy() {

        super.onDestroy();

        if (isExist&&!isCollect) {

            DBManager.deleteCyuToCollcyutb(chengyu);

        }

        if (!isExist&&isCollect) {

            DBManager.insertCyuToCollcyutb(chengyu);

        }

    }

}

3.3.3 运行截图

3. 4 成语接龙小游戏 功能实现

3.4.1 功能描述

用户可参与成语接龙小游戏,通过输入成语的最后一个字来寻找下一个成语的开头字,以完成接龙。

3.4.2 核心代码

java 复制代码
package com.example.dict;

import androidx.annotation.Nullable;

import androidx.appcompat.app.AlertDialog;

import androidx.appcompat.app.AppCompatActivity;

import android.content.DialogInterface;

import android.content.Intent;

import android.os.Bundle;

import android.os.CountDownTimer;

import android.util.Log;

import android.view.Gravity;

import android.view.LayoutInflater;

import android.view.View;

import android.widget.Button;

import android.widget.EditText;

import android.widget.ImageView;

import android.widget.LinearLayout;

import android.widget.TextView;

import android.widget.Toast;

import com.example.dict.BaseActivity;

import com.google.gson.Gson;

import com.example.dict.bean.ChengYuJieLongBean;

import com.example.dict.bean.ChengyuBean;

import com.example.dict.bean.WordBean;

import com.example.dict.db.DBManager;

import com.example.dict.filter.LimitInputTextWatcher;

import com.example.dict.utils.URLUtils;

public class ChengYuJieLongActivity  extends BaseActivity {

    EditText chengyu_et;

    Button sure;

    TextView word1,word2,word3,word4,word5,word6,word7,word8,timeout,level;

    ImageView back;

    LinearLayout chengjiebg;

    char myChar[],newChar[];

    String str,chengyu="";

    int i=1;

    Intent intent;

    CountDownTimer timer;

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_cheng_yu_jie_long);

        inital();

        chengyu_et.addTextChangedListener(new LimitInputTextWatcher(chengyu_et));

        intent = getIntent();

        i = intent.getIntExtra("level",1);

        chengyu=intent.getStringExtra("accchengyu");

        if(chengyu!=""){

            String url = URLUtils.getChengyujielongurl(chengyu);

            loadData(url);

        }

        chengjiebg.setBackgroundResource(getResources().getIdentifier("gufeng"+i, "drawable", getApplicationInfo().packageName));

        level.setText("关卡:"+i);

        String url = URLUtils.getChengyujielongurl(str);

        loadData(url);

//        设置倒计时

         timer = new CountDownTimer(300000, 1000) {

            public void onTick(long millisUntilFinished) {

            timeout.setText(String.valueOf(millisUntilFinished / 1000));

            }

            public void onFinish() {

                showEndingNormalDialog();

            }

        };

            //调用 CountDownTimer 对象的 start() 方法开始倒计时,也不涉及到线程处理

                    timer.start();

                }

    public void inital(){

        chengyu_et=findViewById(R.id.chengyu_et);

        sure=findViewById(R.id.sure);

        back=findViewById(R.id.chengyujielong_iv_back);

        word1=findViewById(R.id.word_1);

        word2=findViewById(R.id.word_2);

        word3=findViewById(R.id.word_3);

        word4=findViewById(R.id.word_4);

        word5=findViewById(R.id.word_5);

        word6=findViewById(R.id.word_6);

        word7=findViewById(R.id.word_7);

        word8=findViewById(R.id.word_8);

        timeout=findViewById(R.id.timeout);

        level=findViewById(R.id.level);

        chengjiebg=findViewById(R.id.chengjiebg);

    }

    public void onClick(View view) {

        switch (view.getId()){

            case R.id.chengyujielong_iv_back:

                Intent intent3 = new Intent(ChengYuJieLongActivity.this, MainActivity.class);

                startActivity(intent3);

                break;

            case R.id.sure:

                str=chengyu_et.getText().toString();

                if(str.length()!=4){

//                    Toast.makeText(getApplicationContext(), "您需要输入四个汉字",

//                            Toast.LENGTH_SHORT).show();

                    Toast toast=new Toast(ChengYuJieLongActivity.this);

//创建一个填充物,用于填充Toast

                    LayoutInflater inflater = LayoutInflater.from(ChengYuJieLongActivity.this);

//填充物来自的xml文件,在这个改成一个view

//实现xml到view的转变哦

                    View view2 =inflater.inflate(R.layout.toast,null);

//不一定需要,找到xml里面的组件,设置组件里面的具体内容

                    ImageView imageView1=view2.findViewById(R.id.iv_toast);

                    TextView textView1=view2.findViewById(R.id.tv_toast);

                imageView1.setImageResource(R.drawable.input);

                    textView1.setText("您需要输入四个汉字");

//把填充物放进toast

                    toast.setView(view2);

                    toast.setDuration(Toast.LENGTH_SHORT);

//                    toast位置居中

                    toast.setGravity(Gravity.CENTER,0,0);

//展示toast

                    toast.show();

                }

                else {

                    myChar = str.toCharArray();

                 word5.setText(Character.toString(myChar[0]));

                 word6.setText(Character.toString(myChar[1]));

                 word7.setText(Character.toString(myChar[2]));

                 word8.setText(Character.toString(myChar[3]));

                    Intent intent = new Intent(ChengYuJieLongActivity.this, IsChengYuActivity.class);

                    intent.putExtra("chengyu", str);

                    startActivityForResult(intent, 3);

                    break;

                }

        }



    }

    /* 网络数据加载成功时回调用的方法*/

    public void onSuccess(String json) {

        ChengYuJieLongBean cyjlBean = new Gson().fromJson(json, ChengYuJieLongBean.class);

        ChengYuJieLongBean.ResultBean resultBean = cyjlBean.getResult();

        String mychengyu=resultBean.getData().get(0);

        newChar = mychengyu.toCharArray();

        word1.setText(Character.toString(newChar[0]));

        word2.setText(Character.toString(newChar[1]));

        word3.setText(Character.toString(newChar[2]));

        word4.setText(Character.toString(newChar[3]));

    }

    @Override

    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {

        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode == 3 && resultCode == RESULT_OK) {

            String chengyuvalue = data.getStringExtra("chengyu");

            if (chengyuvalue.equals("否")) {

                Toast.makeText(getApplicationContext(), "您输入的不是成语!",

                      Toast.LENGTH_SHORT).show();

            } else {

         if(Character.toString(myChar[0]).equals(word4.getText()) && chengyuvalue.equals("是")){

//                    String url = URLUtils.getChengyujielongurl(str);

//                    loadData(url);

//                    Toast.makeText(getApplicationContext(), "您回答正确!",  Toast.LENGTH_SHORT).show();

word5.setBackground(getResources().getDrawable(R.drawable.tianzige));

word6.setBackground(getResources().getDrawable(R.drawable.tianzige));

word7.setBackground(getResources().getDrawable(R.drawable.tianzige));

word8.setBackground(getResources().getDrawable(R.drawable.tianzige));

                    showNormalDialog();

                }

                else {

                    if (Integer.parseInt(timeout.getText().toString()) > 150) {

//                    Toast.makeText(getApplicationContext(), "您输入的成语不正确哦!还有时间哦加油加油",Toast.LENGTH_SHORT).show();

                        Toast toast = new Toast(getApplicationContext());

                        LayoutInflater inflater = LayoutInflater.from(ChengYuJieLongActivity.this);

                        View view2 = inflater.inflate(R.layout.toast, null);

                        ImageView imageView1 = view2.findViewById(R.id.iv_toast);

                        TextView textView1 = view2.findViewById(R.id.tv_toast);

imageView1.setImageResource(R.drawable.fighting);

                        textView1.setText("您输入的成语不正确哦!还有时间哦加油加油!");

                        toast.setView(view2);

                        toast.setDuration(Toast.LENGTH_SHORT);

                        toast.setGravity(Gravity.CENTER, 0, 0);

                        toast.show();

                    } else{

//                    Toast.makeText(getApplicationContext(), "您输入的成语不正确哦!",Toast.LENGTH_SHORT).show();

                        Toast toast = new Toast(ChengYuJieLongActivity.this);

                        LayoutInflater inflater = LayoutInflater.from(ChengYuJieLongActivity.this);

                        View view2 = inflater.inflate(R.layout.toast, null);

                        ImageView imageView1 = view2.findViewById(R.id.iv_toast);

                        TextView textView1 = view2.findViewById(R.id.tv_toast);

    imageView1.setImageResource(R.drawable.wrong);

                        textView1.setText("您输入的成语不正确哦");

                        toast.setView(view2);

                        toast.setDuration(Toast.LENGTH_SHORT);

                        toast.setGravity(Gravity.CENTER, 0, 0);

                        toast.show();

                }

                }

            }

        }

    }

    private void showNormalDialog(){

        /* @setIcon 设置对话框图标

         * @setTitle 设置对话框标题

         * @setMessage 设置对话框消息提示

         * setXXX方法返回Dialog对象,因此可以链式设置属性

         */

        timer.cancel();

        final AlertDialog.Builder normalDialog =

                new AlertDialog.Builder(ChengYuJieLongActivity.this);

        normalDialog.setIcon(R.drawable.like);

        normalDialog.setTitle("恭喜您通过本关");

        String s=String.valueOf(300-Integer.parseInt(timeout.getText().toString()));

        normalDialog.setMessage("仅用了"+s+"秒");



        normalDialog.setPositiveButton("下一关",

                new DialogInterface.OnClickListener() {

                    @Override

                    public void onClick(DialogInterface dialog, int which) {

                        Intent intent = new Intent(ChengYuJieLongActivity.this, ChengYuJieLongActivity.class);

                        i++;

                        intent.putExtra("level", i);

                        intent.putExtra("accchengyu", str);

                        startActivity(intent);

                    }

                });

        normalDialog.setNegativeButton("退出游戏",

                new DialogInterface.OnClickListener() {

                    @Override

                    public void onClick(DialogInterface dialog, int which) {

                        Intent intent = new

    private void showEndingNormalDialog(){

        final AlertDialog.Builder normalDialog =

                new AlertDialog.Builder(ChengYuJieLongActivity.this);

        normalDialog.setIcon(R.drawable.heartbroken);

        normalDialog.setTitle("游戏结束啦,恭喜您通关到第"+i+"关");

        normalDialog.setPositiveButton("重玩",

                new DialogInterface.OnClickListener() {

                    @Override

                    public void onClick(DialogInterface dialog, int which) {

                        Intent intent = new Intent(ChengYuJieLongActivity.this, ChengYuJieLongActivity.class);

                        startActivity(intent);

                    }

                });

        normalDialog.setNegativeButton("退出游戏",

                new DialogInterface.OnClickListener() {

                    @Override

                    public void onClick(DialogInterface dialog, int which) {

                        Intent intent = new Intent(ChengYuJieLongActivity.this, MainActivity.class);

                        startActivity(intent);

                    }

                });

        // 显示

        normalDialog.show();

    }

}

3.4.3 运行截图

4 总结体会

在开发中华字典系统的过程中,我深刻体会到了Java编程的魅力和挑战性。通过设计并实现拼音查询、部首查询、成语查询等多个功能模块,我不仅提升了自己的编程能力,还加深了对数据库操作、前后端交互等技术的理解。同时,成语接龙小游戏的加入为系统增加了趣味性,也提升了用户的参与度和满意度。整个开发过程虽然充满了挑战,但收获颇丰,让我更加坚定了继续深入学习Java编程的决心。

5 附录

|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 源码文件清单 |
| Java代码、Layout布局 |

相关推荐
阿亮说技术2 小时前
Java毕业设计 基于SSM vue电影院票务系统小程序 微信小程序
java·微信小程序·毕业设计·课程设计
远望创客学堂3 小时前
【单片机毕业设计选题24045】-基于单片机的种子烘干机的设计与实现
stm32·单片机·嵌入式硬件·51单片机·课程设计
ing6576814 小时前
基于weixin小程序校园快递系统的设计
java·spring boot·后端·mysql·课程设计
FOUR_A19 小时前
【计算机毕业设计】基于微信小程序的电子购物系统的设计与实现【源码+lw+部署文档】
微信小程序·小程序·课程设计
2401_851243291 天前
2024微信小程序期末大作业-点奶茶微信小程序(后端nodejs-server)(附下载链接)_微信小程序期末大作业百度网盘下载
微信小程序·小程序·课程设计
战神刘玉栋1 天前
《侃侃而谈 · 为什么动笔》
经验分享·笔记·课程设计
栗豆包1 天前
【计算机毕业设计】026基于微信小程序的原创音乐
微信小程序·小程序·课程设计
要做好青年2 天前
HNU电子测试平台与工具2_《计算机串口使用与测量》
经验分享·学习·课程设计
学长是个程序员2 天前
基于springboot实现家政服务平台管理系统项目【项目源码+论文说明】计算机毕业设计
java·spring boot·毕业设计·课程设计·网页设计·项目源码·家政服务平台
Karen1982 天前
基于weixin小程序农场驿站系统的设计
java·spring boot·mysql·毕业设计·课程设计