程序设计-在校整理-02 食堂自动化管理系统

这是一个简化的食堂自动化管理系统,包括学生就餐卡管理、菜品管理及消费记录统计功能。系统采用文件存储数据,支持管理员对学生卡的注册、充值、挂失等操作,以及菜品的增删改查。同时,学生可以查询余额和消费记录,购买菜品。程序实现了字符界面的菜单操作,并确保数据完整性。测试结果显示系统功能运行正常。
摘要由CSDN通过智能技术生成

一、课题内容和要求

1、问题描述

编写一份简化的食堂自动化管理系统,实现学生就餐卡管理和菜品管理以及消费记录统计等相关功能。所有数据包括学生就餐卡信息,菜品信息等都要利用文件系统保存,以备系统下次运行时使用。通过此课题,熟练掌握文件、数组、指针的各种操作,以及一些基本算法的应用。

2、功能要求

(1)学生就餐卡和菜品数据是由多条数据记录构成,其信息包括:
学生就餐卡:卡号,姓名,余额,状态(正常和挂失。)
食堂菜品数据:编号 名称 金额 消费次数
(2)数据保存形式:
所有就餐卡信息,菜品信息数据要以文本或二进制文件保存。
(3)需要实现的功能
代码要能提供以下两个基本模块。
管理员模块:
管理员以密码登录系统,可以完成以下功能
A. 注册学生就餐卡
B.就餐卡的充值挂失模块
C.食堂菜单管理功能,包括对菜单的增删修改查等功能。
学生模块:
以就餐卡号登录系统(说明:卡处于挂失,则拒绝登录。)
可以查询卡中余额。
可以查询本卡的消费记录(选做)
可以浏览菜品并按照金额购买
(4)界面功能要求:
A.采用友好的字符界面,实现一个功能控制菜单。
B.每次操作都从该菜单选择,利用循环结构使得一次运行程序可进行多次操作。

选做要求:
(1)数据完整性保证。例如:就餐卡号和菜单编号不得重复。
(2)学生每次消费可以自动生成消费记录(卡号,购买时间,购买菜品编号,购买金额)。该消费记录表永久保存,用于事后查询和统计。具体请学生自己构思、设计。

二、需求分析

食堂自动化管理系统的功能框架图如图所示。

1
(1) 提供可操作的主菜单:输出菜单,用于显示以从文件中加载的主菜单信息和若干个可选的功能选项。根据客户输入的选项来进入不同的模式,运行不同的函数。流程操作如下图所示。
2
(2)程序入口与多级菜单显示:在主菜单下,根据用户输入的不同选择,进入各级菜单,进而调用不同的函数,实现不同的功能。
(3)数据结构体的设计与初始化:在程序一开始就将自动构建各类用户结构体的实例,并且构造实例,为不同用户提供服务。在用户进行不同的选择时,会读入不同的数据信息,来构建具体的结构体实例,以满足用户需求。
(4)用户信息存储:在程序一始,会将相关数据结构自动初始化置空。在用户使用非存储类功能时,将不会对相关数据信息进行任何更改,也不涉及对文件内容的读写操作;当用户使用设计相关信息存储的功能时,将会从文件中按需写入相关信息到结构体中,在使用完毕后,再次进行信息的存储。如果是仅涉及存储,不涉及更改已存入信息功能的函数,将限制其使用文件的权限,已达到相关数据安全的保障。
(5)面向不同用户的功能协调:本程序设计了两种不同的用户模式:管理员模式与学生模式;程序的主入口是一致的,都将由用户来选择进入任何一种模式继续运行,两种模式都是采用一定的检测手段来进行登录使用,如下图所示。
3

三、概要设计

主要存储结构

// 代码很烂,轻喷。注:仅供参考学习使用。
//主要存储结构
//================ 结构体 ================
struct Student{
    char card_num[20]; //卡号
    char name[20];//姓名
    char money[20];//余额
    char mode[2];//状态 
};
typedef struct Student student;//别名student 

struct Food{
    char id[20];
    char name[20];
    char price[20];
    char num[10];
};
typedef struct Food food;//和student内容相似 

struct Record{
    char stu_id[20];
    char food_id[20];
    char food_price[20];
    char record_time[255];
};
typedef struct Record record;//和student内容相似

