当前位置: 首页 > news >正文

景安服务器管理助手如何备份网站wordpress模板中文

景安服务器管理助手如何备份网站,wordpress模板中文,在线旅游攻略网站建设方案,做食品网站有哪些内容目录 前言#xff1a; 提示#xff1a; 插件 入门#xff1a; ProtoBuf普通字段类型#xff1a; 编译命令#xff1a; 序列化与反序列化#xff1a; Proto3语法#xff1a; 字段规则#xff1a;数组类型 应用 将通讯录数据序列化后写入文件 工具介绍#x…目录 前言 提示 插件 入门 ProtoBuf普通字段类型 编译命令 序列化与反序列化 Proto3语法 字段规则数组类型 应用 将通讯录数据序列化后写入文件 工具介绍hexdump 将文件数据反序列化到类中 ProtoBuf命令选项 Decode选项 Proto3语法 字段规则enum类型 应用 Proto3语法 字段规则Any类型 any的相关接口介绍 应用 Proto3语法 字段规则oneof类型 应用 Proto3语法 字段规则map类型 应用 Proto3语法 字段规则默认值 Proto3语法 字段规则更新消息 字段规则reserved Proto3语法 字段规则option 前言 提示 安装等过程在此处就不阐述请读者自行查阅 代码演示环境ubuntu22.04云服务器 插件 vscode支持ProtoBuf语法高亮的插件vscode-proto 入门 1.首先创建一个.proto文件 2.声明语法指定行 syntax proto3; 3.声明命名空间 package contacts; 4.定义一个message消息 message PeopleInfo {string _name 1;int32 _age 2; } //其中1和2都是ProtoBuf用来标识字段唯一性的ID同一个message中id不能相同也不能缺省; //ID范围 {12^29-1],其中19000~19999之间的数不可用;ProtoBuf普通字段类型 //ProtoBuf类型 double double float float int32 使⽤变⻓编码[1]。负数的编码效率较低⸺若字段可能为负值应使⽤ sint32 代替。 int64 使⽤变⻓编码[1]。负数的编码效率较低⸺若字段可能为负值应使⽤ sint64 代替。 uint32使⽤变⻓编码[1]。 uint64 使⽤变⻓编码[1]。 sint32 :使⽤变⻓编码[1]。符号整型。负值的编码效率⾼于常规的 int32 类型。 sint64 :使⽤变⻓编码[1]。符号整型。负值的编码效率⾼于常规的 int64 类型。 fixed32: 定⻓ 4 字节。若值常⼤于2^28 则会⽐ uint32 更⾼效。 fixed64 :定⻓ 8 字节。若值常⼤于2^56 则会⽐ uint64 更⾼效。 sfixed32:定⻓ 4 字节。 sfixed64:定⻓ 8 字节。 bool类型 string包含 UTF-8 和 ASCII 编码的字符串⻓度不能超过 2^32 。 bytes可包含任意的字节序列但⻓度不能超过 2^32 。 编译命令 1.编译当前路径下的.protoc文件protoc --cpp_out要保存的路径名 依赖的.proto文件例如protoc --cpp_out. contact.proto 2.编译指定路径下的.protoc文件protoc -I .protoc文件所处路径 --cpp_out要保存的路径名 依赖的.proto文件 序列化与反序列化 注意ProtoBuf序列化后不是文本序列而是二进制序列 序列化接口以Serialize开头 反序列化接口以Parse开头 #include iostream #include string //#includeProtoBuf编译后的头文件.h #include contacts.pb.hint main() {std::string data;//序列化{contacts::PeopleInfo ple;ple.set_name(张三);ple.set_age(20);// 序列化if (!ple.SerializeToString(data)){std::cout 序列化联系人信息失败! std::endl;return -1;}std::cout Serialized str data std::endl;}//反序列化{contacts::PeopleInfo ple;if(!ple.ParseFromString(data)){std::cout反序列化失败!std::endl;return -2;}std::cout反序列化成功!std::endl姓名: ple.name()std::endl年龄ple.age()std::endl;}return 0; } Makefile文件 Main:Main.cpp contacts.pb.ccg -o $ $^ -stdc11 -lprotobuf .PHONY:clean clean:rm -f Main Proto3语法 字段规则数组类型 1.数组类型repeated //样例1 message PeopleInfo {string name 1;int32 age 2;repeated string phone_numbers 3; } //也可以是message类型的数组 message PhoneNumbers {string phone 1; } message PeopleInfo {string name 1;int32 age 2;repeated PhoneNumbers phones 3; } 在一个.proto文件中使用另外一个.proto文件的message //以phone.proto和contacts.proto为例 //phone.proto message PhoneNumbers {string phone 1; } //contacts.proto syntax proto3; package contacts; import phone.proto;message PeopleInfo {string name 1;int32 age 2;repeated phone.PhoneNumbers phones 3; } /*注意如果外部的.proto文件中存在命名空间则在本文件inport引入后需要指定空间(空间名.) 才能使用message*/ 应用 将通讯录数据序列化后写入文件 接口介绍以上述.proto文件编译后的文件为例 1.add_contacts() 作用返回一块新的contacts数组中的空间地址用以用户填充相关字段作用类似于push_back 2.add_phones() 作用返回一块新的contacts数组中phone数组中的空间地址用以用户填充相关字段作用类似于push_back 3.cin.ignore() 作用cin的ignore函数可以用来清空cin的缓冲区传递一个足够大的参数和一个终止符即可cin会根据传递的大小和终止符来清空包括终止符在内的缓冲区数据 code: #include iostream #include fstream #include string #include contacts.pb.hvoid AddContact(contacts::PeopleInfo *con) {std::cout---------------新增联系人---------------std::endl;std::cout输入联系人姓名: ;std::string name;std::getline(std::cin, name);con-set_name(name);int age 0;std::cout输入联系人年龄: ;std::cin age;con-set_age(age);// 清空cin缓冲区std::cin.ignore(std::numeric_limitsstd::streamsize::max(), \n);// 新增电话for(int i 1;true;i){std::cout---请输入该联系人的电话i(只输入空格表示完成): ;std::string number;std::getline(std::cin,number);if(number.size() 0) break;contacts::PeopleInfo_Phone* phone con-add_phones();phone-set_phone(number);}std::cout---------------添加联系人成功---------------std::endl; } int main() {contacts::Contacts cons;std::ifstream in(contacts.bin, std::ios::binary);if (!in.is_open()){std::cout contacts.bin is not exist,create new contacts.bin std::endl;}else if (!cons.ParseFromIstream(in)){std::cout Parse contact info error! std::endl;in.close();return -1;}AddContact(cons.add_contacts());// 序列化写入文件std::ofstream out(contacts.bin, std::ios::trunc | std::ios::binary);if (!out.is_open()){std::cout write file error! std::endl;return -2;}if (!cons.SerializePartialToOstream(out)){std::cout 序列化失败! std::endl;return -3;}in.close();out.close();return 0; } 工具介绍hexdump 将二进制数据转换为十六进制: 指令hexdump -C 二进制文件 将文件数据反序列化到类中 #include iostream #include fstream #include contacts.pb.hint main() {contacts::Contacts cons;std::ifstream in(contacts.bin, std::ios::in | std::ios::binary);if (!in.is_open()){std::cout open contacts.bin error! std::endl;return -1;}else if (!cons.ParsePartialFromIstream(in)){std::cout 反序列化失败! std::endl;return -1;}for(int i 0;icons.contacts_size();i){std::cout-------------------------------std::endl;std::cout------------联系人-------------std::endl;auto people cons.contacts(i);std::cout姓名: ;std::coutpeople.name()std::endl;std::cout年龄: people.age()std::endl;std::cout-----------联系电话-------------std::endl;for(int i 0;ipeople.phones_size();i){std::cout(people.phones(i)).phone()std::endl;}std::cout----------- 联系人-------------std::endl;std::cout-----------------------------std::endl;}in.close();return 0; } ProtoBuf命令选项 查询ProtoBuf指令手册指令protoc -h Decode选项 从标准输入流中将二进制数据转换成文本类型数据可以将stdin重定向到某个二进制类型文件 protoc --decode命名空间.指定的message类型的变量名 指定的.proto文件 指定的二进制文件 Proto3语法 字段规则enum类型 枚举类型中,第一个枚举的变量值一定要以0开头枚举类型中的变量不能设置为负值且只能是32位数字 注意1.同一个文件中的枚举类型中的变量名不能相同; 2.在多个.proto文件中如果枚举类型名字相同需要申明一下package 3.import一个.proto文件后如果不适用其中的任何东西编译时会有warning syntax proto3; package contacts;message PeopleInfo {string name 1;int32 age 2;message Phone {string number 1;enum PhoneType{HP 0;TEL 1;}PhoneType type 2;}repeated Phone phones 3; }message Contacts {repeated PeopleInfo contacts 1; } 应用 接口介绍1.set_type(type)作用设置类型在上述例子中参数为contacts::PeopleInfo_Phone_PhoneType中的常量2.PhoneType_Name(type)作用将传递的参数type转换成字符串返回3.Phones(int index)作用返回数组中index下标对应的元素 //write.cc #include iostream #include fstream #include string #include contacts.pb.hvoid AddContact(contacts::PeopleInfo *con) {std::cout---------------新增联系人---------------std::endl;std::cout输入联系人姓名: ;std::string name;std::getline(std::cin, name);con-set_name(name);int age 0;std::cout输入联系人年龄: ;std::cin age;con-set_age(age);// 清空cin缓冲区std::cin.ignore(std::numeric_limitsstd::streamsize::max(), \n);// 新增电话for(int i 1;true;i){std::cout---请输入该联系人的电话i(只输入空格表示完成): ;std::string number;std::getline(std::cin,number);if(number.size() 0) break;contacts::PeopleInfo_Phone* phone con-add_phones();// phone-set_phone(number);phone-set_number(number);std::cout--请输入该联系人电话类型:|1.HP--2.TEL|-----: ;int type;std::cintype;switch(type){case 1: phone-set_type(contacts::PeopleInfo_Phone_PhoneType::PeopleInfo_Phone_PhoneType_HP);break;case 2:phone-set_type(contacts::PeopleInfo_Phone_PhoneType::PeopleInfo_Phone_PhoneType_TEL);break;}}std::cout---------------添加联系人成功---------------std::endl; } int main() {contacts::Contacts cons;std::ifstream in(contacts.bin, std::ios::binary);if (!in.is_open()){std::cout contacts.bin is not exist,create new contacts.bin std::endl;}else if (!cons.ParseFromIstream(in)){std::cout Parse contact info error! std::endl;in.close();return -1;}AddContact(cons.add_contacts());// 序列化写入文件std::ofstream out(contacts.bin, std::ios::trunc | std::ios::binary);if (!out.is_open()){std::cout write file error! std::endl;return -2;}if (!cons.SerializePartialToOstream(out)){std::cout 序列化失败! std::endl;return -3;}in.close();out.close();return 0; } //read.cc #include iostream #include fstream #include contacts.pb.hint main() {contacts::Contacts cons;std::ifstream in(contacts.bin, std::ios::in | std::ios::binary);if (!in.is_open()){std::cout open contacts.bin error! std::endl;return -1;}else if (!cons.ParsePartialFromIstream(in)){std::cout 反序列化失败! std::endl;return -1;}for(int i 0;icons.contacts_size();i){std::cout-------------------------------std::endl;std::cout------------联系人-------------std::endl;auto people cons.contacts(i);std::cout姓名: ;std::coutpeople.name()std::endl;std::cout年龄: people.age()std::endl;std::cout-----------联系电话-------------std::endl;for(int i 0;ipeople.phones_size();i){contacts::PeopleInfo_Phone phone people.phones(i);std::coutphone.number()std::endl;std::cout电话类型: phone.PhoneType_Name(phone.type())std::endl;}std::cout----------- 联系人-------------std::endl;std::cout-----------------------------std::endl;}in.close();return 0; } Proto3语法 字段规则Any类型 首先先查看ProtoBuf库的路径位置 /usr/local/include/google/protobuf/ 在这个路径下存在一个any.ptoto文件 //1引入any.proto import google/protobuf/any.protoc; syntax proto3; package contacts;import google/protobuf/any.proto;//地址信息 message Address{string util_address 1;string home_address 2; }message PeopleInfo{string name 1;int32 age 2;message Phone {string number 1;enum PhoneType{MP 0;TEL 1;}PhoneType type 2;}repeated Phone phones 3;google.protobuf.Any data 4; }message Contacts{repeated PeopleInfo contacts 1; }any的相关接口介绍 any在google::protobuf::Any::中,即定义google::protobuf::Any::变量名 1.mutablek开头的接口() 作用返回一个开辟好的any空间 在上述.proto文件编译的前提下接口名为:mutablek_data(); 2.PackFrom(message) 作用将一个message类型的对象存储到any对象中 3.UnpackTo(message*) 作用将一个any对象中存储的message对象提取出来; 4.has_data() 作用判断内部的any对象是是否有数据有则返回true.反之false 应用 //为联系人信息增加地址信息 //write.cc #include iostream #include fstream #include string #include contacts.pb.hvoid AddContact(contacts::PeopleInfo *con) {std::cout---------------新增联系人---------------std::endl;std::cout输入联系人姓名: ;std::string name;std::getline(std::cin, name);con-set_name(name);int age 0;std::cout输入联系人年龄: ;std::cin age;con-set_age(age);// 清空cin缓冲区std::cin.ignore(std::numeric_limitsstd::streamsize::max(), \n);// 新增电话for(int i 1;true;i){std::cout---请输入该联系人的电话i(只输入空格表示完成): ;std::string number;std::getline(std::cin,number);if(number.size() 0) break;contacts::PeopleInfo_Phone* phone con-add_phones();// phone-set_phone(number);phone-set_number(number);std::cout--请输入该联系人电话类型:|1.移动电话--2.固定电话|-----: ;int type;std::cintype;std::cin.ignore(256,\n);switch(type){case 1: phone-set_type(contacts::PeopleInfo_Phone_PhoneType::PeopleInfo_Phone_PhoneType_MP);break;case 2:phone-set_type(contacts::PeopleInfo_Phone_PhoneType::PeopleInfo_Phone_PhoneType_TEL);break;}//填充地址信息contacts::Address address;std::cout请输入工作单位地址(不填请按空格结束): ;std::string util_address;std::getline(std::cin,util_address);address.set_util_address(util_address);std::string home_address;std::cout请输入家庭地址(不填请按空格结束): ;std::getline(std::cin,home_address);address.set_home_address(home_address);//people中的mutable_data方法会返回一个开辟好的any对象地址google::protobuf::Any* any con-mutable_data();//将message信息解析到any中any-PackFrom(address);}std::cout---------------添加联系人成功---------------std::endl; } int main() {contacts::Contacts cons;std::ifstream in(contacts.bin, std::ios::binary);if (!in.is_open()){std::cout contacts.bin is not exist,create new contacts.bin std::endl;}else if (!cons.ParseFromIstream(in)){std::cout Parse contact info error! std::endl;in.close();return -1;}AddContact(cons.add_contacts());// 序列化写入文件std::ofstream out(contacts.bin, std::ios::trunc | std::ios::binary);if (!out.is_open()){std::cout write file error! std::endl;return -2;}if (!cons.SerializePartialToOstream(out)){std::cout 序列化失败! std::endl;return -3;}in.close();out.close();return 0; } //read.cc #include iostream #include fstream #include contacts.pb.hint main() {contacts::Contacts cons;std::ifstream in(contacts.bin, std::ios::in | std::ios::binary);if (!in.is_open()){std::cout open contacts.bin error! std::endl;return -1;}else if (!cons.ParsePartialFromIstream(in)){std::cout 反序列化失败! std::endl;return -1;}for (int i 0; i cons.contacts_size(); i){std::cout ------------联系人-------------- std::endl;std::cout ------------------------------- std::endl;auto people cons.contacts(i);std::cout 姓名: ;std::cout people.name() std::endl;std::cout 年龄: people.age() std::endl;std::cout -----------联系电话------------- std::endl;for (int i 0; i people.phones_size(); i){contacts::PeopleInfo_Phone phone people.phones(i);std::cout phone.number() std::endl;std::cout 电话类型: phone.PhoneType_Name(phone.type()) std::endl;}if (people.has_data()){std::cout ------------地址---------------- std::endl;google::protobuf::Any any people.data();contacts::Address address;any.UnpackTo(address);std::cout 工作单位地址: address.util_address() std::endl;std::cout 家庭地址: address.home_address() std::endl;std::cout -------------------------------- std::endl;std::cout ----------- 联系人-------------- std::endl;}else{std::cout any is not setting! std::endl;}}in.close();return 0; } Proto3语法 字段规则oneof类型 oneof类型是多选一的 //contacts.proto 例如用来定义oneof other_contact{string qq 5;string wechat 6;} //contacts。proto文件 syntax proto3; package contacts;import google/protobuf/any.proto;//地址信息 message Address{string util_address 1;string home_address 2; }message PeopleInfo{string name 1;int32 age 2;message Phone {string number 1;enum PhoneType{MP 0;TEL 1;}PhoneType type 2;}repeated Phone phones 3;google.protobuf.Any data 4;//其他联系方式oneof other_contact{string qq 5;string wechat 6;} }message Contacts{repeated PeopleInfo contacts 1; }应用 接口解释 1.通过oneof设置的字段只能填写一个即多选一模式以最后一次填写的字段为准 2.other_contact_case() 作用返回内部被设置的那个字段的常量。类型为contacts::PeopleInfo::OtherContactCase 用于读取文件时判断哪个字段是有效的。 //write.ccstd::cout 请输入其他联系方式-|1.qq---2.微信|: ;int op 0;std::cin op;std::cin.ignore(256, \n);std::string other_contact;switch (op){case 1:std::cout 请输入qq号: ;std::getline(std::cin, other_contact);con-set_qq(other_contact);break;case 2:std::cout 请输入微信号: ;std::getline(std::cin, other_contact);con-set_wechat(other_contact);break;default:std::cout未知错误!std::endl;break;} //Read.cc// 查看其他联系方式contacts::PeopleInfo::OtherContactCase other_con people.other_contact_case();switch (other_con){case contacts::PeopleInfo::OtherContactCase::kQq:std::cout QQ: people.qq() std::endl;break;case contacts::PeopleInfo::OtherContactCase::kWechat:std::cout 微信: people.wechat() std::endl;break;default:std::cout 未知错误! std::endl;break;} Proto3语法 字段规则map类型 1.map字段不能被repeated修饰//.proto文件 syntax proto3; package contacts;import google/protobuf/any.proto;//地址信息 message Address{string util_address 1;string home_address 2; }message PeopleInfo{string name 1;int32 age 2;message Phone {string number 1;enum PhoneType{MP 0;TEL 1;}PhoneType type 2;}repeated Phone phones 3;google.protobuf.Any data 4;//其他联系方式oneof other_contact{string qq 5;string wechat 6;}//备注信息mapstring,string remarks 7; }message Contacts{repeated PeopleInfo contacts 1; } 应用 接口介绍 1.mutable_remarks() 作用返回一块开辟好的map空间地址 2.insert() 作用新增map类型的数据--即key-val键值对 注意不能使用make_pair,可以使用{key,val}插入 3.remarks() 作用获取map对象 4.begin()和cbegin() 作用迭代器,用法和c的map一致 //write.ccstd::cout请输入该联系人的备注信息: ;google::protobuf::Mapstd::string, std::string* remark con-mutable_remarks();for(int i 1;;i){std::cout请输入备注标题i(按下空格结束): ;std::string key;std::getline(std::cin,key);if(key.size() 0) break;std::cout请输入备注内容(按下空格结束): ;std::string val;std::getline(std::cin,val);if(val.size() 0) break;remark-insert({key,val});} //Read.cc std::cout---------查看备注信息-----------std::endl; auto remark people.remarks(); for(int i 0;ipeople.remarks_size();i) {std::cout备注标题i1: ((remark.begin())-first)std::endl;std::cout备注内容: ((remark.begin())-second)std::endl; } std::cout----------------------------------std::endl; Proto3语法 字段规则默认值 //默认值 1.反序列化消息时如果被反序列化的⼆进制序列中不包含某个字段反序列化对象中相应字段时就 会设置为该字段的默认值。不同的类型对应的默认值不同 2.对于字符串默认值为空字符串。 3.对于字节默认值为空字节。 4.对于布尔值默认值为 false。 5.对于数值类型默认值为 0。 6.对于枚举默认值是第⼀个定义的枚举值 必须为 0。 7.对于消息字段未设置该字段。它的取值是依赖于语⾔。 8.对于设置了 repeated 的字段的默认值是空的 通常是相应语⾔的⼀个空列表 。 9.对于 消息字段 、 oneof字段 和 any字段 C 和 Java 语⾔中都有 has_ ⽅法来检测当前字段 是否被设置。 注意proto3语法下标量数据类型没有生成has_方法保证对于标量字段用户一定要手动初始化 Proto3语法 字段规则更新消息 1.如果现有的消息类型已经不再满⾜我们的需求例如需要扩展⼀个字段在不破坏任何现有代码的情 况下更新消息类型⾮常简单。遵循如下规则即可 2.禁⽌修改任何已有字段的字段编号。 3.若是移除⽼字段要保证不再使⽤移除字段的字段编号。正确的做法是保留字段编号 reserved以确保该编号将不能被重复使⽤。不建议直接删除或注释掉字段。 4.int32 uint32 int64 uint64 和 bool 是完全兼容的。可以从这些类型中的⼀个改为另⼀个 ⽽不破坏前后兼容性。若解析出来的数值与相应的类型不匹配会采⽤与 C ⼀致的处理⽅案 例如若将 64 位整数当做 32 位进⾏读取它将被截断为 32 位。 5.sint32 和 sint64 相互兼容但不与其他的整型兼容。 6.string 和 bytes 在合法 UTF-8 字节前提下也是兼容的。 7.bytes 包含消息编码版本的情况下嵌套消息与 bytes 也是兼容的。 8.fixed32 与 sfixed32 兼容 fixed64 与 sfixed64兼容。 9.enum 与 int32uint32 int64 和 uint64 兼容注意若值不匹配会被截断。但要注意当反序 列化消息时会根据语⾔采⽤不同的处理⽅案例如未识别的 proto3 枚举类型会被保存在消息 中但是当消息反序列化时如何表⽰是依赖于编程语⾔的。整型字段总是会保持其的值。 10.oneof将⼀个单独的值更改为 新 oneof 类型成员之⼀是安全和⼆进制兼容的。 11.若确定没有代码⼀次性设置多个值那么将多个字段移⼊⼀个新 oneof 类型也是可⾏的。 12.将任何字段移⼊已存在的 oneof 类型是不安全的。 字段规则reserved 1.reserved修饰的编号不能被使用 如果要删除一个已有的消息字段不要使用其对应的字段编号用reserved修饰即可 //例子reserved 1;int age 1; 此时编译不被允许 2.reserved可以用来修饰字段名 //例子:reserved age;int32 age 2;//要删除的字段此时编译不被允许 3.reserved可以用来修饰大量数字 写法1reserved 1,2,3,...; 写法2reserved 100 to 200; 连续修饰字段名可以用逗号分隔开 Proto3语法 字段规则option 本质是影响protobuf的编译功能1.选项1SPEEDZ速度最快但是占用空间更大 2.选项2CODE_SIZE速度最慢空间更小适用于包含大量的.proto文件中使用 3.选项3LITE_RUNTIME阉割版protobuf仅仅提供序列化和反序列化功能encode 4.选项4allow_alias允许将相同的常量值赋值给相同的枚举常量值 option allow_alias true; done
http://www.hkea.cn/news/14325854/

