博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【C】——C模拟atm取款机
阅读量:6079 次
发布时间:2019-06-20

本文共 18727 字,大约阅读时间需要 62 分钟。

  功能描述:1:开户;2:销户;3:存钱;4:取钱;5:查询;6:转账;

主要用的技术:

  一:消息队列:

    1)key_t key = ftok(".",100); //获取key

    2)msgid = msgget(key,IPC_CREATE|0666); //创建   msgid = msgget(key,0); //获取

    3)msgsnd = msgsnd = (msgid,&msg,sizeof(msg),0);  //发送

    4)msgrcv = msgrcv = (msgid,&msg,sizeof(msg),0,0); //获取

    5)msgt = msgctl(msgid,IPC_RMID,NULL);  //删除

  二:信号:

      signal(int sinno, void (*fa)(int));

  三:文件操作:

      int access(const char *filename);  //查看文件是否存在

      int open(int fd,int oflag,.../* mode_t mode*/)

      ssize_t write(int fd,void *buf,size_t nbytes);

      ssize_t read(int fd,void *buf,size_t nbytes);

思想架构:

  头文件:

    dao.h   ----> 定义文件操作的函数

    bank.h  -----> 定义宏,结构体,设置外部变量 key1 key2

  .c文件

    client.c  ---->  客户端操作  主要包括客户端的输入提示,和把数据传入服务器端

    server.c  ---->  创建消息队列,启动服务端,用vfork()创建子进程,用execl() 执行open.c 的目标文件。并且设定  SIG_INT 信号,接收此信号时就删除消息队列。

    open.c  ----->  用来接收客户端传来的消息,并对消息进行业务逻辑操作

    dao.c   ----->   dao.h中一定的函数的具体实现,供open.c 文件调用,主要是用来对文件的操作。

    bank.c  ---->  此文件主要用来对两个 key 赋值。

感觉有点类似网站建设中的三层架构。

client.c  主要用来负责用户层

open.c  主要用来负责业务逻辑层

dao.c  主要用来负责数据操作层

 

设计的技术点不多,但是确实个规范的项目。头文件和各个文件的作用值得学习。框架是老师建的,功能都是自己实现的,如有错误还望指正:

bank.h:

1 //客户端和服务器端共用的头文件 2 #ifndef BANK_H_ 3 #define BANK_H_ 4 //声明两个key值,用来给消息队列用,这两个key在另一个文件中定义 5  6 extern const int key1;//客户端向服务器发送消息队列的键值key 7 extern const int key2;//服务器向客户端发送的 8  9 //消息类型 定义为各种宏 方便处理10 #define M_OPEN 1//代表开户类型11 #define M_DESTROY 2 //销户12 #define M_SAVE 3 //存钱13 #define M_TAKE 4 //取钱14 #define M_QUERY 5 //查询15 #define M_TRANSF 6 //转账16 #define M_SUCCESS 7 //处理成功17 #define M_FAILED 8 //处理失败18 19 //包含帐户信息的帐户结构体20 struct Account{21     int id;//帐号22     char name[10];//用户名23     char password[10];//密码24     double balance;//金额25 };26 27 //消息的结构体28 struct Msg{29     long  mtype;//消息的类型30     struct Account acc;//帐户的信息结构体31 };32 #endif

dao.h:

1 //数据对象的存储 2 #ifndef DAO_H_ 3 #define DAO_H_ 4 #include "bank.h" 5 //生成不重复的帐号 6 int generator_id(); 7 //将新帐号添加到文件中,为开户服务 8 int createUser(struct Account acc); 9 //销户功能10 int destroyUser(struct Account acc);11 //存钱功能12 int saveMoney(struct Account acc,struct Account *p);13 //取钱功能14 int getMoney(struct Account acc,struct Account *p);15 //查询余额功能16 int checkMoney(struct Account acc,struct Account *p);17 //转账功能18 int moveMoney(struct Account acc1,struct Account acc2,struct Account *p);19 #endif

bank.c:

1 //对头文件中的变量进行定义2 #include "bank.h"3 4 const int key1 = 0x12345678;5 const int key2 = 0x23456789;

server.c:

1 //ATM的服务器端 2 #include "bank.h" 3 #include 
4 #include
5 #include
6 #include
7 #include
8 #include
9 #include
10 11 //首先需要创建两个全局存储消息队列的id的变量12 static int msgid1;13 static int msgid2;14 //写一个函数,用来创建两个消息队列,用到msgget函数15 void init(){16 //msgget函数,第一个参数是键值,bank.h中有17 //IPC_CREAT表示没有此消息队列则创建,18 //IPC_EXCL表示如果队列存在,则提示错误19 //0666是给此消息队列对象添加一些权限设置,类似文件系统20 //创建消息队列121 msgid1 = msgget(key1,IPC_CREAT|IPC_EXCL|0666);22 if(msgid1 == -1){23 perror("消息队列1创建失败"),exit(-1);24 }25 printf("消息队列1创建成功\n");26 //创建消息队列227 msgid2 = msgget(key2,IPC_CREAT|IPC_EXCL|0666);28 if(msgid2 == -1){29 perror("消息队列2创建失败");30 exit(-1);31 }32 printf("消息队列2创建成功\n");33 }34 //启动服务函数,用来创建子进程来执行用户不同的选择的结果35 void start(){36 printf("服务器正在启动..\n");37 sleep(2);38 //创建子进程39 pid_t open_pid = vfork();40 if(open_pid == -1){41 perror("vfork failed");42 exit(-1);43 }44 else if(open_pid == 0){ //进入子进程45 //printf("in child process\n");46 execl("./open","open",NULL);//不再和父进程共用代码段47 exit(-1);48 }49 else{50 printf("正在等待客户端选择..\n");51 waitpid(open_pid,0,0);//阻塞,等待子进程结束52 //printf("in parent process\n");53 }54 }55 56 void sig_exit(){57 printf("服务器正在关闭..\n");58 sleep(1);59 if(msgctl(msgid1,IPC_RMID,NULL) == -1){60 perror("消息队列1删除失败\n");61 exit(-1);62 }63 else{64 printf("消息队列1删除成功\n");65 }66 if(msgctl(msgid2,IPC_RMID,NULL) == -1){67 perror("消息队列2删除失败\n");68 exit(-1);69 }70 else{71 printf("消息队列2删除成功\n");72 }73 printf("服务器成功关闭\n");74 exit(0);//直接结束程序75 76 }77 int main(){78 //我们退出服务器用一个信号处理函数来实现79 printf("退出服务器请按CTRL+C\n");//发送SIGINT信号80 signal(SIGINT,sig_exit);//自定义信号处理函数,进行退出操作81 //做好了善后工作,我们从头开始启动服务器82 //创建消息队列83 init();84 //启动服务85 86 start();87 return 0;88 }

open.c:

1 /*开户*/  2 #include 
3 #include
4 #include
5 #include
6 #include
7 #include "bank.h" 8 int main(){ 9 int msgid1 = msgget(key1,0); 10 if(msgid1 == -1){ 11 perror("获取消息队列1失败"); 12 printf("服务器启动失败"); 13 exit(-1); 14 } 15 int msgid2 = msgget(key2,0); 16 if(msgid2 == -1){ 17 perror("获取消息队列2失败"); 18 printf("服务器启动失败"); 19 exit(-1); 20 } 21 //获取到消息队列之后,开始接受消息 22 while(1){ 23 struct Msg msg;//存储消息信息的结构体 24 struct Account accMove,accResult;//存储帐户信息 25 //首先从客户那里收取消息队列1的信息 msgrcv 函数 26 if(msgrcv(msgid1,&msg,sizeof(msg.acc),0,0) <=0 ){ 27 break; 28 } 29 //如果接受到了消息,根据消息的不同类型进行不同的操作 30 if(msg.mtype == M_OPEN){
//如果类型是开户 31 int id = generator_id(); 32 accMove = msg.acc; 33 accMove.id = id; 34 if(createUser(accMove)==-1){ 35 printf("开户失败"); 36 msg.mtype = M_FAILED;//将消息类型置成失败 37 } 38 else{ 39 printf("开户成功"); 40 msg.mtype = M_SUCCESS; 41 } 42 msg.acc.id = id; 43 msgsnd(msgid2,&msg,sizeof(msg.acc),0);//将消息由消息队列2发送给客户端 44 //执行开户的操作 45 //给用户分配帐号,将用户信息记录在文件中。 46 } 47 //最后把消息发过去,这时候消息的类型应该是两种情况M_SUCESS 48 //或者是M_FAILED 49 else if(msg.mtype == M_DESTROY){ 50 accMove = msg.acc; 51 int desval = destroyUser(accMove); 52 if(desval == -1){ 53 printf("没有此ID\n"); 54 msg.mtype = M_FAILED; 55 } 56 else if(desval == 0){ 57 printf("销户失败!\n"); 58 msg.mtype = M_FAILED; 59 } 60 else{ 61 printf("销户成功!\n"); 62 msg.mtype = M_SUCCESS; 63 } 64 if(msgsnd(msgid2,&msg,sizeof(msg.acc),0) == -1) perror("msgsnd"),exit(-1); 65 } 66 else if(msg.mtype == M_SAVE){ 67 accMove = msg.acc; 68 int saval = saveMoney(accMove,&accResult); 69 if(saval == -1){ 70 printf("没有此ID\n"); 71 msg.mtype = M_FAILED; 72 } 73 else if(saval == 0){ 74 printf("存钱失败!\n"); 75 msg.mtype = M_FAILED; 76 } 77 else{ 78 printf("存钱成功!\n"); 79 msg.mtype = M_SUCCESS; 80 } 81 msg.acc = accResult; 82 if(msgsnd(msgid2,&msg,sizeof(msg.acc),0) == -1) perror("msgsnd"),exit(-1); 83 } 84 else if(msg.mtype == M_TAKE){ 85 accMove = msg.acc; 86 int saval = getMoney(accMove,&accResult); 87 if(saval == -1){ 88 printf("没有此ID\n"); 89 msg.mtype = M_FAILED; 90 } 91 else if(saval == 2){ 92 printf("余额不足\n"); 93 msg.mtype = M_FAILED; 94 } 95 else if(saval == 0){ 96 printf("取钱失败!\n"); 97 msg.mtype = M_FAILED; 98 } 99 else{100 printf("取钱成功!\n");101 msg.mtype = M_SUCCESS;102 }103 msg.acc = accResult;104 if(msgsnd(msgid2,&msg,sizeof(msg.acc),0) == -1) perror("msgsnd"),exit(-1);105 106 }107 else if(msg.mtype == M_QUERY){108 accMove = msg.acc;109 int saval = checkMoney(accMove,&accResult);110 if(saval == -1){111 printf("没有此ID\n");112 msg.mtype = M_FAILED;113 }114 else if(saval == 0){115 printf("查询失败!\n");116 msg.mtype = M_FAILED;117 }118 else{119 printf("查询成功!\n");120 msg.mtype = M_SUCCESS;121 }122 msg.acc = accResult;123 if(msgsnd(msgid2,&msg,sizeof(msg.acc),0) == -1) perror("msgsnd"),exit(-1);124 125 }126 else if(msg.mtype == M_TRANSF){127 struct Account accto;128 accMove = msg.acc;129 if(msgrcv(msgid1,&msg,sizeof(struct Account),0,0) == -1) perror("msgrcv"),exit(-1);130 accto = msg.acc;131 int tra = moveMoney(accMove,accto,&accResult);132 if(tra == -1){133 printf("没有此ID\n");134 msg.mtype = M_FAILED;135 }136 else if(tra == 0){137 printf("转账失败\n");138 msg.mtype = M_FAILED;139 }140 else if(tra == 2){141 printf("余额不足\n");142 msg.mtype = M_FAILED;143 }144 else{145 printf("转账成功\n");146 msg.mtype = M_SUCCESS;147 }148 msg.acc = accResult;149 if(msgsnd(msgid2,&msg,sizeof(struct Account),0) == -1) perror("msgsnd"),exit(-1);150 151 }152 }153 return 0;154 }
View Code

client.c:

1 /* 客户端*/  2 #include 
3 #include "bank.h" 4 #include
5 #include
6 #include
7 #include
8 #include
9 10 static int msgid1;//定义两个接受消息队列的id的变量 11 static int msgid2; 12 //获取消息队列函数, 13 void getID(){ 14 msgid1 = msgget(key1,0); 15 if(msgid1 == -1){ 16 perror("获取消息队列1失败"); 17 exit(-1); 18 } 19 msgid2 = msgget(key2,0); 20 if(msgid2 == -1){ 21 perror("获取消息队列2失败"); 22 exit(-1); 23 } 24 } 25 //开户函数 26 void createUser(){ 27 struct Account acc; 28 printf("请输入用户名:\n"); 29 scanf("%s",acc.name); 30 printf("请输入密码:\n"); 31 scanf("%s",acc.password); 32 printf("请输入金额:\n"); 33 scanf("%d",&acc.balance); 34 struct Msg msg = {M_OPEN,acc}; 35 //获取消息队列 36 getID(); 37 //将消息发送到消息队列1中 38 msgsnd(msgid1,&msg,sizeof(msg.acc),0); 39 //接受消息队列2中的消息 40 msgrcv(msgid2,&msg,sizeof(msg.acc),0,0); 41 if(msg.mtype == M_SUCCESS){ 42 printf("开户成功!\n"); 43 printf("您的ID为:%d\n",msg.acc.id); 44 } 45 else{ 46 printf("开户失败!\n"); 47 } 48 } 49 //销户 50 void destroyUser(){ 51 struct Account acc; 52 printf("请输入需要销户的ID:"); 53 scanf("%d",&acc.id); 54 getchar(); 55 struct Msg msg; 56 msg.mtype = M_DESTROY; 57 msg.acc = acc; 58 //获取消息ID 59 getID(); 60 //将消息发送到消息队列1中 61 if(msgsnd(msgid1,&msg,sizeof(msg.acc),0) == -1) perror("msgsnd"),exit(-1); 62 //接收服务端消息 63 if(msgrcv(msgid2,&msg,sizeof(msg.acc),0,0) == -1) perror("msgrcv"),exit(-1); 64 if(msg.mtype == M_SUCCESS) 65 printf("销户成功\n"); 66 else 67 printf("销户失败\n"); 68 } 69 //存钱 70 void saveMoney(){ 71 struct Account acc; 72 printf("请输入您的ID:"); 73 scanf("%d",&acc.id); 74 getchar(); 75 printf("请输入您需要存的钱数:"); 76 scanf("%lf",&acc.balance); 77 getchar(); 78 79 getID(); 80 struct Msg msg = {M_SAVE,acc}; 81 if(msgsnd(msgid1,&msg,sizeof(acc),0) == -1) perror("msgsnd"),exit(-1); 82 if(msgrcv(msgid2,&msg,sizeof(acc),0,0) == -1) perror("msgrcv"),exit(-1); 83 if(msg.mtype == M_SUCCESS){ 84 printf("存钱成功\n"); 85 printf("您的余额为:%lf\n",msg.acc.balance); 86 } 87 else 88 printf("存钱失败!\n"); 89 } 90 //取钱 91 void getMoney(){ 92 struct Account acc; 93 printf("请输入您的ID:"); 94 scanf("%d",&acc.id); 95 getchar(); 96 printf("请输入您想取的金额:"); 97 scanf("%lf",&acc.balance); 98 99 getID();100 struct Msg msg = {M_TAKE,acc};101 102 if(msgsnd(msgid1,&msg,sizeof(acc),0) == -1) perror("msgsnd"),exit(-1);103 if(msgrcv(msgid2,&msg,sizeof(acc),0,0) == -1) perror("msgrcv"),exit(-1);104 if(msg.mtype == M_SUCCESS){105 printf("取钱成功\n");106 printf("您的余额为:%lf\n",msg.acc.balance);107 }108 else109 printf("取钱失败!\n");110 111 }112 //查询113 void checkMoney(){114 struct Account acc;115 printf("请输入您的ID:");116 scanf("%d",&acc.id);117 getchar();118 119 struct Msg msg = {M_QUERY,acc};120 121 getID();122 if(msgsnd(msgid1,&msg,sizeof(acc),0) == -1) perror("msgsnd"),exit(-1);123 if(msgrcv(msgid2,&msg,sizeof(acc),0,0) == -1) perror("msgrcv"),exit(-1);124 if(msg.mtype == M_SUCCESS){125 printf("查询成功\n");126 printf("您的余额为:%lf\n",msg.acc.balance);127 }128 else129 printf("查询失败!\n");130 }131 //转账132 void moveMoney(){133 struct Account acc;134 printf("请输入你的ID:%d:");135 scanf("%d",&acc.id);136 getchar();137 printf("请输入你需要转账的金额:");138 scanf("%lf",&acc.balance);139 getchar();140 141 getID();142 143 struct Msg msg;144 msg.mtype = M_TRANSF;145 msg.acc = acc;146 147 if(msgsnd(msgid1,&msg,sizeof(struct Account),0) == -1) perror("msgsnd"),exit(-1); 148 149 printf("请输入需要转入的ID:");150 scanf("%d",&acc.id);151 msg.mtype = M_TRANSF;152 msg.acc = acc;153 if(msgsnd(msgid1,&msg,sizeof(struct Account),0) == -1) perror("msgsnd"),exit(-1);154 155 if(msgrcv(msgid2,&msg,sizeof(struct Account),0,0) == -1) perror("msgrcv"),exit(-1);156 157 if(msg.mtype == M_SUCCESS){158 printf("转账成功!您的余额为:%lf",msg.acc.balance);159 }160 else161 printf("转账失败!\n");162 }163 164 //客户端界面165 void mainPage(){166 while(1){167 printf(" 欢迎使用迷你ATM机\n");168 printf("---------------------\n");169 printf("[1] 开户");170 printf(" [2] 销户\n");171 printf("[3] 存钱");172 printf(" [4] 取钱\n");173 printf("[5] 查询");174 printf(" [6] 转账\n");175 printf("[0] 退出\n");176 printf("---------------------\n");177 printf("请选择:\n");178 int num = 0;179 scanf("%d",&num);180 switch(num){181 case 1:createUser();break;182 case 2:destroyUser();break;183 case 3:saveMoney();break;184 case 4:getMoney();break;185 case 5:checkMoney();break;186 case 6:moveMoney();break;187 case 0:printf("谢谢使用,再见!\n");return ;188 default:printf("输入错误\n");189 }190 }191 }192 int main(){193 mainPage();194 return 0;195 }
View Code