四、源程序代码

// 代码很烂,轻喷。注:仅供参考学习使用。
//头文件   
#include <stdio.h>  
#include <string.h>  
#include <stdlib.h>  
#include <math.h> 
#include <time.h> 

//全局变量定义   
#define USER_FILE "user.txt"  
#define RECORD_FILE "record.txt" 
#define FOOD_FILE "food.txt"   
#define CONSOLE "CON"
#define BUFLEN 255
#define NUM 50  
#define password 123

//================ 结构体 ================
struct Student{
    char card_num[20]; //卡号
    char name[20];//姓名
    char money[20];//余额
    char mode[2];//状态 
};
typedef struct Student student;//别名student 

struct Food{
    char id[20];
    char name[20];
    char price[20];
    char num[10];
};
typedef struct Food food;//和student内容相似 

struct Record{
    char stu_id[20];
    char food_id[20];
    char food_price[20];
    char record_time[255];
};
typedef struct Record record;//和student内容相似 
 
//================ 函数声明 ================
//主函数
int main(void);
//重启函数
void rerun();
//主菜单显示
int menu();
//结构体内容初始化 
void init(student *stu,food *fd,record *re);
//从文件读入学生卡信息
void readfile(student *stu);
//从文件读入菜品信息
void readfood(food *fd);
//从文件读入记录信息
void readrecord(record *re);
//保存学生信息 
void savefile(student *stu);
//保存食物信息 
void savefood(food *fd);
//保存记录信息
void saverecord(record *re);

//管理模式 
void admin_mode(student *stu,food *fd);
//管理模式菜单 
int admin_menu();
//注册学生卡
void regist();
//充值 
void charge(student *stu);
//挂失 
void report_of_loss(student *stu);
//解挂 
void hanging_solutions(student *stu);
//注销 
void del(student *stu);
//录入菜品 
void input(food *fd);
//查询菜品 
void check(food *fd);
//统计功能 (打印所有菜品信息) 
void count(food *fd);

//学生模式 
void stu_mode(student *stu,food *fd,record *re);
//学生模式菜单 
int stu_menu();
//查余额 
void surplus(student *stu,char *num);
//消费记录 
void sturecord(record *re,char *num);
//购物 
void purchase(student *stu,food *fd,char *num);

//================ 程序辅助功能实现 ================
//结构体内容初始化 
void init(student *stu,food *fd,record *re){
    
    for(int i = 0; i<NUM;i++){
        strcpy(stu[i].card_num,"");
        strcpy(stu[i].name,"");         
        strcpy(stu[i].money,"");            
        strcpy(stu[i].mode,"");
    }
    
    for(int i = 0; i<NUM;i++){
        strcpy(fd[i].id,"");
        strcpy(fd[i].name,"");          
        strcpy(fd[i].price,"");         
        strcpy(fd[i].num,"");
    }

    for(int i = 0; i<BUFLEN;i++){
        strcpy(re[i].stu_id,"");
        strcpy(re[i].food_id,"");           
        strcpy(re[i].food_price,"");            
        strcpy(re[i].record_time,"");
    }

}

//从文件读入学生卡信息
void readfile(student *stu){
    int i=0; 
    //输入重定向,从文件输入。 
    freopen(USER_FILE, "r", stdin);
    for(i=0;i<NUM;i++){
//      while(~scanf("%s%s%s%s", stu[i].card_num,stu[i].name, stu[i].money,stu[i].mode));
        scanf("%s%s%s%s", stu[i].card_num,stu[i].name, stu[i].money,stu[i].mode);
        
    }
    //重定向返回 
    freopen("CON", "r", stdin);

} 

//从文件读入菜品信息
void readfood(food *fd){ 
    freopen(FOOD_FILE, "r", stdin);

    for(int i=0;i<NUM;i++){
        scanf("%s%s%s%s", fd[i].id,fd[i].name,fd[i].price,fd[i].num);   
    }
    freopen("CON", "r", stdin);

} 

//从文件读入记录信息
void readrecord(record *re){ 
    freopen(RECORD_FILE, "r", stdin);

    for(int i=0;i<NUM;i++){
        scanf("%s%s%s%s", re[i].stu_id,re[i].food_id,re[i].food_price,re[i].record_time);   
    }
    freopen("CON", "r", stdin);
} 