相关文章:

  • 网站建设用到的技术wamp网站建设
  • 网站内部资源推广案例网站建设的实验原理和方法
  • 驻马店市可以做网站的公司wordpress3.9.1中文
  • 大连网站建设怎么样辽宁省工程造价
  • 网站开发专业职称有哪些dw旅游网站模板下载
  • 上海网站seoseodian系统之家网站怎么做
  • 怎么做找券网站wordpress悬浮刷新
  • 做美食教程的网站有哪些上海外贸网站搭建
  • 泰州市建设监理协会网站阿里云网站备案好了 怎么建站
  • wordpress 很卡seo教程自学网
  • 物流门户网站开发wordpress 微信 支付
  • 开发一个网站的过程是什么北京千锋教育培训机构怎么样
  • 网站定制哪个好用什么网站做浏览器主页
  • vs可以做网站吗建立一个网站大约要多少钱
  • 桂林网站制作人才招聘南阳企业网站seo
  • 为什么网站开发需要写php网站优化公司哪家好
  • 福州网站设计软件公司企业建设网站的
  • 市桥做网站的公司虚拟网站服务器
  • 网站无障碍建设报告高级软件工程师
  • 建网站 温州手机网站和电脑网站跳转
  • 虹口品牌网站建设北京医疗网站建设公司排名
  • 怎样设计一个移动网站动漫网站设计源代码
  • 福建厦门网站建设公司自媒体平台注册入口快看点
  • 装修网站建设优缺点龙岗商城网站建设教程
  • 国内出名的校园文化建设网站有哪些跨境电商要投资多少钱
  • 网页做得好的网站公众号微信
  • 建企业版网站多久php网站开发工程师任职要求
  • 淘宝网站设计价格外贸型网站开发
  • 西安网站seo技术apache添加网站
  • 外贸网站建站推广知名的建站公司