后台代码实现

  • 我的文件列表
    • Mian
    • 读取配置信息
    • 解析json登录token(cmd为count)
    • 解析jason(cmd不为count)
    • 获取用户文件个数
    • 获取用户文件列表
    • 源码
  • 共享文件列表
    • main
    • 获取共享文件个数
    • 前端分页请求包
    • 获得普通共享文件列表
    • 共享文件排行榜
    • 源码

我的文件列表

  • 业务逻辑是,点击我的文件,会在展示界面展示出该用户所有文件
  • 单机图标会显示选项下载,分享,删除,属性
  • 单机空白处会显示选型,会显示选项:按下载量排序/按下载量排序/刷新/上传
  • 其中上传操作也可以点击界面中的上传图标,然后会弹出窗口选择要上传的文件,上传过程是一个toolbar会显示进度在传输列表中

在这里插入图片描述

  • 实质是两张表联查 file_info, user_file_list ,做了物理分页,根据指令按照pv字段做升序降序排列

Mian

  • 读取配置文件 read_cfg();拿到数据库连接

  • while (FCGI_Accept() >= 0)等待连接

  • 业务主要分两种,一是只想知道用户有多少个文件,另一个是普通排序,按照pv升降序排序;均为post请求;为post请求时,由环境变量cmd拿到请求指令,由buf缓冲区拿到数据

  • cmd为count,获取用户文件个数if (strcmp(cmd, “count”) == 0) ,查表 get_user_files_count(user, ret); //获取用户文件个数

  • cmd为normal;pvacs;pvdesc;获取用户文件列表 get_user_filelist(cmd, user, start, count);

  • 需要注意的是,在fcgi程序中,直接fread是从标准输入读,就是从web服务器读;直接printf就是往标准输出,也是往web服务器(cgi程序利用I.O重定向技术)

      	int main(){//count 获取用户文件个数//display 获取用户文件信息,展示到前端char cmd[20];char user[USER_NAME_LEN];char token[TOKEN_LEN];//读取数据库配置信息read_cfg();//阻塞等待用户连接while (FCGI_Accept() >= 0){// 获取URL地址 "?" 后面的内容char *query = getenv("QUERY_STRING");//解析命令query_parse_key_value(query, "cmd", cmd, NULL);LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "cmd = %s\n", cmd);char *contentLength = getenv("CONTENT_LENGTH");int len;printf("Content-type: text/html\r\n\r\n");if( contentLength == NULL ){len = 0;}else{len = atoi(contentLength); //字符串转整型}if (len <= 0){printf("No data from standard input.<p>\n");LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "len = 0, No data from standard input\n");}else{char buf[4*1024] = {0};int ret = 0;ret = fread(buf, 1, len, stdin); //从标准输入(web服务器)读取内容if(ret == 0){LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "fread(buf, 1, len, stdin) err\n");continue;}LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "buf = %s\n", buf);if (strcmp(cmd, "count") == 0) //count 获取用户文件个数{get_count_json_info(buf, user, token); //通过json包获取用户名, token//验证登陆token,成功返回0,失败-1ret = verify_token(user, token); //util_cgi.hget_user_files_count(user, ret); //获取用户文件个数}//获取用户文件信息 127.0.0.1:80/myfiles&cmd=normal//按下载量升序 127.0.0.1:80/myfiles?cmd=pvasc//按下载量降序127.0.0.1:80/myfiles?cmd=pvdescelse{int start; //文件起点int count; //文件个数get_fileslist_json_info(buf, user, token, &start, &count); //通过json包获取信息LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "user = %s, token = %s, start = %d, count = %d\n", user, token, start, count);//验证登陆token,成功返回0,失败-1ret = verify_token(user, token); //util_cgi.hif(ret == 0){get_user_filelist(cmd, user, start, count); //获取用户文件列表}else{char *out = return_status("111"); //token验证失败错误码if(out != NULL){printf(out); //给前端反馈错误码free(out);}}}}}return 0;}
    

读取配置信息

  • 读取到MySQL配置文件信息

      void read_cfg(){//读取mysql数据库配置信息get_cfg_value(CFG_PATH, "mysql", "user", mysql_user);get_cfg_value(CFG_PATH, "mysql", "password", mysql_pwd);get_cfg_value(CFG_PATH, "mysql", "database", mysql_db);LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "mysql:[user=%s,pwd=%s,database=%s]", mysql_user, mysql_pwd, mysql_db);//读取redis配置信息//get_cfg_value(CFG_PATH, "redis", "ip", redis_ip);//get_cfg_value(CFG_PATH, "redis", "port", redis_port);//LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "redis:[ip=%s,port=%s]\n", redis_ip, redis_port);}
    

解析json登录token(cmd为count)

  • cmd为count时,此时的json包格式为

      {"token": "9e894efc0b2a898a82765d0a7f2c94cb",user:xxxx}
    
  • 此时,解析jason拿到token和username

      //解析的json包, 登陆tokenint get_count_json_info(char *buf, char *user, char *token){int ret = 0;/*json数据如下{"token": "9e894efc0b2a898a82765d0a7f2c94cb",user:xxxx}*///解析json包//解析一个json字符串为cJSON对象cJSON * root = cJSON_Parse(buf);if(NULL == root){LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "cJSON_Parse err\n");ret = -1;goto END;}//返回指定字符串对应的json对象//用户cJSON *child1 = cJSON_GetObjectItem(root, "user");if(NULL == child1){LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "cJSON_GetObjectItem err\n");ret = -1;goto END;}//LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "child1->valuestring = %s\n", child1->valuestring);strcpy(user, child1->valuestring); //拷贝内容//登陆tokencJSON *child2 = cJSON_GetObjectItem(root, "token");if(NULL == child2){LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "cJSON_GetObjectItem err\n");ret = -1;goto END;}//LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "child2->valuestring = %s\n", child2->valuestring);strcpy(token, child2->valuestring); //拷贝内容END:if(root != NULL){cJSON_Delete(root);//删除json对象root = NULL;}return ret;}
    

解析jason(cmd不为count)

  • 作用是为了拿到user,token,start,count,用来给普通/升/降序同时物理分页查询准备

      	//解析的json包int get_fileslist_json_info(char *buf, char *user, char *token, int *p_start, int *p_count){int ret = 0;/*json数据如下{"user": "yoyo""token": xxxx"start": 0"count": 10}*///解析json包//解析一个json字符串为cJSON对象cJSON * root = cJSON_Parse(buf);if(NULL == root){LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "cJSON_Parse err\n");ret = -1;goto END;}//返回指定字符串对应的json对象//用户cJSON *child1 = cJSON_GetObjectItem(root, "user");if(NULL == child1){LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "cJSON_GetObjectItem err\n");ret = -1;goto END;}//LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "child1->valuestring = %s\n", child1->valuestring);strcpy(user, child1->valuestring); //拷贝内容//tokencJSON *child2 = cJSON_GetObjectItem(root, "token");if(NULL == child2){LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "cJSON_GetObjectItem err\n");ret = -1;goto END;}strcpy(token, child2->valuestring); //拷贝内容//文件起点cJSON *child3 = cJSON_GetObjectItem(root, "start");if(NULL == child3){LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "cJSON_GetObjectItem err\n");ret = -1;goto END;}*p_start = child3->valueint;//文件请求个数cJSON *child4 = cJSON_GetObjectItem(root, "count");if(NULL == child4){LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "cJSON_GetObjectItem err\n");ret = -1;goto END;}*p_count = child4->valueint;END:if(root != NULL){cJSON_Delete(root);//删除json对象root = NULL;}return ret;}
    

获取用户文件个数

  • 数据库查询操作 sprintf(sql_cmd, “select count from user_file_count where user=”%s"", user);

  • 将结果封装进tmp int ret2 = process_result_one(conn, sql_cmd, tmp);

    		//获取用户文件个数void get_user_files_count(char *user, int ret){char sql_cmd[SQL_MAX_LEN] = {0};MYSQL *conn = NULL;long line = 0;//connect the databaseconn = msql_conn(mysql_user, mysql_pwd, mysql_db);if (conn == NULL){LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "msql_conn err\n");goto END;}//设置数据库编码,主要处理中文编码问题mysql_query(conn, "set names utf8");sprintf(sql_cmd, "select count from user_file_count where user=\"%s\"", user);char tmp[512] = {0};//返回值: 0成功并保存记录集,1没有记录集,2有记录集但是没有保存,-1失败int ret2 = process_result_one(conn, sql_cmd, tmp); //指向sql语句if(ret2 != 0){LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "%s 操作失败\n", sql_cmd);goto END;}line = atol(tmp); //字符串转长整形END:if(conn != NULL){mysql_close(conn);}LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "line = %ld\n", line);//给前端反馈的信息return_login_status(line, ret);}
    

    获取用户文件列表

  • get_user_filelist(char *cmd, char *user, int start, int count)需要参数cmd,user,start,count(这两个参数在前端设置好)

      - cmd为normal 普通查询只做了物理分页,==limit %d, %d", user, start, count==if(strcmp(cmd, "normal") == 0) //获取用户文件信息{//sql语句sprintf(sql_cmd, "select user_file_list.*, file_info.url, file_info.size, file_info.type from file_info, user_file_list where user = '%s' and file_info.md5 = user_file_list.md5 limit %d, %d", user, start, count);}	- cmd为pvasc升序查询按照pv排序同时做了物理分页,==order by pv asc limit %d, %d", user, start, count)==else if(strcmp(cmd, "pvasc") == 0) //按下载量升序{//sql语句sprintf(sql_cmd, "select user_file_list.*, file_info.url, file_info.size, file_info.type from file_info, user_file_list where user = '%s' and file_info.md5 = user_file_list.md5  order by pv asc limit %d, %d", user, start, count);}-  cmd为pvdesc降序查询按照pv排序同时做了物理分页,==order by pv desc limit %d, %d", user, start, count==else if(strcmp(cmd, "pvdesc") == 0) //按下载量降序{//sql语句sprintf(sql_cmd, "select user_file_list.*, file_info.url, file_info.size, file_info.type from file_info, user_file_list where user = '%s' and file_info.md5 = user_file_list.md5 order by pv desc limit %d, %d", user, start, count);}
    
  • 进行查询 if (mysql_query(conn, sql_cmd) != 0)

  • 生成结果集 res_set = mysql_store_result(conn);/生成结果集/

  • 对结果集进行处理

    • 数据库的查询结果是一行行的,游标依次往下拿到每一个字段的值,封装进jason对象 cJSON_AddItemToArray(array, item);
    • 再封装进数组cJSON_AddItemToObject(root, “files”, array)代表所有文件的列表,
    • 再将该数组封装进root根对象转为字符串发送前端
      int get_user_filelist(char *cmd, char *user, int start, int count){int ret = 0;char sql_cmd[SQL_MAX_LEN] = {0};MYSQL *conn = NULL;cJSON *root = NULL;cJSON *array =NULL;char *out = NULL;char *out2 = NULL;MYSQL_RES *res_set = NULL;//connect the databaseconn = msql_conn(mysql_user, mysql_pwd, mysql_db);if (conn == NULL){LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "msql_conn err\n");ret = -1;goto END;}//设置数据库编码,主要处理中文编码问题mysql_query(conn, "set names utf8");//多表指定行范围查询if(strcmp(cmd, "normal") == 0) //获取用户文件信息{//sql语句sprintf(sql_cmd, "select user_file_list.*, file_info.url, file_info.size, file_info.type from file_info, user_file_list where user = '%s' and file_info.md5 = user_file_list.md5 limit %d, %d", user, start, count);}else if(strcmp(cmd, "pvasc") == 0) //按下载量升序{//sql语句sprintf(sql_cmd, "select user_file_list.*, file_info.url, file_info.size, file_info.type from file_info, user_file_list where user = '%s' and file_info.md5 = user_file_list.md5  order by pv asc limit %d, %d", user, start, count);}else if(strcmp(cmd, "pvdesc") == 0) //按下载量降序{//sql语句sprintf(sql_cmd, "select user_file_list.*, file_info.url, file_info.size, file_info.type from file_info, user_file_list where user = '%s' and file_info.md5 = user_file_list.md5 order by pv desc limit %d, %d", user, start, count);}LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "%s 在操作\n", sql_cmd);if (mysql_query(conn, sql_cmd) != 0){LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "%s 操作失败:%s\n", sql_cmd, mysql_error(conn));ret = -1;goto END;}res_set = mysql_store_result(conn);/*生成结果集*/if (res_set == NULL){LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "smysql_store_result error: %s!\n", mysql_error(conn));ret = -1;goto END;}ulong line = 0;//mysql_num_rows接受由mysql_store_result返回的结果结构集,并返回结构集中的行数line = mysql_num_rows(res_set);if (line == 0)//没有结果{LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "mysql_num_rows(res_set) failed:%s\n", mysql_error(conn));ret = -1;goto END;}MYSQL_ROW row;root = cJSON_CreateObject();array = cJSON_CreateArray();// mysql_fetch_row从使用mysql_store_result得到的结果结构中提取一行,并把它放到一个行结构中。// 当数据用完或发生错误时返回NULL.while ((row = mysql_fetch_row(res_set)) != NULL){//array[i]:cJSON* item = cJSON_CreateObject();//mysql_num_fields获取结果中列的个数/*for(i = 0; i < mysql_num_fields(res_set); i++){if(row[i] != NULL){}}*//*{"user": "yoyo","md5": "e8ea6031b779ac26c319ddf949ad9d8d","time": "2017-02-26 21:35:25","filename": "test.mp4","share_status": 0,"pv": 0,"url": "http://192.168.31.109:80/group1/M00/00/00/wKgfbViy2Z2AJ-FTAaM3As-g3Z0782.mp4","size": 27473666,"type": "mp4"}*///-- user	文件所属用户if(row[0] != NULL){cJSON_AddStringToObject(item, "user", row[0]);}//-- md5 文件md5if(row[1] != NULL){cJSON_AddStringToObject(item, "md5", row[1]);}//-- createtime 文件创建时间if(row[2] != NULL){cJSON_AddStringToObject(item, "time", row[2]);}//-- filename 文件名字if(row[3] != NULL){cJSON_AddStringToObject(item, "filename", row[3]);}//-- shared_status 共享状态, 0为没有共享, 1为共享if(row[4] != NULL){cJSON_AddNumberToObject(item, "share_status", atoi( row[4] ));}//-- pv 文件下载量,默认值为0,下载一次加1if(row[5] != NULL){cJSON_AddNumberToObject(item, "pv", atol( row[5] ));}//-- url 文件urlif(row[6] != NULL){cJSON_AddStringToObject(item, "url", row[6]);}//-- size 文件大小, 以字节为单位if(row[7] != NULL){cJSON_AddNumberToObject(item, "size", atol( row[7] ));}//-- type 文件类型: png, zip, mp4……if(row[8] != NULL){cJSON_AddStringToObject(item, "type", row[8]);}cJSON_AddItemToArray(array, item);}cJSON_AddItemToObject(root, "files", array);out = cJSON_Print(root);LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "%s\n", out);END:if(ret == 0){printf("%s", out); //给前端反馈信息}else{   //失败/*获取用户文件列表:成功:文件列表json失败:{"code": "015"}*/out2 = NULL;out2 = return_status("015");}if(out2 != NULL){printf(out2); //给前端反馈错误码free(out2);}if(res_set != NULL){//完成所有对数据的操作后,调用mysql_free_result来善后处理mysql_free_result(res_set);}if(conn != NULL){mysql_close(conn);}if(root != NULL){cJSON_Delete(root);}if(out != NULL){free(out);}return ret;}
    

源码

	/*** @file myfiles_cgi.c* @brief  用户列表展示CGI程序* @author Mike* @version 2.0* @date 2017年2月27日*/#include "fcgi_config.h"#include "fcgi_stdio.h"#include <stdio.h>#include <stdlib.h>#include <string.h>#include "make_log.h" //日志头文件#include "util_cgi.h"#include "deal_mysql.h"#include "cfg.h"#include "cJSON.h"#include <sys/time.h>#define MYFILES_LOG_MODULE       "cgi"#define MYFILES_LOG_PROC         "myfiles"//mysql 数据库配置信息 用户名, 密码, 数据库名称static char mysql_user[128] = {0};static char mysql_pwd[128] = {0};static char mysql_db[128] = {0};//redis 服务器ip、端口//static char redis_ip[30] = {0};//static char redis_port[10] = {0};//读取配置信息void read_cfg(){//读取mysql数据库配置信息get_cfg_value(CFG_PATH, "mysql", "user", mysql_user);get_cfg_value(CFG_PATH, "mysql", "password", mysql_pwd);get_cfg_value(CFG_PATH, "mysql", "database", mysql_db);LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "mysql:[user=%s,pwd=%s,database=%s]", mysql_user, mysql_pwd, mysql_db);//读取redis配置信息//get_cfg_value(CFG_PATH, "redis", "ip", redis_ip);//get_cfg_value(CFG_PATH, "redis", "port", redis_port);//LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "redis:[ip=%s,port=%s]\n", redis_ip, redis_port);}//解析的json包, 登陆tokenint get_count_json_info(char *buf, char *user, char *token){int ret = 0;/*json数据如下{"token": "9e894efc0b2a898a82765d0a7f2c94cb",user:xxxx}*///解析json包//解析一个json字符串为cJSON对象cJSON * root = cJSON_Parse(buf);if(NULL == root){LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "cJSON_Parse err\n");ret = -1;goto END;}//返回指定字符串对应的json对象//用户cJSON *child1 = cJSON_GetObjectItem(root, "user");if(NULL == child1){LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "cJSON_GetObjectItem err\n");ret = -1;goto END;}//LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "child1->valuestring = %s\n", child1->valuestring);strcpy(user, child1->valuestring); //拷贝内容//登陆tokencJSON *child2 = cJSON_GetObjectItem(root, "token");if(NULL == child2){LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "cJSON_GetObjectItem err\n");ret = -1;goto END;}//LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "child2->valuestring = %s\n", child2->valuestring);strcpy(token, child2->valuestring); //拷贝内容END:if(root != NULL){cJSON_Delete(root);//删除json对象root = NULL;}return ret;}//返回前端情况void return_login_status(long num, int token_flag){char *out = NULL;char *token;char num_buf[128] = {0};if(token_flag == 0){token = "110"; //成功}else{token = "111"; //失败}//数字sprintf(num_buf, "%ld", num);cJSON *root = cJSON_CreateObject();  //创建json项目cJSON_AddStringToObject(root, "num", num_buf);// {"num":"1111"}cJSON_AddStringToObject(root, "code", token);// {"code":"110"}out = cJSON_Print(root);//cJSON to string(char *)cJSON_Delete(root);if(out != NULL){printf(out); //给前端反馈信息free(out); //记得释放}}//获取用户文件个数void get_user_files_count(char *user, int ret){char sql_cmd[SQL_MAX_LEN] = {0};MYSQL *conn = NULL;long line = 0;//connect the databaseconn = msql_conn(mysql_user, mysql_pwd, mysql_db);if (conn == NULL){LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "msql_conn err\n");goto END;}//设置数据库编码,主要处理中文编码问题mysql_query(conn, "set names utf8");sprintf(sql_cmd, "select count from user_file_count where user=\"%s\"", user);char tmp[512] = {0};//返回值: 0成功并保存记录集,1没有记录集,2有记录集但是没有保存,-1失败int ret2 = process_result_one(conn, sql_cmd, tmp); //指向sql语句if(ret2 != 0){LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "%s 操作失败\n", sql_cmd);goto END;}line = atol(tmp); //字符串转长整形END:if(conn != NULL){mysql_close(conn);}LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "line = %ld\n", line);//给前端反馈的信息return_login_status(line, ret);}//解析的json包int get_fileslist_json_info(char *buf, char *user, char *token, int *p_start, int *p_count){int ret = 0;/*json数据如下{"user": "yoyo""token": xxxx"start": 0"count": 10}*///解析json包//解析一个json字符串为cJSON对象cJSON * root = cJSON_Parse(buf);if(NULL == root){LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "cJSON_Parse err\n");ret = -1;goto END;}//返回指定字符串对应的json对象//用户cJSON *child1 = cJSON_GetObjectItem(root, "user");if(NULL == child1){LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "cJSON_GetObjectItem err\n");ret = -1;goto END;}//LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "child1->valuestring = %s\n", child1->valuestring);strcpy(user, child1->valuestring); //拷贝内容//tokencJSON *child2 = cJSON_GetObjectItem(root, "token");if(NULL == child2){LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "cJSON_GetObjectItem err\n");ret = -1;goto END;}strcpy(token, child2->valuestring); //拷贝内容//文件起点cJSON *child3 = cJSON_GetObjectItem(root, "start");if(NULL == child3){LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "cJSON_GetObjectItem err\n");ret = -1;goto END;}*p_start = child3->valueint;//文件请求个数cJSON *child4 = cJSON_GetObjectItem(root, "count");if(NULL == child4){LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "cJSON_GetObjectItem err\n");ret = -1;goto END;}*p_count = child4->valueint;END:if(root != NULL){cJSON_Delete(root);//删除json对象root = NULL;}return ret;}//获取用户文件列表//获取用户文件信息 127.0.0.1:80/myfiles&cmd=normal//按下载量升序 127.0.0.1:80/myfiles?cmd=pvasc//按下载量降序127.0.0.1:80/myfiles?cmd=pvdescint get_user_filelist(char *cmd, char *user, int start, int count){int ret = 0;char sql_cmd[SQL_MAX_LEN] = {0};MYSQL *conn = NULL;cJSON *root = NULL;cJSON *array =NULL;char *out = NULL;char *out2 = NULL;MYSQL_RES *res_set = NULL;//connect the databaseconn = msql_conn(mysql_user, mysql_pwd, mysql_db);if (conn == NULL){LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "msql_conn err\n");ret = -1;goto END;}//设置数据库编码,主要处理中文编码问题mysql_query(conn, "set names utf8");//多表指定行范围查询if(strcmp(cmd, "normal") == 0) //获取用户文件信息{//sql语句sprintf(sql_cmd, "select user_file_list.*, file_info.url, file_info.size, file_info.type from file_info, user_file_list where user = '%s' and file_info.md5 = user_file_list.md5 limit %d, %d", user, start, count);}else if(strcmp(cmd, "pvasc") == 0) //按下载量升序{//sql语句sprintf(sql_cmd, "select user_file_list.*, file_info.url, file_info.size, file_info.type from file_info, user_file_list where user = '%s' and file_info.md5 = user_file_list.md5  order by pv asc limit %d, %d", user, start, count);}else if(strcmp(cmd, "pvdesc") == 0) //按下载量降序{//sql语句sprintf(sql_cmd, "select user_file_list.*, file_info.url, file_info.size, file_info.type from file_info, user_file_list where user = '%s' and file_info.md5 = user_file_list.md5 order by pv desc limit %d, %d", user, start, count);}LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "%s 在操作\n", sql_cmd);if (mysql_query(conn, sql_cmd) != 0){LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "%s 操作失败:%s\n", sql_cmd, mysql_error(conn));ret = -1;goto END;}res_set = mysql_store_result(conn);/*生成结果集*/if (res_set == NULL){LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "smysql_store_result error: %s!\n", mysql_error(conn));ret = -1;goto END;}ulong line = 0;//mysql_num_rows接受由mysql_store_result返回的结果结构集,并返回结构集中的行数line = mysql_num_rows(res_set);if (line == 0)//没有结果{LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "mysql_num_rows(res_set) failed:%s\n", mysql_error(conn));ret = -1;goto END;}MYSQL_ROW row;root = cJSON_CreateObject();array = cJSON_CreateArray();// mysql_fetch_row从使用mysql_store_result得到的结果结构中提取一行,并把它放到一个行结构中。// 当数据用完或发生错误时返回NULL.while ((row = mysql_fetch_row(res_set)) != NULL){//array[i]:cJSON* item = cJSON_CreateObject();//mysql_num_fields获取结果中列的个数/*for(i = 0; i < mysql_num_fields(res_set); i++){if(row[i] != NULL){}}*//*{"user": "yoyo","md5": "e8ea6031b779ac26c319ddf949ad9d8d","time": "2017-02-26 21:35:25","filename": "test.mp4","share_status": 0,"pv": 0,"url": "http://192.168.31.109:80/group1/M00/00/00/wKgfbViy2Z2AJ-FTAaM3As-g3Z0782.mp4","size": 27473666,"type": "mp4"}*///-- user	文件所属用户if(row[0] != NULL){cJSON_AddStringToObject(item, "user", row[0]);}//-- md5 文件md5if(row[1] != NULL){cJSON_AddStringToObject(item, "md5", row[1]);}//-- createtime 文件创建时间if(row[2] != NULL){cJSON_AddStringToObject(item, "time", row[2]);}//-- filename 文件名字if(row[3] != NULL){cJSON_AddStringToObject(item, "filename", row[3]);}//-- shared_status 共享状态, 0为没有共享, 1为共享if(row[4] != NULL){cJSON_AddNumberToObject(item, "share_status", atoi( row[4] ));}//-- pv 文件下载量,默认值为0,下载一次加1if(row[5] != NULL){cJSON_AddNumberToObject(item, "pv", atol( row[5] ));}//-- url 文件urlif(row[6] != NULL){cJSON_AddStringToObject(item, "url", row[6]);}//-- size 文件大小, 以字节为单位if(row[7] != NULL){cJSON_AddNumberToObject(item, "size", atol( row[7] ));}//-- type 文件类型: png, zip, mp4……if(row[8] != NULL){cJSON_AddStringToObject(item, "type", row[8]);}cJSON_AddItemToArray(array, item);}cJSON_AddItemToObject(root, "files", array);out = cJSON_Print(root);LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "%s\n", out);END:if(ret == 0){printf("%s", out); //给前端反馈信息}else{   //失败/*获取用户文件列表:成功:文件列表json失败:{"code": "015"}*/out2 = NULL;out2 = return_status("015");}if(out2 != NULL){printf(out2); //给前端反馈错误码free(out2);}if(res_set != NULL){//完成所有对数据的操作后,调用mysql_free_result来善后处理mysql_free_result(res_set);}if(conn != NULL){mysql_close(conn);}if(root != NULL){cJSON_Delete(root);}if(out != NULL){free(out);}return ret;}int main(){//count 获取用户文件个数//display 获取用户文件信息,展示到前端char cmd[20];char user[USER_NAME_LEN];char token[TOKEN_LEN];//读取数据库配置信息read_cfg();//阻塞等待用户连接while (FCGI_Accept() >= 0){// 获取URL地址 "?" 后面的内容char *query = getenv("QUERY_STRING");//解析命令query_parse_key_value(query, "cmd", cmd, NULL);LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "cmd = %s\n", cmd);char *contentLength = getenv("CONTENT_LENGTH");int len;printf("Content-type: text/html\r\n\r\n");if( contentLength == NULL ){len = 0;}else{len = atoi(contentLength); //字符串转整型}if (len <= 0){printf("No data from standard input.<p>\n");LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "len = 0, No data from standard input\n");}else{char buf[4*1024] = {0};int ret = 0;ret = fread(buf, 1, len, stdin); //从标准输入(web服务器)读取内容if(ret == 0){LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "fread(buf, 1, len, stdin) err\n");continue;}LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "buf = %s\n", buf);if (strcmp(cmd, "count") == 0) //count 获取用户文件个数{get_count_json_info(buf, user, token); //通过json包获取用户名, token//验证登陆token,成功返回0,失败-1ret = verify_token(user, token); //util_cgi.hget_user_files_count(user, ret); //获取用户文件个数}//获取用户文件信息 127.0.0.1:80/myfiles&cmd=normal//按下载量升序 127.0.0.1:80/myfiles?cmd=pvasc//按下载量降序127.0.0.1:80/myfiles?cmd=pvdescelse{int start; //文件起点int count; //文件个数get_fileslist_json_info(buf, user, token, &start, &count); //通过json包获取信息LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "user = %s, token = %s, start = %d, count = %d\n", user, token, start, count);//验证登陆token,成功返回0,失败-1ret = verify_token(user, token); //util_cgi.hif(ret == 0){get_user_filelist(cmd, user, start, count); //获取用户文件列表}else{char *out = return_status("111"); //token验证失败错误码if(out != NULL){printf(out); //给前端反馈错误码free(out);}}}}}return 0;}

共享文件列表

业务逻辑,点击QT界面的共享列表,会显示背当前用户共享的文件,且是普通排序

  • 点击图标会显示取消分享,属性
  • 点击空白处会选项显示排行榜

共享文件列表主要涉及的是file_info和share_file_list两张表查询

main

  • cmd为count,代表获取该用户共享出去的文件个数,只返回给前端共享了的文件个数

       if (strcmp(cmd, "count") == 0) //count 获取用户文件个数{get_share_files_count(); //获取共享文件个数}
    
  • 解析jason包拿到拿到count,start

  • 如果cmd为normal,则就按照查询顺序显示共享文件列表

  • 如果cmd为pvdesc,则将查询结果按照pv字段降序排列显示共享文件列表

  • 如果cmd为pvasc,则将查询结果按照pv字段升序排列显示为共享文件列表

获取共享文件个数

  • get_share_files_count(),当cmd为count,则只需要查询共享文件个数

  • 从user_file_count查询处用户的共享文件个数

		void get_share_files_count(){char sql_cmd[SQL_MAX_LEN] = {0};MYSQL *conn = NULL;long line = 0;//connect the databaseconn = msql_conn(mysql_user, mysql_pwd, mysql_db);if (conn == NULL){LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "msql_conn err\n");goto END;}//设置数据库编码,主要处理中文编码问题mysql_query(conn, "set names utf8");sprintf(sql_cmd, "select count from user_file_count where user=\"%s\"", "xxx_share_xxx_file_xxx_list_xxx_count_xxx");char tmp[512] = {0};int ret2 = process_result_one(conn, sql_cmd, tmp); //指向sql语句if(ret2 != 0){LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "%s 操作失败\n", sql_cmd);goto END;}line = atol(tmp); //字符串转长整形END:if(conn != NULL){mysql_close(conn);}LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "line = %ld\n", line);printf("%ld", line); //给前端反馈的信息}

前端分页请求包

  • get_fileslist_json_info

  • 这个包是前端发送的post数据,封装的是物理分页的信息,然后再根据URL上的指令去做业务逻辑判断

  • 解析包拿到start,count

      //解析的json包int get_fileslist_json_info(char *buf, int *p_start, int *p_count){int ret = 0;/*json数据如下{"start": 0"count": 10}*///解析json包//解析一个json字符串为cJSON对象cJSON * root = cJSON_Parse(buf);if(NULL == root){LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "cJSON_Parse err\n");ret = -1;goto END;}//文件起点cJSON *child2 = cJSON_GetObjectItem(root, "start");if(NULL == child2){LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "cJSON_GetObjectItem err\n");ret = -1;goto END;}*p_start = child2->valueint;//文件请求个数cJSON *child3 = cJSON_GetObjectItem(root, "count");if(NULL == child3){LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "cJSON_GetObjectItem err\n");ret = -1;goto END;}*p_count = child3->valueint;END:if(root != NULL){cJSON_Delete(root);//删除json对象root = NULL;}return ret;}
    

获得普通共享文件列表

  • get_share_filelist(int start, int count)

  • 查出share_file_list所有记录,同时根据md5查file_info表部分文件信息并进行物理分页

  • 从结果集中将记录进行一行行封装成对象;将封装好的对象加入数组;将数组加到跟对象root,将root转为字符串输出

      //获取共享文件列表//获取用户文件信息 127.0.0.1:80/sharefiles&cmd=normalint get_share_filelist(int start, int count){int ret = 0;char sql_cmd[SQL_MAX_LEN] = {0};MYSQL *conn = NULL;cJSON *root = NULL;cJSON *array =NULL;char *out = NULL;char *out2 = NULL;MYSQL_RES *res_set = NULL;//connect the databaseconn = msql_conn(mysql_user, mysql_pwd, mysql_db);if (conn == NULL){LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "msql_conn err\n");ret = -1;goto END;}//设置数据库编码,主要处理中文编码问题mysql_query(conn, "set names utf8");//sql语句sprintf(sql_cmd, "select share_file_list.*, file_info.url, file_info.size, file_info.type from file_info, share_file_list where file_info.md5 = share_file_list.md5 limit %d, %d", start, count);LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "%s 在操作\n", sql_cmd);if (mysql_query(conn, sql_cmd) != 0){LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "%s 操作失败: %s\n", sql_cmd, mysql_error(conn));ret = -1;goto END;}res_set = mysql_store_result(conn);/*生成结果集*/if (res_set == NULL){LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "smysql_store_result error!\n");ret = -1;goto END;}ulong line = 0;//mysql_num_rows接受由mysql_store_result返回的结果结构集,并返回结构集中的行数line = mysql_num_rows(res_set);if (line == 0){LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "mysql_num_rows(res_set) failed\n");ret = -1;goto END;}MYSQL_ROW row;root = cJSON_CreateObject();array = cJSON_CreateArray();// mysql_fetch_row从使用mysql_store_result得到的结果结构中提取一行,并把它放到一个行结构中。// 当数据用完或发生错误时返回NULL.while ((row = mysql_fetch_row(res_set)) != NULL){//array[i]:cJSON* item = cJSON_CreateObject();//mysql_num_fields获取结果中列的个数/*for(i = 0; i < mysql_num_fields(res_set); i++){if(row[i] != NULL){}}*//*{"user": "yoyo","md5": "e8ea6031b779ac26c319ddf949ad9d8d","time": "2017-02-26 21:35:25","filename": "test.mp4","share_status": 1,"pv": 0,"url": "http://192.168.31.109:80/group1/M00/00/00/wKgfbViy2Z2AJ-FTAaM3As-g3Z0782.mp4","size": 27473666,"type": "mp4"}*///-- user	文件所属用户if(row[0] != NULL){cJSON_AddStringToObject(item, "user", row[0]);}//-- md5 文件md5if(row[1] != NULL){cJSON_AddStringToObject(item, "md5", row[1]);}//-- createtime 文件创建时间if(row[2] != NULL){cJSON_AddStringToObject(item, "time", row[2]);}//-- filename 文件名字if(row[3] != NULL){cJSON_AddStringToObject(item, "filename", row[3]);}//-- shared_status 共享状态, 0为没有共享, 1为共享cJSON_AddNumberToObject(item, "share_status", 1);//-- pv 文件下载量,默认值为0,下载一次加1if(row[4] != NULL){cJSON_AddNumberToObject(item, "pv", atol( row[4] ));}//-- url 文件urlif(row[5] != NULL){cJSON_AddStringToObject(item, "url", row[5]);}//-- size 文件大小, 以字节为单位if(row[6] != NULL){cJSON_AddNumberToObject(item, "size", atol( row[6] ));}//-- type 文件类型: png, zip, mp4……if(row[7] != NULL){cJSON_AddStringToObject(item, "type", row[7]);}cJSON_AddItemToArray(array, item);}cJSON_AddItemToObject(root, "files", array);out = cJSON_Print(root);LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "%s\n", out);END:if(ret == 0){printf("%s", out); //给前端反馈信息}else{   //失败out2 = NULL;out2 = return_status("015");}if(out2 != NULL){printf(out2); //给前端反馈错误码free(out2);}if(res_set != NULL){//完成所有对数据的操作后,调用mysql_free_result来善后处理mysql_free_result(res_set);}if(conn != NULL){mysql_close(conn);}if(root != NULL){cJSON_Delete(root);}if(out != NULL){free(out);}return ret;}
    

共享文件排行榜

  • 操作redis “FILE_NAME_HASH”和“FILE_PUBLIC_ZSET”两张表和MySQL“share_file_list”,完成redis和MySQL数据交互
  • int get_ranking_filelist(int start, int count)
  • 拿到mysql中共享文件的数量,拿到redis中的共享文件的数量进行比较
    • 不相等,更新redis数据,删除redis中所有数据( FILE_PUBLIC_ZSET,FILE_NAME_HASH) ;再将mysql中的数据导入到mysql:查出share_file_list中md5,filename和pv字段,游标提取结果集每一行(md5+filename组成fileid和pv字段作为score一起添加到zset;将组合的fileid作为fileld,filename作为value添加到hash表)
  • 将zset按照score降序排序,其中排序有分页参数start,end;
  • 将排序后的集合从FILE_NAME_HASH取出filename,从FILE_PUBLIC_ZSET取出pv字段封装成对象;再将数据封装成对象转字符串后发送给前端 printf("%s", out),会在QT界面点击排行榜时候显示

源码

	/*** @file sharefiles_cgi.c* @brief  共享文件列表展示CGI程序* @author Mike* @version 2.0* @date 2017年3月7日21:46:57*/#include "fcgi_config.h"#include "fcgi_stdio.h"#include <stdio.h>#include <stdlib.h>#include <string.h>#include "make_log.h" //日志头文件#include "util_cgi.h"#include "deal_mysql.h"#include "redis_keys.h"#include "redis_op.h"#include "cfg.h"#include "cJSON.h"#include <sys/time.h>#define SHAREFILES_LOG_MODULE       "cgi"#define SHAREFILES_LOG_PROC         "sharefiles"//mysql 数据库配置信息 用户名, 密码, 数据库名称static char mysql_user[128] = {0};static char mysql_pwd[128] = {0};static char mysql_db[128] = {0};//redis 服务器ip、端口static char redis_ip[30] = {0};static char redis_port[10] = {0};//读取配置信息void read_cfg(){//读取mysql数据库配置信息get_cfg_value(CFG_PATH, "mysql", "user", mysql_user);get_cfg_value(CFG_PATH, "mysql", "password", mysql_pwd);get_cfg_value(CFG_PATH, "mysql", "database", mysql_db);LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "mysql:[user=%s,pwd=%s,database=%s]", mysql_user, mysql_pwd, mysql_db);//读取redis配置信息get_cfg_value(CFG_PATH, "redis", "ip", redis_ip);get_cfg_value(CFG_PATH, "redis", "port", redis_port);LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "redis:[ip=%s,port=%s]\n", redis_ip, redis_port);}//获取共享文件个数void get_share_files_count(){char sql_cmd[SQL_MAX_LEN] = {0};MYSQL *conn = NULL;long line = 0;//connect the databaseconn = msql_conn(mysql_user, mysql_pwd, mysql_db);if (conn == NULL){LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "msql_conn err\n");goto END;}//设置数据库编码,主要处理中文编码问题mysql_query(conn, "set names utf8");sprintf(sql_cmd, "select count from user_file_count where user=\"%s\"", "xxx_share_xxx_file_xxx_list_xxx_count_xxx");char tmp[512] = {0};int ret2 = process_result_one(conn, sql_cmd, tmp); //指向sql语句if(ret2 != 0){LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "%s 操作失败\n", sql_cmd);goto END;}line = atol(tmp); //字符串转长整形END:if(conn != NULL){mysql_close(conn);}LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "line = %ld\n", line);printf("%ld", line); //给前端反馈的信息}//解析的json包int get_fileslist_json_info(char *buf, int *p_start, int *p_count){int ret = 0;/*json数据如下{"start": 0"count": 10}*///解析json包//解析一个json字符串为cJSON对象cJSON * root = cJSON_Parse(buf);if(NULL == root){LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "cJSON_Parse err\n");ret = -1;goto END;}//文件起点cJSON *child2 = cJSON_GetObjectItem(root, "start");if(NULL == child2){LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "cJSON_GetObjectItem err\n");ret = -1;goto END;}*p_start = child2->valueint;//文件请求个数cJSON *child3 = cJSON_GetObjectItem(root, "count");if(NULL == child3){LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "cJSON_GetObjectItem err\n");ret = -1;goto END;}*p_count = child3->valueint;END:if(root != NULL){cJSON_Delete(root);//删除json对象root = NULL;}return ret;}//获取共享文件列表//获取用户文件信息 127.0.0.1:80/sharefiles&cmd=normalint get_share_filelist(int start, int count){int ret = 0;char sql_cmd[SQL_MAX_LEN] = {0};MYSQL *conn = NULL;cJSON *root = NULL;cJSON *array =NULL;char *out = NULL;char *out2 = NULL;MYSQL_RES *res_set = NULL;//connect the databaseconn = msql_conn(mysql_user, mysql_pwd, mysql_db);if (conn == NULL){LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "msql_conn err\n");ret = -1;goto END;}//设置数据库编码,主要处理中文编码问题mysql_query(conn, "set names utf8");//sql语句sprintf(sql_cmd, "select share_file_list.*, file_info.url, file_info.size, file_info.type from file_info, share_file_list where file_info.md5 = share_file_list.md5 limit %d, %d", start, count);LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "%s 在操作\n", sql_cmd);if (mysql_query(conn, sql_cmd) != 0){LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "%s 操作失败: %s\n", sql_cmd, mysql_error(conn));ret = -1;goto END;}res_set = mysql_store_result(conn);/*生成结果集*/if (res_set == NULL){LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "smysql_store_result error!\n");ret = -1;goto END;}ulong line = 0;//mysql_num_rows接受由mysql_store_result返回的结果结构集,并返回结构集中的行数line = mysql_num_rows(res_set);if (line == 0){LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "mysql_num_rows(res_set) failed\n");ret = -1;goto END;}MYSQL_ROW row;root = cJSON_CreateObject();array = cJSON_CreateArray();// mysql_fetch_row从使用mysql_store_result得到的结果结构中提取一行,并把它放到一个行结构中。// 当数据用完或发生错误时返回NULL.while ((row = mysql_fetch_row(res_set)) != NULL){//array[i]:cJSON* item = cJSON_CreateObject();//mysql_num_fields获取结果中列的个数/*for(i = 0; i < mysql_num_fields(res_set); i++){if(row[i] != NULL){}}*//*{"user": "yoyo","md5": "e8ea6031b779ac26c319ddf949ad9d8d","time": "2017-02-26 21:35:25","filename": "test.mp4","share_status": 1,"pv": 0,"url": "http://192.168.31.109:80/group1/M00/00/00/wKgfbViy2Z2AJ-FTAaM3As-g3Z0782.mp4","size": 27473666,"type": "mp4"}*///-- user	文件所属用户if(row[0] != NULL){cJSON_AddStringToObject(item, "user", row[0]);}//-- md5 文件md5if(row[1] != NULL){cJSON_AddStringToObject(item, "md5", row[1]);}//-- createtime 文件创建时间if(row[2] != NULL){cJSON_AddStringToObject(item, "time", row[2]);}//-- filename 文件名字if(row[3] != NULL){cJSON_AddStringToObject(item, "filename", row[3]);}//-- shared_status 共享状态, 0为没有共享, 1为共享cJSON_AddNumberToObject(item, "share_status", 1);//-- pv 文件下载量,默认值为0,下载一次加1if(row[4] != NULL){cJSON_AddNumberToObject(item, "pv", atol( row[4] ));}//-- url 文件urlif(row[5] != NULL){cJSON_AddStringToObject(item, "url", row[5]);}//-- size 文件大小, 以字节为单位if(row[6] != NULL){cJSON_AddNumberToObject(item, "size", atol( row[6] ));}//-- type 文件类型: png, zip, mp4……if(row[7] != NULL){cJSON_AddStringToObject(item, "type", row[7]);}cJSON_AddItemToArray(array, item);}cJSON_AddItemToObject(root, "files", array);out = cJSON_Print(root);LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "%s\n", out);END:if(ret == 0){printf("%s", out); //给前端反馈信息}else{   //失败out2 = NULL;out2 = return_status("015");}if(out2 != NULL){printf(out2); //给前端反馈错误码free(out2);}if(res_set != NULL){//完成所有对数据的操作后,调用mysql_free_result来善后处理mysql_free_result(res_set);}if(conn != NULL){mysql_close(conn);}if(root != NULL){cJSON_Delete(root);}if(out != NULL){free(out);}return ret;}//获取共享文件排行版//按下载量降序127.0.0.1:80/sharefiles?cmd=pvdescint get_ranking_filelist(int start, int count){/*a) mysql共享文件数量和redis共享文件数量对比,判断是否相等b) 如果不相等,清空redis数据,从mysql中导入数据到redis (mysql和redis交互)c) 从redis读取数据,给前端反馈相应信息*/int ret = 0;char sql_cmd[SQL_MAX_LEN] = {0};MYSQL *conn = NULL;cJSON *root = NULL;RVALUES value = NULL;cJSON *array =NULL;char *out = NULL;char *out2 = NULL;char tmp[512] = {0};int ret2 = 0;MYSQL_RES *res_set = NULL;redisContext * redis_conn = NULL;//连接redis数据库redis_conn = rop_connectdb_nopwd(redis_ip, redis_port);if (redis_conn == NULL){LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "redis connected error");ret = -1;goto END;}//connect the databaseconn = msql_conn(mysql_user, mysql_pwd, mysql_db);if (conn == NULL){LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "msql_conn err\n");ret = -1;goto END;}//设置数据库编码,主要处理中文编码问题mysql_query(conn, "set names utf8");//===1、mysql共享文件数量sprintf(sql_cmd, "select count from user_file_count where user=\"%s\"", "xxx_share_xxx_file_xxx_list_xxx_count_xxx");ret2 = process_result_one(conn, sql_cmd, tmp); //指向sql语句if(ret2 != 0){LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "%s 操作失败\n", sql_cmd);ret = -1;goto END;}int sql_num = atoi(tmp); //字符串转长整形//===2、redis共享文件数量int redis_num = rop_zset_zcard(redis_conn, FILE_PUBLIC_ZSET);if(redis_num == -1){LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "rop_zset_zcard 操作失败\n");ret = -1;goto END;}LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "sql_num = %d, redis_num = %d\n", sql_num, redis_num);//===3、mysql共享文件数量和redis共享文件数量对比,判断是否相等if(redis_num != sql_num){//===4、如果不相等,清空redis数据,重新从mysql中导入数据到redis (mysql和redis交互)//a) 清空redis有序数据rop_del_key(redis_conn, FILE_PUBLIC_ZSET);rop_del_key(redis_conn, FILE_NAME_HASH);//b) 从mysql中导入数据到redis//sql语句strcpy(sql_cmd, "select md5, filename, pv from share_file_list order by pv desc");LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "%s 在操作\n", sql_cmd);if (mysql_query(conn, sql_cmd) != 0){LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "%s 操作失败: %s\n", sql_cmd, mysql_error(conn));ret = -1;goto END;}res_set = mysql_store_result(conn);/*生成结果集*/if (res_set == NULL){LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "smysql_store_result error!\n");ret = -1;goto END;}ulong line = 0;//mysql_num_rows接受由mysql_store_result返回的结果结构集,并返回结构集中的行数line = mysql_num_rows(res_set);if (line == 0){LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "mysql_num_rows(res_set) failed\n");ret = -1;goto END;}MYSQL_ROW row;// mysql_fetch_row从使用mysql_store_result得到的结果结构中提取一行,并把它放到一个行结构中。// 当数据用完或发生错误时返回NULL.while ((row = mysql_fetch_row(res_set)) != NULL){//md5, filename, pvif(row[0] == NULL || row[1] == NULL || row[2] == NULL){LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "mysql_fetch_row(res_set)) failed\n");ret = -1;goto END;}char fileid[1024] = {0};sprintf(fileid, "%s%s", row[0], row[1]); //文件标示,md5+文件名//增加有序集合成员rop_zset_add(redis_conn, FILE_PUBLIC_ZSET, atoi(row[2]), fileid);//增加hash记录rop_hash_set(redis_conn, FILE_NAME_HASH, fileid, row[1]);}}//===5、从redis读取数据,给前端反馈相应信息//char value[count][1024];value  = (RVALUES)calloc(count, VALUES_ID_SIZE); //堆区请求空间if(value == NULL){ret = -1;goto END;}int n = 0;int end = start + count - 1;//加载资源的结束位置//降序获取有序集合的元素ret = rop_zset_zrevrange(redis_conn, FILE_PUBLIC_ZSET, start, end, value, &n);if(ret != 0){LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "rop_zset_zrevrange 操作失败\n");goto END;}root = cJSON_CreateObject();array = cJSON_CreateArray();//遍历元素个数for(int i = 0; i < n; ++i){//array[i]:cJSON* item = cJSON_CreateObject();/*{"filename": "test.mp4","pv": 0}*///-- filename 文件名字char filename[1024] = {0};ret = rop_hash_get(redis_conn, FILE_NAME_HASH, value[i], filename);if(ret != 0){LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "rop_hash_get 操作失败\n");ret = -1;goto END;}cJSON_AddStringToObject(item, "filename", filename);//-- pv 文件下载量int score = rop_zset_get_score(redis_conn, FILE_PUBLIC_ZSET, value[i]);if(score == -1){LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "rop_zset_get_score 操作失败\n");ret = -1;goto END;}cJSON_AddNumberToObject(item, "pv", score);cJSON_AddItemToArray(array, item);}cJSON_AddItemToObject(root, "files", array);out = cJSON_Print(root);LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "%s\n", out);END:if(ret == 0){printf("%s", out); //给前端反馈信息}else{   //失败out2 = NULL;out2 = return_status("015");}if(out2 != NULL){printf(out2); //给前端反馈错误码free(out2);}if(res_set != NULL){//完成所有对数据的操作后,调用mysql_free_result来善后处理mysql_free_result(res_set);}if(redis_conn != NULL){rop_disconnect(redis_conn);}if(conn != NULL){mysql_close(conn);}if(value != NULL){free(value);}if(root != NULL){cJSON_Delete(root);}if(out != NULL){free(out);}return ret;}int main(){char cmd[20];//读取数据库配置信息read_cfg();//阻塞等待用户连接while (FCGI_Accept() >= 0){// 获取URL地址 "?" 后面的内容char *query = getenv("QUERY_STRING");//解析命令query_parse_key_value(query, "cmd", cmd, NULL);LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "cmd = %s\n", cmd);printf("Content-type: text/html\r\n\r\n");if (strcmp(cmd, "count") == 0) //count 获取用户文件个数{get_share_files_count(); //获取共享文件个数}else{char *contentLength = getenv("CONTENT_LENGTH");int len;if( contentLength == NULL ){len = 0;}else{len = atoi(contentLength); //字符串转整型}if (len <= 0){printf("No data from standard input.<p>\n");LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "len = 0, No data from standard input\n");}else{char buf[4*1024] = {0};int ret = 0;ret = fread(buf, 1, len, stdin); //从标准输入(web服务器)读取内容if(ret == 0){LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "fread(buf, 1, len, stdin) err\n");continue;}LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "buf = %s\n", buf);//获取共享文件信息 127.0.0.1:80/sharefiles&cmd=normal//按下载量升序 127.0.0.1:80/sharefiles?cmd=pvasc//按下载量降序127.0.0.1:80/sharefiles?cmd=pvdescint start; //文件起点int count; //文件个数get_fileslist_json_info(buf, &start, &count); //通过json包获取信息LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "start = %d, count = %d\n", start, count);if (strcmp(cmd, "normal") == 0){get_share_filelist(start, count); //获取共享文件列表}else if(strcmp(cmd, "pvdesc") == 0){get_ranking_filelist(start, count);//获取共享文件排行版}}}}return 0;}
查看全文
如若内容造成侵权/违法违规/事实不符,请联系编程学习网邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

相关文章

  1. Java多线程编程复习总结(一)

    Java中多线程概述 一、基本概念 进程和线程进程是程序运行的实例,比如Java程序就是一个Java虚拟机进程 每个进程中可以包含多个线程,每个线程完成各自不同的任务,在Java平台中一个线程对应一个对象但是这个对象和普通类中声明的对象不一样,不是分配在对空间中的;而是,JVM…...

    2024/4/16 17:34:19
  2. 通过组键扫描使得Spring管理类的对象

    通过组件扫描使得Spring管理类的对象。 如果User类需要使用Spring框架管理,必须声明User类所在的包,然后再用测试类中的AnnotationConfigApplicationContext的构造方法中将包名作为参数():import org.springframework.context.annotation.AnnotationConfigApplicationContex…...

    2024/4/20 1:33:08
  3. 致敬建党99年 | 不忘初心,砥砺前行

    致敬建党99年 | 不忘初心,砥砺前行 七一建党节(1921-2020) 听风雨飘摇,看沧桑巨变 一个民族的图存、崛起、强盛 离不开一代代中华儿女的奋斗与牺牲 在此 热烈庆祝中国共产党成立99年共产党一路走来,始终坚持了为中国人民谋幸福、为中华民族谋复兴的初心和使命。 这一份不忘…...

    2024/3/31 23:32:28
  4. 【转】Android Notification 版本适配方案

    Notification 介绍见:https://developer.android.com/reference/android/app/Notification.htmlAndroid api 一直对通知栏进行升级! 包括7.0继续改善快捷通知栏,接下来介绍下通知栏不同版本的兼容适配.**Android JELLY_BEAN(16) 通知可以直接new Notification()**Notificat…...

    2024/4/23 14:25:39
  5. 08 数据采集 - 如何自动化采集数据

    # Author:Nimo_Ding 数据源: 1、开放数据源政府 企业 高校 2、爬虫抓取网页 app - 例如购物评价Python爬虫三个步骤:1、requests库爬取内容2、XPath解析内容(XML Path,XML路径语言),XPath可以通过元素和属性进行位置索引。3、使用pandas保存数据,写入xlsx、csv或mysql。其他…...

    2024/4/20 13:14:05
  6. 考研成长日记day2(2)

    字符串按照下标访问明明有字符,但是输出为空 string s; s[0]=h; s[1]=i; cout<<s;按理来说应该是输出hi 但是由于字符串初始长度为0,所以说字符串会发生访问越界 所以说实际输出为 我们来看看下标能不能正常输出 string s; s[0]=h; s[1]=i; cout<<s<<endl;…...

    2024/4/16 17:35:25
  7. C++初始化列表详解

    目录:定义使用初始化列表的原因必须使用初始化列表的时候成员变量的顺序 定义 与其他函数不同,构造函数除了有名字,参数列表和函数体之外,还可以有初始化列表,初始化列表以冒号开头,后跟一系列以逗号分隔的初始化字段。 class Date { public:Date(int year = 1900, int m…...

    2024/4/20 13:50:12
  8. 网页访问的流程(涵盖网络基础)

    静态网页的访问:首先得有一台个人电脑就是所谓的主机,然后还需要一个浏览器。在浏览器中输入URL(Uniform Resource Location)中文是统一资源定位,就是指互联网上的绝对路径,例如http://localhost:8080/new.htmlURL可以分为4个部分:网络协议:http 域名:localhost 端口号…...

    2024/4/20 3:18:13
  9. js日期工具类

    /***************************************************************************************************************通用时间工具************************************************************************************************************************************…...

    2024/4/16 17:35:19
  10. LeetCode 14. 最长公共前缀

    目录结构1.题目2.题解1.题目编写一个函数来查找字符串数组中的最长公共前缀。如果不存在公共前缀,返回空字符串 ""。示例:输入: ["flower","flow","flight"] 输出: "fl"输入: ["dog","racecar","…...

    2024/4/20 5:15:10
  11. 自己开发封装的微信小程序组件——计算器,复制即可用

    写在前面 我在开发自己用的账本类微信小程序时,因为嫌老是要切屏打开计算器,算完之后还要照着计算结果手动记录很不方便,尤其是当计算出来的结果位数较长时,容易看错或打错,因此想自己开发封装一个计算器组件在需要用的页面里,这样不仅可以减少切屏的次数,还可以直接去拿…...

    2024/4/16 17:35:19
  12. ADB 安装和简单使用

    Windows下*一,安装:安装AndroidAtudio,也可以单独安装ADB。Android 调试桥 (adb) 是一种功能多样的命令行工具,可让您与设备进行通信。adb 命令可用于执行各种设备操作(例如安装和调试应用),并提供对 Unix shell(可用来在设备上运行各种命令)的访问权限。它是一种客户端…...

    2024/4/16 17:35:08
  13. 如何有效实施DevOps?

    当今IT行业的竞争日益激烈,各家公司都在寻找优化软件研发过程的方法,因为交付比对手更具竞争力的产品已经越发成为一件成本高昂的事情。这也是DevOps发挥作用的地方,因为它可以在工程管理的各个方面提供帮助。 瀑布开发模型已被广泛使用多年,但它的开发、测试和运维在整个生…...

    2024/4/16 17:35:01
  14. Hadoop序列化机制

    文章目录一.什么是序列化和反序列化二.Hadoop的序列化三.Hadoop的序列化案例 一.什么是序列化和反序列化序列化:将对象转化为字节流,以便在网络上传输或者写在磁盘磁盘上进行永久存储 反序列化:将字节流转回成对象 序列化在分布式数据处理的两个领域经常出现: 进程间通信和永久…...

    2024/4/18 13:00:54
  15. 注解(Annotation)

    一、注解(Annotation)概述 1.注解的作用不是程序本身,可以对程序做出解释—> 相当于注释。 可以被其他程序(比如“编译器”等)读取。2.注解的格式 注解格式为“@注释名”,还可以添加一些参数值,;例如: @SuppressWarnings(value = “unchecked”). 3.使用方式 可以附…...

    2024/4/16 17:35:19
  16. 《最值得收藏的python3语法汇总》之错误和异常

    目录关于这个系列1、定义2、处理异常3、清理行为4、自定义异常关于这个系列《最值得收藏的python3语法汇总》,是我为了准备公众号“跟哥一起学python”上面视频教程而写的课件。整个课件将近200页,10w字,几乎囊括了python3所有的语法知识点。你可以关注这个公众号“跟哥一起…...

    2024/4/16 17:35:32
  17. BFS - Meteor Shower - 流星雨

    题解这个是我前三个月扔下的题,原来一直没有读懂是什么意思ps:这次也是看了别人的博客才知道大意:给你M个坐标,坐标后面是这个点爆炸的时间,注意点爆炸以后就不能再去了,不是只是一瞬间。 从源点开始,找一个永远都不会爆炸的点 所需要的时间(步数)题解:说了x,y的范围…...

    2024/4/20 16:03:21
  18. QQ扫码解冻找好友担保立即解冻

    最近的绿萝行动,导致大部分QQ账号被冻结,扫码担保解冻成了热门话题,符合解封条件的号码少之又少,那么如何才能快速解冻呢?Q 40026692 15代解,10分钟左右完成。...

    2024/4/16 17:35:49
  19. gitlab 删除远端untracked content文件或目录

    git rm -r --cached 远端untracked content文件或目录 git commit -m "备注信息" git push -u origin master...

    2024/4/16 17:35:55
  20. f103 hal RTC_alarm使用方法

    1.初始化RTC RTC_handle.Instance = RTC; RTC_handle.Lock = HAL_UNLOCKED; RTC_handle.Init.AsynchPrediv = RTC_AUTO_1_SECOND; RTC_handle.Init.OutPut = RTC_OUTPUTSOURCE_ALARM;if(HAL_RTC_Init(&RTC_handle) != HAL_OK) {HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PI…...

    2024/4/19 21:40:58

最新文章

  1. 2024五一萌趣嘉年华主题展活动策划案

    2024五一国宝大作战 萌趣嘉年华熊猫滚滚来野主题展活动策划案-53P 活动策划信息&#xff1a; 方案页码&#xff1a;53页 文件格式&#xff1a;PPT 方案简介&#xff1a; 活动思路&#xff1a; 五一马上就要到了~再加上全民关注的对象--大熊猫&#xff01;&#xff01; 这…...

    2024/4/25 0:53:41
  2. 梯度消失和梯度爆炸的一些处理方法

    在这里是记录一下梯度消失或梯度爆炸的一些处理技巧。全当学习总结了如有错误还请留言&#xff0c;在此感激不尽。 权重和梯度的更新公式如下&#xff1a; w w − η ⋅ ∇ w w w - \eta \cdot \nabla w ww−η⋅∇w 个人通俗的理解梯度消失就是网络模型在反向求导的时候出…...

    2024/3/20 10:50:27
  3. 【嵌入式开发 Linux 常用命令系列 4.3 -- git add 不 add untracked file】

    请阅读【嵌入式开发学习必备专栏 】 文章目录 git add 不add untracked file git add 不add untracked file 如果你想要Git在执行git add .时不添加未跟踪的文件&#xff08;untracked files&#xff09;&#xff0c;你可以使用以下命令&#xff1a; git add -u这个命令只会加…...

    2024/4/23 6:14:17
  4. ssm框架中各层级介绍

    1、Spring&#xff08;业务逻辑层&#xff09;&#xff1a; Spring框架提供了依赖注入&#xff08;DI&#xff09;和面向切面编程&#xff08;AOP&#xff09;等功能&#xff0c;可以帮助管理Java应用程序中的对象依赖关系和提供横切关注点的支持。 在SSM框架中&#xff0c;S…...

    2024/4/21 13:57:27
  5. 【外汇早评】美通胀数据走低,美元调整

    原标题:【外汇早评】美通胀数据走低,美元调整昨日美国方面公布了新一期的核心PCE物价指数数据,同比增长1.6%,低于前值和预期值的1.7%,距离美联储的通胀目标2%继续走低,通胀压力较低,且此前美国一季度GDP初值中的消费部分下滑明显,因此市场对美联储后续更可能降息的政策…...

    2024/4/23 20:58:27
  6. 【原油贵金属周评】原油多头拥挤,价格调整

    原标题:【原油贵金属周评】原油多头拥挤,价格调整本周国际劳动节,我们喜迎四天假期,但是整个金融市场确实流动性充沛,大事频发,各个商品波动剧烈。美国方面,在本周四凌晨公布5月份的利率决议和新闻发布会,维持联邦基金利率在2.25%-2.50%不变,符合市场预期。同时美联储…...

    2024/4/23 13:30:22
  7. 【外汇周评】靓丽非农不及疲软通胀影响

    原标题:【外汇周评】靓丽非农不及疲软通胀影响在刚结束的周五,美国方面公布了新一期的非农就业数据,大幅好于前值和预期,新增就业重新回到20万以上。具体数据: 美国4月非农就业人口变动 26.3万人,预期 19万人,前值 19.6万人。 美国4月失业率 3.6%,预期 3.8%,前值 3…...

    2024/4/23 13:28:06
  8. 【原油贵金属早评】库存继续增加,油价收跌

    原标题:【原油贵金属早评】库存继续增加,油价收跌周三清晨公布美国当周API原油库存数据,上周原油库存增加281万桶至4.692亿桶,增幅超过预期的74.4万桶。且有消息人士称,沙特阿美据悉将于6月向亚洲炼油厂额外出售更多原油,印度炼油商预计将每日获得至多20万桶的额外原油供…...

    2024/4/24 18:16:28
  9. 【外汇早评】日本央行会议纪要不改日元强势

    原标题:【外汇早评】日本央行会议纪要不改日元强势近两日日元大幅走强与近期市场风险情绪上升,避险资金回流日元有关,也与前一段时间的美日贸易谈判给日本缓冲期,日本方面对汇率问题也避免继续贬值有关。虽然今日早间日本央行公布的利率会议纪要仍然是支持宽松政策,但这符…...

    2024/4/23 13:27:44
  10. 【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响

    原标题:【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响近日伊朗局势升温,导致市场担忧影响原油供给,油价试图反弹。此时OPEC表态稳定市场。据消息人士透露,沙特6月石油出口料将低于700万桶/日,沙特已经收到石油消费国提出的6月份扩大出口的“适度要求”,沙特将满…...

    2024/4/19 11:57:53
  11. 【外汇早评】美欲与伊朗重谈协议

    原标题:【外汇早评】美欲与伊朗重谈协议美国对伊朗的制裁遭到伊朗的抗议,昨日伊朗方面提出将部分退出伊核协议。而此行为又遭到欧洲方面对伊朗的谴责和警告,伊朗外长昨日回应称,欧洲国家履行它们的义务,伊核协议就能保证存续。据传闻伊朗的导弹已经对准了以色列和美国的航…...

    2024/4/23 13:29:53
  12. 【原油贵金属早评】波动率飙升,市场情绪动荡

    原标题:【原油贵金属早评】波动率飙升,市场情绪动荡因中美贸易谈判不安情绪影响,金融市场各资产品种出现明显的波动。随着美国与中方开启第十一轮谈判之际,美国按照既定计划向中国2000亿商品征收25%的关税,市场情绪有所平复,已经开始接受这一事实。虽然波动率-恐慌指数VI…...

    2024/4/23 13:27:22
  13. 【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试

    原标题:【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试美国和伊朗的局势继续升温,市场风险情绪上升,避险黄金有向上突破阻力的迹象。原油方面稍显平稳,近期美国和OPEC加大供给及市场需求回落的影响,伊朗局势并未推升油价走强。近期中美贸易谈判摩擦再度升级,美国对中…...

    2024/4/23 13:28:42
  14. 【原油贵金属早评】市场情绪继续恶化,黄金上破

    原标题:【原油贵金属早评】市场情绪继续恶化,黄金上破周初中国针对于美国加征关税的进行的反制措施引发市场情绪的大幅波动,人民币汇率出现大幅的贬值动能,金融市场受到非常明显的冲击。尤其是波动率起来之后,对于股市的表现尤其不安。隔夜美国股市出现明显的下行走势,这…...

    2024/4/23 22:01:21
  15. 【外汇早评】美伊僵持,风险情绪继续升温

    原标题:【外汇早评】美伊僵持,风险情绪继续升温昨日沙特两艘油轮再次发生爆炸事件,导致波斯湾局势进一步恶化,市场担忧美伊可能会出现摩擦生火,避险品种获得支撑,黄金和日元大幅走强。美指受中美贸易问题影响而在低位震荡。继5月12日,四艘商船在阿联酋领海附近的阿曼湾、…...

    2024/4/23 13:29:23
  16. 【原油贵金属早评】贸易冲突导致需求低迷,油价弱势

    原标题:【原油贵金属早评】贸易冲突导致需求低迷,油价弱势近日虽然伊朗局势升温,中东地区几起油船被袭击事件影响,但油价并未走高,而是出于调整结构中。由于市场预期局势失控的可能性较低,而中美贸易问题导致的全球经济衰退风险更大,需求会持续低迷,因此油价调整压力较…...

    2024/4/25 0:00:17
  17. 氧生福地 玩美北湖(上)——为时光守候两千年

    原标题:氧生福地 玩美北湖(上)——为时光守候两千年一次说走就走的旅行,只有一张高铁票的距离~ 所以,湖南郴州,我来了~ 从广州南站出发,一个半小时就到达郴州西站了。在动车上,同时改票的南风兄和我居然被分到了一个车厢,所以一路非常愉快地聊了过来。 挺好,最起…...

    2024/4/23 13:47:22
  18. 氧生福地 玩美北湖(中)——永春梯田里的美与鲜

    原标题:氧生福地 玩美北湖(中)——永春梯田里的美与鲜一觉醒来,因为大家太爱“美”照,在柳毅山庄去寻找龙女而错过了早餐时间。近十点,向导坏坏还是带着饥肠辘辘的我们去吃郴州最富有盛名的“鱼头粉”。说这是“十二分推荐”,到郴州必吃的美食之一。 哇塞!那个味美香甜…...

    2024/4/19 11:59:23
  19. 氧生福地 玩美北湖(下)——奔跑吧骚年!

    原标题:氧生福地 玩美北湖(下)——奔跑吧骚年!让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 啊……啊……啊 两…...

    2024/4/19 11:59:44
  20. 扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!

    原标题:扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!扒开伪装医用面膜,翻六倍价格宰客!当行业里的某一品项火爆了,就会有很多商家蹭热度,装逼忽悠,最近火爆朋友圈的医用面膜,被沾上了污点,到底怎么回事呢? “比普通面膜安全、效果好!痘痘、痘印、敏感肌都能用…...

    2024/4/23 13:28:08
  21. 「发现」铁皮石斛仙草之神奇功效用于医用面膜

    原标题:「发现」铁皮石斛仙草之神奇功效用于医用面膜丽彦妆铁皮石斛医用面膜|石斛多糖无菌修护补水贴19大优势: 1、铁皮石斛:自唐宋以来,一直被列为皇室贡品,铁皮石斛生于海拔1600米的悬崖峭壁之上,繁殖力差,产量极低,所以古代仅供皇室、贵族享用 2、铁皮石斛自古民间…...

    2024/4/24 16:38:05
  22. 丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者

    原标题:丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者【公司简介】 广州华彬企业隶属香港华彬集团有限公司,专注美业21年,其旗下品牌: 「圣茵美」私密荷尔蒙抗衰,产后修复 「圣仪轩」私密荷尔蒙抗衰,产后修复 「花茵莳」私密荷尔蒙抗衰,产后修复 「丽彦妆」专注医学护…...

    2024/4/23 13:28:14
  23. 广州械字号面膜生产厂家OEM/ODM4项须知!

    原标题:广州械字号面膜生产厂家OEM/ODM4项须知!广州械字号面膜生产厂家OEM/ODM流程及注意事项解读: 械字号医用面膜,其实在我国并没有严格的定义,通常我们说的医美面膜指的应该是一种「医用敷料」,也就是说,医用面膜其实算作「医疗器械」的一种,又称「医用冷敷贴」。 …...

    2024/4/23 13:27:51
  24. 械字号医用眼膜缓解用眼过度到底有无作用?

    原标题:械字号医用眼膜缓解用眼过度到底有无作用?医用眼膜/械字号眼膜/医用冷敷眼贴 凝胶层为亲水高分子材料,含70%以上的水分。体表皮肤温度传导到本产品的凝胶层,热量被凝胶内水分子吸收,通过水分的蒸发带走大量的热量,可迅速地降低体表皮肤局部温度,减轻局部皮肤的灼…...

    2024/4/23 13:27:19
  25. 配置失败还原请勿关闭计算机,电脑开机屏幕上面显示,配置失败还原更改 请勿关闭计算机 开不了机 这个问题怎么办...

    解析如下&#xff1a;1、长按电脑电源键直至关机&#xff0c;然后再按一次电源健重启电脑&#xff0c;按F8健进入安全模式2、安全模式下进入Windows系统桌面后&#xff0c;按住“winR”打开运行窗口&#xff0c;输入“services.msc”打开服务设置3、在服务界面&#xff0c;选中…...

    2022/11/19 21:17:18
  26. 错误使用 reshape要执行 RESHAPE,请勿更改元素数目。

    %读入6幅图像&#xff08;每一幅图像的大小是564*564&#xff09; f1 imread(WashingtonDC_Band1_564.tif); subplot(3,2,1),imshow(f1); f2 imread(WashingtonDC_Band2_564.tif); subplot(3,2,2),imshow(f2); f3 imread(WashingtonDC_Band3_564.tif); subplot(3,2,3),imsho…...

    2022/11/19 21:17:16
  27. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机...

    win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”问题的解决方法在win7系统关机时如果有升级系统的或者其他需要会直接进入一个 等待界面&#xff0c;在等待界面中我们需要等待操作结束才能关机&#xff0c;虽然这比较麻烦&#xff0c;但是对系统进行配置和升级…...

    2022/11/19 21:17:15
  28. 台式电脑显示配置100%请勿关闭计算机,“准备配置windows 请勿关闭计算机”的解决方法...

    有不少用户在重装Win7系统或更新系统后会遇到“准备配置windows&#xff0c;请勿关闭计算机”的提示&#xff0c;要过很久才能进入系统&#xff0c;有的用户甚至几个小时也无法进入&#xff0c;下面就教大家这个问题的解决方法。第一种方法&#xff1a;我们首先在左下角的“开始…...

    2022/11/19 21:17:14
  29. win7 正在配置 请勿关闭计算机,怎么办Win7开机显示正在配置Windows Update请勿关机...

    置信有很多用户都跟小编一样遇到过这样的问题&#xff0c;电脑时发现开机屏幕显现“正在配置Windows Update&#xff0c;请勿关机”(如下图所示)&#xff0c;而且还需求等大约5分钟才干进入系统。这是怎样回事呢&#xff1f;一切都是正常操作的&#xff0c;为什么开时机呈现“正…...

    2022/11/19 21:17:13
  30. 准备配置windows 请勿关闭计算机 蓝屏,Win7开机总是出现提示“配置Windows请勿关机”...

    Win7系统开机启动时总是出现“配置Windows请勿关机”的提示&#xff0c;没过几秒后电脑自动重启&#xff0c;每次开机都这样无法进入系统&#xff0c;此时碰到这种现象的用户就可以使用以下5种方法解决问题。方法一&#xff1a;开机按下F8&#xff0c;在出现的Windows高级启动选…...

    2022/11/19 21:17:12
  31. 准备windows请勿关闭计算机要多久,windows10系统提示正在准备windows请勿关闭计算机怎么办...

    有不少windows10系统用户反映说碰到这样一个情况&#xff0c;就是电脑提示正在准备windows请勿关闭计算机&#xff0c;碰到这样的问题该怎么解决呢&#xff0c;现在小编就给大家分享一下windows10系统提示正在准备windows请勿关闭计算机的具体第一种方法&#xff1a;1、2、依次…...

    2022/11/19 21:17:11
  32. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”的解决方法...

    今天和大家分享一下win7系统重装了Win7旗舰版系统后&#xff0c;每次关机的时候桌面上都会显示一个“配置Windows Update的界面&#xff0c;提示请勿关闭计算机”&#xff0c;每次停留好几分钟才能正常关机&#xff0c;导致什么情况引起的呢&#xff1f;出现配置Windows Update…...

    2022/11/19 21:17:10
  33. 电脑桌面一直是清理请关闭计算机,windows7一直卡在清理 请勿关闭计算机-win7清理请勿关机,win7配置更新35%不动...

    只能是等着&#xff0c;别无他法。说是卡着如果你看硬盘灯应该在读写。如果从 Win 10 无法正常回滚&#xff0c;只能是考虑备份数据后重装系统了。解决来方案一&#xff1a;管理员运行cmd&#xff1a;net stop WuAuServcd %windir%ren SoftwareDistribution SDoldnet start WuA…...

    2022/11/19 21:17:09
  34. 计算机配置更新不起,电脑提示“配置Windows Update请勿关闭计算机”怎么办?

    原标题&#xff1a;电脑提示“配置Windows Update请勿关闭计算机”怎么办&#xff1f;win7系统中在开机与关闭的时候总是显示“配置windows update请勿关闭计算机”相信有不少朋友都曾遇到过一次两次还能忍但经常遇到就叫人感到心烦了遇到这种问题怎么办呢&#xff1f;一般的方…...

    2022/11/19 21:17:08
  35. 计算机正在配置无法关机,关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机...

    关机提示 windows7 正在配置windows 请勿关闭计算机 &#xff0c;然后等了一晚上也没有关掉。现在电脑无法正常关机以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;关机提示 windows7 正在配…...

    2022/11/19 21:17:05
  36. 钉钉提示请勿通过开发者调试模式_钉钉请勿通过开发者调试模式是真的吗好不好用...

    钉钉请勿通过开发者调试模式是真的吗好不好用 更新时间:2020-04-20 22:24:19 浏览次数:729次 区域: 南阳 > 卧龙 列举网提醒您:为保障您的权益,请不要提前支付任何费用! 虚拟位置外设器!!轨迹模拟&虚拟位置外设神器 专业用于:钉钉,外勤365,红圈通,企业微信和…...

    2022/11/19 21:17:05
  37. 配置失败还原请勿关闭计算机怎么办,win7系统出现“配置windows update失败 还原更改 请勿关闭计算机”,长时间没反应,无法进入系统的解决方案...

    前几天班里有位学生电脑(windows 7系统)出问题了&#xff0c;具体表现是开机时一直停留在“配置windows update失败 还原更改 请勿关闭计算机”这个界面&#xff0c;长时间没反应&#xff0c;无法进入系统。这个问题原来帮其他同学也解决过&#xff0c;网上搜了不少资料&#x…...

    2022/11/19 21:17:04
  38. 一个电脑无法关闭计算机你应该怎么办,电脑显示“清理请勿关闭计算机”怎么办?...

    本文为你提供了3个有效解决电脑显示“清理请勿关闭计算机”问题的方法&#xff0c;并在最后教给你1种保护系统安全的好方法&#xff0c;一起来看看&#xff01;电脑出现“清理请勿关闭计算机”在Windows 7(SP1)和Windows Server 2008 R2 SP1中&#xff0c;添加了1个新功能在“磁…...

    2022/11/19 21:17:03
  39. 请勿关闭计算机还原更改要多久,电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机怎么办...

    许多用户在长期不使用电脑的时候&#xff0c;开启电脑发现电脑显示&#xff1a;配置windows更新失败&#xff0c;正在还原更改&#xff0c;请勿关闭计算机。。.这要怎么办呢&#xff1f;下面小编就带着大家一起看看吧&#xff01;如果能够正常进入系统&#xff0c;建议您暂时移…...

    2022/11/19 21:17:02
  40. 还原更改请勿关闭计算机 要多久,配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以...

    配置windows update失败 还原更改 请勿关闭计算机&#xff0c;电脑开机后一直显示以以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;配置windows update失败 还原更改 请勿关闭计算机&#x…...

    2022/11/19 21:17:01
  41. 电脑配置中请勿关闭计算机怎么办,准备配置windows请勿关闭计算机一直显示怎么办【图解】...

    不知道大家有没有遇到过这样的一个问题&#xff0c;就是我们的win7系统在关机的时候&#xff0c;总是喜欢显示“准备配置windows&#xff0c;请勿关机”这样的一个页面&#xff0c;没有什么大碍&#xff0c;但是如果一直等着的话就要两个小时甚至更久都关不了机&#xff0c;非常…...

    2022/11/19 21:17:00
  42. 正在准备配置请勿关闭计算机,正在准备配置windows请勿关闭计算机时间长了解决教程...

    当电脑出现正在准备配置windows请勿关闭计算机时&#xff0c;一般是您正对windows进行升级&#xff0c;但是这个要是长时间没有反应&#xff0c;我们不能再傻等下去了。可能是电脑出了别的问题了&#xff0c;来看看教程的说法。正在准备配置windows请勿关闭计算机时间长了方法一…...

    2022/11/19 21:16:59
  43. 配置失败还原请勿关闭计算机,配置Windows Update失败,还原更改请勿关闭计算机...

    我们使用电脑的过程中有时会遇到这种情况&#xff0c;当我们打开电脑之后&#xff0c;发现一直停留在一个界面&#xff1a;“配置Windows Update失败&#xff0c;还原更改请勿关闭计算机”&#xff0c;等了许久还是无法进入系统。如果我们遇到此类问题应该如何解决呢&#xff0…...

    2022/11/19 21:16:58
  44. 如何在iPhone上关闭“请勿打扰”

    Apple’s “Do Not Disturb While Driving” is a potentially lifesaving iPhone feature, but it doesn’t always turn on automatically at the appropriate time. For example, you might be a passenger in a moving car, but your iPhone may think you’re the one dri…...

    2022/11/19 21:16:57