//保存学生信息 
void savefile(student *stu){
    //重定向到文件,向文件中输入 
    freopen(USER_FILE, "w", stdout);

    for(int i = 0; i<NUM; i++){
        if(strlen(stu[i].card_num)!=0){
            printf("%s %s %s %s\n",stu[i].card_num,stu[i].name, stu[i].money,stu[i].mode);
        }
    }
    freopen(CONSOLE, "w", stdout);
}

//保存食物信息 
void savefood(food *fd){
    freopen(FOOD_FILE, "w", stdout);

    for(int i = 0; i<NUM; i++){
        if(strlen(fd[i].id) != 0){
            printf("%s %s %s %s\n",fd[i].id,fd[i].name, fd[i].price,fd[i].num);
        }
    }
    freopen(CONSOLE, "w", stdout);

}

//保存记录信息
void saverecord(record *re){
    freopen(RECORD_FILE, "w", stdout);

    for(int i=0;i<NUM;i++){
        if(strlen(re[i].stu_id) != 0){
            printf("%s %s %s %s\n",re[i].stu_id,re[i].food_id,re[i].food_price,re[i].record_time);
        }
    }
    freopen(CONSOLE, "w", stdout);
}

//================ 管理员功能实现 ================
//注册学生卡,默认激活 
void regist(){
    char cardnum[20],name[20]; //接收用户输入
    int money,mode=0; //标记使用

    printf(" 输入卡号:");
    scanf("%s",cardnum);
    printf(" 输入姓名:");
    scanf("%s",name); 
    printf(" 输入余额:");
    scanf("%d",&money);
        
    // 文件指针  
    FILE* fp = fopen(USER_FILE, "a+");  
  
    // 输出到文件  
    fputs(cardnum, fp);  fputs(" ", fp);  
    fputs(name, fp);  fputs(" ", fp); 
    char str1[20];  
    itoa(money, str1, 10);  
    fputs(str1, fp);  fputs(" ", fp); 
    char str2[20];  
    itoa(mode, str2, 10);  
    fputs(str2, fp);  fputs("\n", fp); 
    // 关闭文件  
    fclose(fp);
    printf(" 注册成功!\n");

    rerun();//重新启动程序
}  
    
//充值 
void charge(student *stu){
    readfile(stu);
    char num[20];
    char charge_num[999];
    int charge_money=0,flag=0; 
    printf(" 请输入要充值的卡号:");
    scanf("%s",num);
    printf(" 请输入充值金额:");
    scanf("%s",charge_num);
    charge_money=atol(charge_num);
    for(int i =0;i<NUM-1;i++){
        if(strcmp(stu[i].card_num,num)==0){         
            charge_money=atol(stu[i].money)+charge_money;
            ltoa(charge_money,charge_num,10);
            strcpy(stu[i].money,charge_num);
            flag=1;
            printf(" 充值成功!\n");
            break;
        }
    }  
    if(flag==0) printf(" 没有该卡!\n") ;
    savefile(stu);

    rerun();//重新启动程序
}

//挂失 
void report_of_loss(student *stu){
    readfile(stu);
    int flag=-1;//做标记 
    char num[20];
    printf(" 请输入要挂失的卡号:");
    scanf("%s",num);
    for(int i =0;i<NUM-1;i++){
        if(strcmp(stu[i].card_num,num)==0){ 
            flag=i;     
            strcpy(stu[i].mode,"1");
            printf(" 挂失成功!\n");
            break;
        }
    }  
    if(flag==-1) printf(" 查无此卡,请先注册!\n");
    savefile(stu);  //将关键信息保存

    rerun();//重新启动程序
}

//解挂 
void hanging_solutions(student *stu){
    readfile(stu);
    int flag=-1; 
    char num[20];

    printf(" 请输入要解挂的卡号:");
    scanf("%s",num);
    for(int i =0;i<NUM-1;i++){
        if(strcmp(stu[i].card_num,num)==0){         
            flag=i;
            strcpy(stu[i].mode,"0");
            printf(" 解挂成功!\n");
            break;
        }
    }  
    if(flag==-1) printf(" 查无此卡,请先注册!\n");
    savefile(stu);

    rerun();//重新启动程序
}