dao.c:

1 #include "dao.h"  2 #include 
3 #include
4 #include
5 #include
6 #include
7 //定义一个文件来存储帐号 8 const char* ID_FILE = "id.dat"; 9 //生成不重复的帐号 10 int generator_id(){ 11 static int x = 100000; 12 if(access(ID_FILE,F_OK)==-1){
//判断文件是否存在,不存在返回-1 13 //不存在就创建 14 int fd = open(ID_FILE,O_WRONLY|O_CREAT|O_EXCL,0600); 15 if(fd == -1){ 16 perror("文件打开失败"); 17 return -1; 18 } 19 write(fd,&x,sizeof(x));//写入文件 20 close(fd); 21 return x; 22 } 23 //如果文件存 24 int fd = open(ID_FILE,O_RDWR); 25 if(fd == -1){ 26 perror("文件打开失败"); 27 return -1; 28 } 29 //将文件中的数值读到x中 30 read(fd,&x,sizeof(x)); 31 x++;//保证帐号唯一 32 //将读写位置置到文件开始头 33 lseek(fd,0,SEEK_SET); 34 //再将x的值写到文件中,覆盖原来的x 35 write(fd,&x,sizeof(x)); 36 close(fd); 37 return x; 38 } 39 40 //将一个新帐号 存到文件中 41 int createUser(struct Account acc){ 42 char filename[20]={}; 43 sprintf(filename,"%d.dat",acc.id);//为每个帐号建立一个文件 44 int fd = open(filename,O_WRONLY|O_CREAT|O_EXCL,0600); 45 if(fd == -1){ 46 perror("创建帐户文件失败"); 47 return -1; 48 } 49 if(write(fd,&acc,sizeof(acc)) < 0){ 50 return -1; 51 } 52 close(fd); 53 printf("创建用户成功\n"); 54 return 0; 55 } 56 57 //销户功能 58 int destroyUser(struct Account acc){ 59 char filename[20]; 60 sprintf(filename,"%d.dat",acc.id); 61 if(access(filename,F_OK) == -1) 62 return -1;//返回 -1 表示没有这个ID 63 if(remove(filename) == -1) 64 return 0;//返回 0 表示 销户失败 65 else 66 return 1;//返回 1 表示 销户成功 67 68 } 69 70 //存钱功能 71 int saveMoney(struct Account acc, struct Account *p){ 72 char filename[20]; 73 sprintf(filename,"%d.dat",acc.id); 74 if(access(filename,F_OK) == -1) 75 return -1; 76 int fd; 77 if((fd = open(filename,O_RDWR)) == -1) perror("open"),exit(-1); 78 79 if(read(fd,p,sizeof(struct Account)) < 0) perror("read"),exit(-1); 80 81 p->balance += acc.balance; 82 83 //printf("存过钱:%lf",p->balance); 84 lseek(fd,0,SEEK_SET); 85 if(write(fd,p,sizeof(struct Account)) < 0) 86 return 0; 87 else 88 return 1; 89 close(fd); 90 } 91 92 //取钱 93 int getMoney(struct Account acc, struct Account *p){ 94 char filename[20]; 95 sprintf(filename,"%d.dat",acc.id); 96 if(access(filename,F_OK) == -1) 97 return -1; 98 int fd; 99 if((fd = open(filename,O_RDWR)) == -1) perror("open"),exit(-1);100 101 if(read(fd,p,sizeof(struct Account)) < 0) perror("read"),exit(-1);102 103 if(p->balance < acc.balance){104 return 2; //余额不足105 }106 107 p->balance -= acc.balance;108 //printf("存过钱:%lf",p->balance);109 lseek(fd,0,SEEK_SET);110 if(write(fd,p,sizeof(struct Account)) < 0)111 return 0;112 else113 return 1;114 close(fd);115 }116 117 118 //查询余额功能119 int checkMoney(struct Account acc, struct Account *p){120 char filename[20];121 sprintf(filename,"%d.dat",acc.id);122 if(access(filename,F_OK) == -1)123 return -1;124 int fd;125 if((fd = open(filename,O_RDWR)) == -1) perror("open"),exit(-1);126 127 if(read(fd,p,sizeof(struct Account)) < 0)128 return 0;129 else130 return 1;131 close(fd);132 }133 134 //转账功能 acc1 --> from acc2 --> to135 int moveMoney(struct Account acc1, struct Account acc2, struct Account *p){136 char filename[20];137 sprintf(filename,"%d.dat",acc1.id);138 if(access(filename,F_OK) == -1)139 return -1;140 int fdfrom,fdto;141 if((fdfrom = open(filename,O_RDWR)) < 0) perror("open"),exit(-1);142 if(read(fdfrom,p,sizeof(struct Account)) < 0) return 0;143 //判断金额是否足够144 if(p->balance < acc1.balance) return 2;145 //判断转入的用户是否存在146 sprintf(filename,"%d.dat",acc2.id);147 if(access(filename,F_OK) == -1)148 return -1;149 150 p->balance -= acc1.balance;151 lseek(fdfrom,0,SEEK_SET);152 if(write(fdfrom,p,sizeof(struct Account)) < 0) perror("write"),exit(-1);153 close(fdfrom);154 155 if((fdto = open(filename,O_RDWR)) < 0) perror("open"),exit(-1);156 if(read(fdto,&acc2,sizeof(struct Account)) < 0) perror("open"),exit(-1);157 acc2.balance += acc1.balance;158 lseek(fdto,0,SEEK_SET); //需要把文件指针移动到文件开头159 if(write(fdto,&acc2,sizeof(struct Account)) < 0){160 return 0;161 close(fdto);162 }163 else{164 close(fdto);165 return 1;166 }167 168 }
View Code

 