//注销 
void del(student *stu){
    readfile(stu);
    int flag =-1;
    char num[20];
    printf(" 请输入要注销的卡号:");
    scanf("%s",num);
    for(int i =0;i<NUM-1;i++){
        //找到卡后置空 
        if(strcmp(stu[i].card_num,num)==0){
            flag=i;
            strcpy(stu[i].card_num,"");
            strcpy(stu[i].name,"");         
            strcpy(stu[i].money,"");            
            strcpy(stu[i].mode,"");
            printf(" 注销成功!\n") ; 
        }
    } 
    if(flag==-1) printf(" 查无此卡,请先注册!\n"); 
    savefile(stu);
    rerun();
}

//录入菜品 
void input(food *fd){
    char id[20],name[20],price[20],num[10];

    printf(" 输入菜品ID:");
    scanf("%s",id);
    printf(" 输入菜品名称:");
    scanf("%s",name); 
    printf(" 输入菜品价格:");
    scanf("%s",price);
    printf(" 输入菜品数量:");
    scanf("%s",num);
        
    // 文件指针  
    FILE* fp = fopen(FOOD_FILE, "a+");  
  
    // 输出到文件  
    fputs(id, fp);  fputs(" ", fp);  
    fputs(name, fp);  fputs(" ", fp); 
    fputs(price, fp);  fputs(" ", fp);  
    fputs(num, fp);  fputs("\n", fp); 

    // 关闭文件  
    fclose(fp);
    printf(" 录入成功!\n");
    rerun();
}

//查询菜品 
void check(food *fd){
    readfood(fd);
    char id[20];
    printf(" 请输入需要查询的菜品ID:");
    scanf("%s",id);
    for(int i =0;i<NUM-1;i++){
        if(strcmp(fd[i].id,id)==0){ 
            printf(" 菜品ID为:%s",fd[i].id);
            printf("  菜品名称为:%s",fd[i].name);
            printf("  菜品价格为:%s",fd[i].price);
            printf("  菜品数量为:%s\n",fd[i].num);
        } 
    } 

    rerun();    
}

//统计功能 (打印所有菜品信息) 
void count(food *fd){
    readfood(fd);
    int total_num=0,total_money=0;//菜品数量,总销售额 
    for(int i =0;i<NUM-1;i++){
        if(strlen(fd[i].id)!=0){
        printf(" 菜品ID为:%s",fd[i].id);
        printf("  菜品名称为:%s",fd[i].name);
        printf("  菜品价格为:%s",fd[i].price);
        printf("  菜品数量为:%s\n",fd[i].num);
        total_num+=atoi(fd[i].num);
        total_money+=atol(fd[i].num)* atol(fd[i].price);
        }
     } 
    printf(" 菜品总数量为:%d\t",total_num);
    printf(" 菜品可销售总金额为:%d\n",total_money);
    rerun();
}

//================ 学生功能实现 ================
//查余额 
void surplus(student *stu,char *num){
    readfile(stu);
    for(int i =0;i<NUM-1;i++){
        if(strcmp(stu[i].card_num,num)==0){ 
            printf(" 账户余额为:%s\n",stu[i].money);
        } 
    } 
    rerun();    
} 

//消费记录 
void sturecord(record *re,char *num){
    readrecord(re);
    int flag=-1;
    for(int i =0;i<BUFLEN-1;i++){
        if(strcmp(re[i].stu_id,num)==0){
            flag=i;
            printf(" 学生卡号为:%s",re[i].stu_id);
            printf("  购买菜品编号为:%s",re[i].food_id);
            printf("  购买菜品价格为:%s",re[i].food_price);
            printf("  购买时间为:%s\n",re[i].record_time);
        }
    }if(flag==-1) printf(" 无记录!\n");
    rerun();
}