link:  

  server:

    gcc server.c bank.c -o server

  client:  

    gcc client.c bank.c -o client

  open:

    gcc open.c bank.c dao.c -o open

转载地址:http://dphgx.baihongyu.com/

你可能感兴趣的文章
破解物联网落地困境-阿里云硬件接入最佳实践
查看>>
POJ 2503 字符串(两种方法)
查看>>
ArcGIS API for Flex 调用天地图、e都市瓦片地图
查看>>
【Yaml】Yaml学习笔记
查看>>
Mockito教程
查看>>
筛选并保留最后一次记录(如筛选最后一次缴纳电费的记录 )
查看>>
亚马逊开源 Neo-AI 框架,可优化 AI 模型提升部署速度
查看>>
新网盘时代,私有云斐讯天天链N1开启智能家居新生活!
查看>>
《西游伏妖篇》明星全阵容曝光 相约大年初一
查看>>
有一种手机能让你一见钟情,华为P20 Pro亮黑色图赏
查看>>
京东商城CEO徐雷年会演讲:我们抗住风霜 业务基本面良好
查看>>
德国飞往意大利民航客机机翼撕裂 途中乘客发现裂痕
查看>>
菜鸟保税仓成全球商家进中国首选 秒级通关领先全球
查看>>
退休延迟致新老职员共事 澳大利亚管理者面临挑战
查看>>
适当时公布?新西兰会否重启父母团聚移民引关注
查看>>
春运中的“洋导游”
查看>>
探访高铁“火花侠”驾驶火龙专列 脚下钢花飞溅
查看>>
2019年美联储加息若放缓有何影响?外汇局回应
查看>>
2018年访日外国游客消费创新高 中国大陆居首
查看>>
瓜子二手车保障消费新举措 首家12315维权服务站于呼市成立
查看>>