//购物 
void purchase(student *stu,food *fd,char *num){
    readfile(stu);
    readfood(fd);
    
    char stu_id[20];
    char food_id[20];
    char food_price[20];
    char record_time[255];
    char ch_fd[10],money[20];
    int re_id1=-1,re_id2=-1,flag=0; 
    //获取时间 
    time_t t = time( 0 );
    char tmpBuf[BUFLEN];
    strftime(tmpBuf, BUFLEN, "%Y-%m-%d-%H:%M:%S", localtime(&t)); //格式化时间 

    
    for(int i =0;i<NUM-1;i++){
        if(strcmp(stu[i].card_num,num)==0){ 
        //找到对应得学生卡后输出菜品 
            re_id1=i;
            for(int j =0;j<NUM-1;j++){
                if(strlen(fd[j].id)!=0){
                    printf(" 菜品ID为:%s",fd[j].id);
                    printf("  菜品名称为:%s",fd[j].name);
                    printf("  菜品价格为:%s",fd[j].price);
                    printf("  菜品数量为:%s\n",fd[j].num);
                } 
            } 
            //购物选择 
            printf(" 输入要购买的商品ID:");
            scanf("%s",ch_fd);
            for(int k =0;k<NUM-1;k++){
                if(strcmp(fd[k].id,ch_fd)==0){
                    //找到菜品后 余额和菜价进行比较
                    if(atoi(stu[i].money)>atoi(fd[k].price)&&fd[k].num>0){
                        printf(" 购买成功!\n");
                        re_id2=k;
                        savefile(stu);
                        // 文件指针  
                        FILE* fp = fopen(RECORD_FILE, "a+");  
                        // 输出到文件  
                        fputs(stu[re_id1].card_num, fp);  fputs(" ", fp);  
                        fputs(fd[re_id2].id, fp);  fputs(" ", fp); 
                        fputs(fd[re_id2].price, fp);  fputs(" ", fp);  
                        fputs(tmpBuf, fp);  fputs("\n", fp); 
                        // 关闭文件  
                        fclose(fp);
                        char re_money[20],remun[10];
                        itoa(atoi(stu[i].money)-atoi(fd[k].price),re_money,10);
                        strcpy(stu[i].money,re_money);
                        itoa(atoi(fd[k].num)-1,remun,10);
                        strcpy(fd[k].num,remun);
                        savefile(stu);
                        savefood(fd);
                    } else printf(" 余额不足,请充值!\n"); 
                }
            }
        } 
    } 
rerun();//重新启动程序    
} 

//================ 菜单与模式入口================
//管理模式菜单 
int admin_menu(){
    int re=0; 
    printf("========== 管理模式 ==========\n");
    printf("   * * * 学生卡相关 * * *\n");  
    printf(" [---- Press 1 :注册----]\n");//  regist
    printf(" [---- Press 2 :充值----]\n");//  charge
    printf(" [---- Press 3 :挂失----]\n");//  report_of_loss
    printf(" [---- Press 4 :解挂----]\n");//  hanging_solutions
    printf(" [---- Press 5 :注销----]\n\n");//    del
    printf("   * * * 菜品相关* * *\n");  
    printf(" [---- Press 6 :录入菜品----]\n");//    input 
    printf(" [---- Press 7 :查询菜品----]\n");//    check  
    printf(" [---- Press 8 :统计菜品----]\n\n");//  count
      
    printf(" 请输入您的选择:"); 
    scanf("%d",&re);
    return re;  
}

//学生模式菜单 
int stu_menu(){
    int re=0; 

    printf("========== 学生模式 ==========\n");
    printf(" [---- Press 1 :查询余额----]\n");//    surplus
    printf(" [---- Press 2 :消费记录----]\n");//    record
    printf(" [---- Press 3 :购买菜品----]\n");//    purchase 
    printf(" 请输入您的选择:"); 
    scanf("%d",&re);
    return re; 
    
}

//管理模式 
void admin_mode(student *stu,food *fd){
    int admin_password=0,menu_ch=0;
    printf(" 请输入管理员密码:");
    scanf("%d",&admin_password); 
    if(admin_password==password){
        menu_ch = admin_menu();
        switch(menu_ch){
            case 1 :  fflush(stdin);regist();break;//   注册 
            case 2 :  fflush(stdin);charge(stu);break;//    充值 
            case 3 :  fflush(stdin);report_of_loss(stu);break;//    挂失 
            case 4 :  fflush(stdin);hanging_solutions(stu);break;// 解挂 
            case 5 :  fflush(stdin);del(stu);break;//   注销 
            case 6 :  fflush(stdin);input(fd);break;//  录入 
            case 7 :  fflush(stdin);check(fd);break;//  查询 
            case 8 :  fflush(stdin);count(fd);break;//  统计 
        }
    }else{
        printf(" 密码错误!请确认密码后重试。\n\n");
    }   
    admin_mode(stu,fd);//再次载入
} 

//学生模式 
void stu_mode(student *stu,food *fd,record *re){
    readfile(stu);
    int stu_ch=0,flag=-1; 
    char num[20];
    printf(" 请输入您的卡号:");
    scanf("%s",num);
    for(int i =0;i<NUM-1;i++){
        if(strcmp(stu[i].card_num,num)==0 && strcmp(stu[i].mode,"0")==0){   
            flag=i;     
            stu_ch = stu_menu();
            switch(stu_ch){
            case 1 :  fflush(stdin);surplus(stu,num);break;//   查余额 
            case 2 :  fflush(stdin);sturecord(re,num);break;//  查记录 
            case 3 :  fflush(stdin);purchase(stu,fd,num);break;//   购买菜品 
            }
        } 
    } 
    if(flag==-1) printf(" 登录出错,请确认该卡是否已注册或处于挂失状态!\n") ;
    rerun();
}   
     
//主菜单显示 
int menu(){
    int re=0; 
    printf("======== 食堂管理系统 ========\n");
    printf(" [---- Press 1 :管理模式----]\n");  
    printf(" [---- Press 2 :学生模式----]\n");  
    printf(" 请输入您的选择:"); 
    scanf("%d",&re);
    return re; 
}

//重启函数
void rerun(){
     //判断是否重新运行本系统
    char re_star[2];
    printf("\n 目前程序已运行完毕,是否重新启动本程序?(y or else): ");
    scanf("%s",re_star);
    if (strcmp(re_star,"y")==0){
        main();
    } else {
        system("pause");
        exit(0);
    }
}

int main(void){
    //三个结构体的初始化 
    student stu[NUM];
    food fd[NUM];
    record re[BUFLEN];
    init(stu,fd,re);
    
    //载入文本文件 
    readfile(stu);
    readfood(fd);
    readrecord(re);
    
    printf("\n");
    
    int re_menu=0;
    re_menu=menu();
    if (re_menu==1){
        printf("\n 您将进入管理模式!\n\n");
        admin_mode(stu,fd);
    } else if(re_menu==2){
        printf("\n 您将进入学生模式!\n\n");
        stu_mode(stu,fd,re);
    }else{
        printf(" 输入有误,请重新输入!\n");
        fflush(stdin);  //清空缓冲区
        main();//重新调用初始菜单函数;
    }

    system("pause");
    return 0; 
}

五、测试总结

在开始正式测试之前,因为编写程序时需要进行必要的测试,已造成相关数据的变动,本次测试数据及其结果将继续沿用目前已经存在的相关数据。内容介绍如下:
user.txt 文件用来存放学生卡信息
逐列分别代表:卡号;姓名;余额;状态。数据:
001 qqq 101 0
002 wqq 111 0
003 ewq 10 0

food.txt文件用来保存菜品的信息
逐列分别代表:菜号;菜名;金额;数量数据:
001 qwe 10 9
002 qwq 99 1

record.txt文件用来保存购买的信息
逐列分别代表:学生卡号;菜品ID;菜品金额;时间
数据:
001 001 10 2021-03-12-13:17:40
002 001 10 2021-03-12-13:17:53
001 001 10 2021-03-12-13:26:32
003 002 99 2021-03-12-13:44:46
001 002 99 2021-03-12-14:13:21
001 001 10 2021-03-12-14:17:40
001 001 10 2021-03-12-14:24:10

在测试的过程中会对与变动的数据进行截图对比,对非必要对比部分(比如菜单运行)将不再说明。本程序已对用户输入进行检测,会给出输入检测示例。另外,因为本程序涉及函数过多,不再一一测试截图,仅对部分主要功能部分进行测试。

数据已经给啦,测试截图就不贴啦~

六、其他

以上以及博客中含有在校整理字样的博客内容,均是本人本科在校学习期间所写的代码,源文件以及数据文件等在个人主页资源区可以获取。本人水平很低,大佬轻喷。整理出来是为了帮助初学者学习的过程中,在有需要的情况下能够有所参考。再次声明:仅供学习交流使用。大家有什么问题,欢迎留言~

  • 11
    点赞
  • 89
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值