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

广告营销是什么意思优化是什么

广告营销是什么意思,优化是什么,深圳服装设计学院,怎么做网站端口代理​​​​​​​Springboot仿抖音app开发之粉丝业务模块后端复盘及相关业务知识总结 Springboot仿抖音app开发之用短视频务模块后端复盘及相关业务知识总结 Springboot仿抖音app开发之用户业务模块后端复盘及相关业务知识总结 用户发表评论并显示评论总数 1. 控制层 (Comment…​​​​​​​Springboot仿抖音app开发之粉丝业务模块后端复盘及相关业务知识总结 Springboot仿抖音app开发之用短视频务模块后端复盘及相关业务知识总结 Springboot仿抖音app开发之用户业务模块后端复盘及相关业务知识总结 用户发表评论并显示评论总数 1. 控制层 (CommentController) PostMapping(create) public GraceJSONResult create(RequestBody Valid CommentBO commentBO)throws Exception {CommentVO commentVO commentService.createComment(commentBO);return GraceJSONResult.ok(commentVO); }控制层的主要职责 提供REST API接口 /comment/createPOST请求接收前端传来的JSON数据并绑定到CommentBO对象使用Valid注解进行参数校验调用服务层方法处理业务逻辑将处理结果包装成统一响应格式返回 2. 服务层 (CommentServiceImpl) Override public CommentVO createComment(CommentBO commentBO) {String commentId sid.nextShort();Comment comment new Comment();comment.setId(commentId);comment.setVlogId(commentBO.getVlogId());comment.setVlogerId(commentBO.getVlogerId());comment.setCommentUserId(commentBO.getCommentUserId());comment.setFatherCommentId(commentBO.getFatherCommentId());comment.setContent(commentBO.getContent());comment.setLikeCounts(0);comment.setCreateTime(new Date());commentMapper.insert(comment);// redis操作评论总数的累加redis.increment(REDIS_VLOG_COMMENT_COUNTS : commentBO.getVlogId(), 1);// 留言后的最新评论需要返回给前端进行展示CommentVO commentVO new CommentVO();BeanUtils.copyProperties(comment, commentVO);// 系统消息相关代码被注释掉了return commentVO; }服务层的主要职责 生成唯一评论ID (sid.nextShort())将前端数据(CommentBO)转换为数据库实体(Comment)设置额外信息点赞数初始化为0、创建时间等调用Mapper层将评论保存到数据库在Redis中增加视频的评论计数将数据库实体(Comment)转换为视图对象(CommentVO)返回给前端(注释掉的部分)创建系统消息通知视频作者有新评论 3. 数据访问层 (CommentMapper) 使用commentMapper.insert(comment)将评论数据插入到数据库 4. 数据模型 业务对象 (CommentBO) 包含用户提交的评论信息vlogerId, fatherCommentId, vlogId, commentUserId, content使用注解实现参数验证如NotBlank, Length等 数据库实体 (Comment) 映射到数据库表的实体类包含完整的评论信息id, vlogerId, fatherCommentId, vlogId, commentUserId, content, likeCounts, createTime 视图对象 (CommentVO) 返回给前端的数据对象包含额外信息commentUserNickname, commentUserFace, replyedUserNickname, isLike等 评论总数显示 非常容易理解吧 从redis中获取之前存储的评论总数 GetMapping(counts)public GraceJSONResult counts(RequestParam String vlogId) {String countsStr redis.get(REDIS_VLOG_COMMENT_COUNTS : vlogId);if (StringUtils.isBlank(countsStr)) {countsStr 0;}return GraceJSONResult.ok(Integer.valueOf(countsStr));} 为什么要Integer.valueOf(countsStr) Integer.valueOf(countsStr) 的作用是将字符串类型的数字转换为 Integer 对象。这在这段代码中非常重要原因如下 数据类型一致性 Redis 中存储的评论数是字符串类型即使存储的是数字从 Redis 获取时也是字符串前端或调用方期望接收的是数值类型Integer而不是字符串 统一响应格式 GraceJSONResult.ok() 方法接收各种数据类型并将其包装成统一的响应格式返回 Integer 类型更符合 API 的语义因为评论数就是一个整数 避免前端处理 如果直接返回字符串 0前端在进行数值运算时可能需要额外的转换返回 Integer 类型让前端可以直接使用这个数值无需自行转换 确保类型安全 Java 是强类型语言通过明确的类型转换可以避免隐式转换带来的潜在问题Integer.valueOf() 比 Integer.parseInt() 更优因为它可以重用常用整数的缓存 这段代码的完整逻辑是 从 Redis 获取指定视频的评论数字符串格式如果 Redis 中没有该数据默认为 0将字符串转换为 Integer 对象将转换后的 Integer 对象包装在统一响应格式中返回 这种处理方式体现了 RESTful API 设计的最佳实践确保返回的数据类型与其语义一致并减轻了客户端的处理负担。 实现查询评论列表与联调 1. 控制层实现 (CommentController) GetMapping(list) public GraceJSONResult list(RequestParam String vlogId,RequestParam(defaultValue ) String userId,RequestParam Integer page,RequestParam Integer pageSize) {return GraceJSONResult.ok(commentService.queryVlogComments(vlogId,userId,page,pageSize)); }控制层职责 提供REST API接口 /comment/listGET请求接收前端传来的参数视频ID、用户ID、页码、每页数量为userId设置默认值为空字符串处理可选参数调用服务层方法查询评论列表将查询结果包装成统一响应格式返回 2. 服务层实现 (CommentServiceImpl) Override public PagedGridResult queryVlogComments(String vlogId,String userId,Integer page,Integer pageSize) {MapString, Object map new HashMap();map.put(vlogId, vlogId);PageHelper.startPage(page, pageSize);ListCommentVO list commentMapperCustom.getCommentList(map);return setterPagedGrid(list, page); }服务层职责 创建参数Map用于传递查询条件设置vlogId作为查询条件使用PageHelper进行分页设置调用Mapper查询评论列表将结果封装为分页对象返回 3. 数据访问层实现 (CommentMapperCustom) 接口定义 public ListCommentVO getCommentList(Param(paramMap) MapString, Object map);SQL查询实现 select idgetCommentList parameterTypemap resultTypecom.imooc.vo.CommentVOSELECTc.id as commentId,c.vlog_id as vlogId,u.id as vlogerId,u.nickname as commentUserNickname,u.face as commentUserFace,c.father_comment_id as fatherCommentId,c.comment_user_id as commentUserId,c.content as content,c.like_counts as likeCounts,fu.nickname as replyedUserNickname,c.create_time as createTime FROMcomment as c LEFT JOINusers as u ONc.comment_user_id u.id LEFT JOINcomment as fc ONc.father_comment_id fc.id LEFT JOINusers as fu ONfc.comment_user_id fu.id WHEREc.vlog_id #{paramMap.vlogId} ORDER BYc.like_counts DESC,c.create_time DESC/select 评论列表查询SQL的设计详解 SQL整体设计思路 这段SQL是为了实现短视频平台的评论列表功能需要展示评论内容及相关的用户信息并支持评论回复的层级关系。整体设计采用了多表关联查询的方式将评论数据与用户数据整合在一起。 表结构及关系设计 该查询涉及到两个主要数据表 comment表存储评论的基本信息users表存储用户的基本信息 在SQL中这些表以不同的别名出现形成了四个逻辑实体 c主评论表包含当前查询的评论数据u评论作者表包含评论作者的信息fc父评论表用于处理回复关系fu父评论作者表包含被回复者的信息 关联关系详解 1. 评论与评论作者关联 LEFT JOIN users as u ON c.comment_user_id u.id这个关联将评论与发表评论的用户连接起来 关联条件评论表的comment_user_id与用户表的id使用LEFT JOIN确保即使用户信息缺失评论数据也能返回查询目的获取评论者的昵称和头像 2. 评论与父评论关联 LEFT JOIN comment as fc ON c.father_comment_id fc.id这个关联实现了评论的层级结构 关联条件当前评论的father_comment_id与父评论的id表的自关联comment表自己与自己关联通过不同别名区分设计意图支持评论回复功能建立评论之间的父子关系使用LEFT JOIN允许一级评论存在father_comment_id可能为null或0 3. 父评论与父评论作者关联 LEFT JOIN users as fu ON fc.comment_user_id fu.id这个关联获取被回复者的信息 关联条件父评论的comment_user_id与用户表的id设计目的获取被回复者的昵称以便显示回复某人的效果使用LEFT JOIN即使父评论作者信息缺失也不影响结果返回 删除评论功能的实现分析  1. 控制层实现 (CommentController) DeleteMapping(delete) public GraceJSONResult delete(RequestParam String commentUserId,RequestParam String commentId,RequestParam String vlogId) {commentService.deleteComment(commentUserId,commentId,vlogId);return GraceJSONResult.ok(); }控制层职责 提供REST API接口 /comment/deleteDELETE请求接收三个关键参数评论者ID、评论ID和视频ID调用服务层方法执行删除逻辑返回统一的成功响应格式 设计特点 使用HTTP DELETE方法符合RESTful设计规范参数通过RequestParam接收表明这些是必填项返回标准化的响应格式 2. 服务层实现 (CommentServiceImpl) Override public void deleteComment(String commentUserId,String commentId,String vlogId) {Comment pendingDelete new Comment();pendingDelete.setId(commentId);pendingDelete.setCommentUserId(commentUserId);commentMapper.delete(pendingDelete);// 评论总数的累减redis.decrement(REDIS_VLOG_COMMENT_COUNTS : vlogId, 1); }服务层职责 构建待删除的评论对象设置评论ID和评论者ID作为删除条件调用Mapper执行数据库删除操作在Redis中减少视频的评论计数 设计特点 同时验证评论ID和评论者ID确保用户只能删除自己的评论数据库操作与缓存操作结合保持数据一致性使用Redis计数器维护评论数避免频繁查询数据库 3. 数据访问层实现 虽然代码片段中没有显示commentMapper.delete()的具体实现但根据通用Mapper的使用方式这是一个条件删除操作 // MyBatis通用Mapper的典型实现 public interface CommentMapper extends MapperComment {// delete方法会根据非空字段作为条件// 等价于 DELETE FROM comment WHERE id #{id} AND comment_user_id #{commentUserId} }数据访问层职责 执行SQL删除操作根据提供的条件评论ID和评论者ID定位要删除的记录 评论点赞与取消点赞功能分析 1. 点赞功能实现 PostMapping(like) public GraceJSONResult like(RequestParam String commentId,RequestParam String userId) {// 故意犯错bigkeyredis.incrementHash(REDIS_VLOG_COMMENT_LIKED_COUNTS, commentId, 1);// // 改为每个评论单独一个 Key// String key REDIS_VLOG_COMMENT_LIKED_COUNTS : commentId;// redis.increment(key, 1);redis.setHashValue(REDIS_USER_LIKE_COMMENT, userId : commentId, 1);// // 改为每个用户评论组合一个 Key// String key REDIS_USER_LIKE_COMMENT : userId : commentId;// redis.set(key, 1);// redis.hset(REDIS_USER_LIKE_COMMENT, userId, 1);return GraceJSONResult.ok(); }功能逻辑 接收评论ID和用户ID作为参数在Redis中增加评论的点赞数记录用户对该评论的点赞状态返回成功响应 2. 取消点赞功能实现 PostMapping(unlike) public GraceJSONResult unlike(RequestParam String commentId,RequestParam String userId) {redis.decrementHash(REDIS_VLOG_COMMENT_LIKED_COUNTS, commentId, 1);redis.hdel(REDIS_USER_LIKE_COMMENT, userId : commentId);return GraceJSONResult.ok(); }功能逻辑 接收评论ID和用户ID作为参数在Redis中减少评论的点赞数删除用户对该评论的点赞状态记录返回成功响应 3. 设计问题分析 3.1 Redis Bigkey问题 代码中注释部分明确指出故意犯错bigkey这表明当前实现存在Redis性能问题 // 故意犯错bigkey redis.incrementHash(REDIS_VLOG_COMMENT_LIKED_COUNTS, commentId, 1);问题描述 使用单个hash结构REDIS_VLOG_COMMENT_LIKED_COUNTS存储所有评论的点赞数随着评论数增长这个hash会变得非常大成为bigkey大型hash会导致Redis性能下降甚至可能导致服务不稳定 更好的方案代码中已注释 String key REDIS_VLOG_COMMENT_LIKED_COUNTS : commentId; redis.increment(key, 1);这种方案为每个评论创建独立的key避免了单个hash过大的问题。 3.2 用户点赞记录存储问题 同样的bigkey问题也存在于用户点赞记录的存储中 redis.setHashValue(REDIS_USER_LIKE_COMMENT, userId : commentId, 1);问题描述 使用单个hashREDIS_USER_LIKE_COMMENT存储所有用户的所有点赞记录该hash将随用户数和评论数的增长而迅速膨胀对大型hash的操作会变得越来越慢 更好的方案代码中已注释 String key REDIS_USER_LIKE_COMMENT : userId : commentId; redis.set(key, 1);这种方案为每个用户对每个评论的点赞创建独立的key避免了hash结构过大。 Redis BigKey 问题解析  什么是 BigKey 问题 BigKey 指的是 Redis 中存储的某个 Key 对应的 Value 过大通常表现为 一个 String 类型的 Value 过大超过 10KB一个 Hash/List/Set/ZSet 类型的元素过多比如 Hash 有数千个字段 当前代码中的 BigKey 问题 1. REDIS_VLOG_COMMENT_LIKED_COUNTS Hash 结构问题 redis.incrementHash(REDIS_VLOG_COMMENT_LIKED_COUNTS, commentId, 1);这种方式将所有视频评论的点赞数都存储在一个 Hash 中 随着评论数量增加这个 Hash 会变得非常庞大每次操作都需要加载整个 Hash 到内存可能导致内存占用过高、操作延迟增加 2. REDIS_USER_LIKE_COMMENT Hash 结构问题 redis.setHashValue(REDIS_USER_LIKE_COMMENT, userId : commentId, 1);这种方式将所有用户对评论的点赞关系存储在一个 Hash 中 用户和评论数量增加时这个 Hash 会变得极其庞大每个用户点赞一个评论就增加一个字段可能导致内存爆炸性增长 改进方案注释中的正确做法 1. 为每个评论单独创建 Key String key REDIS_VLOG_COMMENT_LIKED_COUNTS : commentId; redis.increment(key, 1);优点 每个评论的点赞数独立存储避免单个 Key 过大操作更高效 2. 为每个用户评论组合创建 Key String key REDIS_USER_LIKE_COMMENT : userId : commentId; redis.set(key, 1);优点 每个点赞关系独立存储避免 Hash 结构无限增长更容易管理和清理 BigKey 的危害 内存不均导致 Redis 内存使用不平衡可能引发内存不足阻塞风险操作大 Key 可能导致 Redis 阻塞网络拥塞传输大 Key 消耗更多带宽持久化问题AOF 重写和 RDB 保存时效率降低迁移困难集群环境下数据迁移更困难 最佳实践建议 避免使用单个 Key 存储大量数据合理拆分数据结构如示例中的改进方案对于计数器类需求考虑使用多个 Key 而不是单个 Hash定期监控 Redis 的 Key 大小分布对大 Key 进行拆分或使用其他存储方案 Redis Hash 数据结构详解  Redis Hash 的三层结构 Redis 的 Hash 数据结构实际上是三层结构 外层 Key - Hash 结构的名称如 REDIS_VLOG_COMMENT_LIKED_COUNTS内层 Field - Hash 内部的字段名如 commentIdValue - 字段对应的值点赞数 所以完整结构是Key → (Field → Value) 对比普通 Key-Value 结构类型示例说明普通 Key-ValueSET comment:1001:likes 5直接键值对Hash 结构HSET comment_likes comment:1001 5两层映射关系 您的代码具体解析 redis.incrementHash(REDIS_VLOG_COMMENT_LIKED_COUNTS, commentId, 1);对应关系 外层 KeyREDIS_VLOG_COMMENT_LIKED_COUNTS所有评论点赞数的容器FieldcommentId具体是哪个评论Value点赞数通过参数1实现原子递增 为什么这样设计 组织相关数据可以把相关联的多个字段放在一个Hash中 例如用户信息user:1001 → {name:张三, age:25, email:xxxx.com} 减少Key数量避免为每个小数据都创建独立Key 原子操作可以单独操作Hash中的某个字段 用户是否点赞评论与评论总数展示  主要是在查询接口中添加业务逻辑 Overridepublic PagedGridResult queryVlogComments(String vlogId,String userId,Integer page,Integer pageSize) {MapString, Object map new HashMap();map.put(vlogId, vlogId);PageHelper.startPage(page, pageSize);ListCommentVO list commentMapperCustom.getCommentList(map);for (CommentVO cv:list) {String commentId cv.getCommentId();// 当前短视频的某个评论的点赞总数String countsStr redis.getHashValue(REDIS_VLOG_COMMENT_LIKED_COUNTS, commentId);Integer counts 0;if (StringUtils.isNotBlank(countsStr)) {counts Integer.valueOf(countsStr);}cv.setLikeCounts(counts);// 判断当前用户是否点赞过该评论String doILike redis.hget(REDIS_USER_LIKE_COMMENT, userId : commentId);if (StringUtils.isNotBlank(doILike) doILike.equalsIgnoreCase(1)) {cv.setIsLike(YesOrNo.YES.type);}}return setterPagedGrid(list, page);} 1. 基础评论数据查询 MapString, Object map new HashMap(); map.put(vlogId, vlogId); PageHelper.startPage(page, pageSize); ListCommentVO list commentMapperCustom.getCommentList(map);创建参数Map设置视频ID作为查询条件使用PageHelper设置分页参数调用自定义Mapper查询评论列表得到包含基本评论信息的VO对象列表 2. 为每条评论添加点赞数 for (CommentVO cv:list) {String commentId cv.getCommentId();// 当前短视频的某个评论的点赞总数String countsStr redis.getHashValue(REDIS_VLOG_COMMENT_LIKED_COUNTS, commentId);Integer counts 0;if (StringUtils.isNotBlank(countsStr)) {counts Integer.valueOf(countsStr);}cv.setLikeCounts(counts);// ... }遍历评论列表从Redis的hash结构中获取每条评论的点赞数若点赞数不存在则默认为0将点赞数设置到评论VO对象中 3. 判断当前用户是否点赞过评论 // 判断当前用户是否点赞过该评论 String doILike redis.hget(REDIS_USER_LIKE_COMMENT, userId : commentId); if (StringUtils.isNotBlank(doILike) doILike.equalsIgnoreCase(1)) {cv.setIsLike(YesOrNo.YES.type); }构造用户点赞记录的key格式为userId:commentId从Redis的hash结构中查询该记录是否存在如果记录存在且值为1则设置评论VO对象的isLike属性为YES 4. 封装分页结果返回 return setterPagedGrid(list, page);将处理后的评论列表封装成统一的分页响应对象返回
文章转载自:
http://www.morning.wrlqr.cn.gov.cn.wrlqr.cn
http://www.morning.ypdhl.cn.gov.cn.ypdhl.cn
http://www.morning.klrpm.cn.gov.cn.klrpm.cn
http://www.morning.mdrnn.cn.gov.cn.mdrnn.cn
http://www.morning.fbtgp.cn.gov.cn.fbtgp.cn
http://www.morning.gczzm.cn.gov.cn.gczzm.cn
http://www.morning.lfpdc.cn.gov.cn.lfpdc.cn
http://www.morning.xppj.cn.gov.cn.xppj.cn
http://www.morning.qbxdt.cn.gov.cn.qbxdt.cn
http://www.morning.rlrxh.cn.gov.cn.rlrxh.cn
http://www.morning.qxkcx.cn.gov.cn.qxkcx.cn
http://www.morning.bqhlp.cn.gov.cn.bqhlp.cn
http://www.morning.brwp.cn.gov.cn.brwp.cn
http://www.morning.tkgjl.cn.gov.cn.tkgjl.cn
http://www.morning.xbhpm.cn.gov.cn.xbhpm.cn
http://www.morning.lgxzj.cn.gov.cn.lgxzj.cn
http://www.morning.c7624.cn.gov.cn.c7624.cn
http://www.morning.rcntx.cn.gov.cn.rcntx.cn
http://www.morning.kzhgy.cn.gov.cn.kzhgy.cn
http://www.morning.vaqmq.cn.gov.cn.vaqmq.cn
http://www.morning.xstfp.cn.gov.cn.xstfp.cn
http://www.morning.zylzk.cn.gov.cn.zylzk.cn
http://www.morning.ftzll.cn.gov.cn.ftzll.cn
http://www.morning.wqjpl.cn.gov.cn.wqjpl.cn
http://www.morning.rxdsq.cn.gov.cn.rxdsq.cn
http://www.morning.lgznc.cn.gov.cn.lgznc.cn
http://www.morning.gyfhk.cn.gov.cn.gyfhk.cn
http://www.morning.jpgfq.cn.gov.cn.jpgfq.cn
http://www.morning.frfpx.cn.gov.cn.frfpx.cn
http://www.morning.jgnjl.cn.gov.cn.jgnjl.cn
http://www.morning.hxlch.cn.gov.cn.hxlch.cn
http://www.morning.qjrjs.cn.gov.cn.qjrjs.cn
http://www.morning.nsrtvu.com.gov.cn.nsrtvu.com
http://www.morning.cwrnr.cn.gov.cn.cwrnr.cn
http://www.morning.jrbyz.cn.gov.cn.jrbyz.cn
http://www.morning.dtnzk.cn.gov.cn.dtnzk.cn
http://www.morning.ygxf.cn.gov.cn.ygxf.cn
http://www.morning.qttft.cn.gov.cn.qttft.cn
http://www.morning.hxxzp.cn.gov.cn.hxxzp.cn
http://www.morning.gccdr.cn.gov.cn.gccdr.cn
http://www.morning.jfmjq.cn.gov.cn.jfmjq.cn
http://www.morning.hchrb.cn.gov.cn.hchrb.cn
http://www.morning.qhkdt.cn.gov.cn.qhkdt.cn
http://www.morning.wmyqw.com.gov.cn.wmyqw.com
http://www.morning.xxwfq.cn.gov.cn.xxwfq.cn
http://www.morning.sgmis.com.gov.cn.sgmis.com
http://www.morning.sjsfw.cn.gov.cn.sjsfw.cn
http://www.morning.mqldj.cn.gov.cn.mqldj.cn
http://www.morning.pswqx.cn.gov.cn.pswqx.cn
http://www.morning.nmbbt.cn.gov.cn.nmbbt.cn
http://www.morning.yongkangyiyuan-pfk.com.gov.cn.yongkangyiyuan-pfk.com
http://www.morning.qkqzm.cn.gov.cn.qkqzm.cn
http://www.morning.spsqr.cn.gov.cn.spsqr.cn
http://www.morning.gtbjc.cn.gov.cn.gtbjc.cn
http://www.morning.kmcby.cn.gov.cn.kmcby.cn
http://www.morning.mdfxn.cn.gov.cn.mdfxn.cn
http://www.morning.dkqr.cn.gov.cn.dkqr.cn
http://www.morning.fwnqq.cn.gov.cn.fwnqq.cn
http://www.morning.smmby.cn.gov.cn.smmby.cn
http://www.morning.fdrch.cn.gov.cn.fdrch.cn
http://www.morning.rxydr.cn.gov.cn.rxydr.cn
http://www.morning.xpwdf.cn.gov.cn.xpwdf.cn
http://www.morning.lmrjn.cn.gov.cn.lmrjn.cn
http://www.morning.sbjhm.cn.gov.cn.sbjhm.cn
http://www.morning.cspwj.cn.gov.cn.cspwj.cn
http://www.morning.zzfjh.cn.gov.cn.zzfjh.cn
http://www.morning.zgnng.cn.gov.cn.zgnng.cn
http://www.morning.rsnn.cn.gov.cn.rsnn.cn
http://www.morning.mpscg.cn.gov.cn.mpscg.cn
http://www.morning.wgxtz.cn.gov.cn.wgxtz.cn
http://www.morning.jyfrz.cn.gov.cn.jyfrz.cn
http://www.morning.hxlpm.cn.gov.cn.hxlpm.cn
http://www.morning.czqqy.cn.gov.cn.czqqy.cn
http://www.morning.bgzgq.cn.gov.cn.bgzgq.cn
http://www.morning.tssmk.cn.gov.cn.tssmk.cn
http://www.morning.jhwqp.cn.gov.cn.jhwqp.cn
http://www.morning.rdzlh.cn.gov.cn.rdzlh.cn
http://www.morning.cwwbm.cn.gov.cn.cwwbm.cn
http://www.morning.kjdxh.cn.gov.cn.kjdxh.cn
http://www.morning.kwhrq.cn.gov.cn.kwhrq.cn
http://www.tj-hxxt.cn/news/277950.html

相关文章:

  • 哪些网站可以做问卷调查赚钱网站建设添加汉语
  • 免费在线网站模板茂名本土网站建设公司
  • 什么叫网站降权wordpress页面怎么添加
  • 彩票网站里的统计怎么做黄山旅游攻略
  • 长沙有哪些公司如何优化网络速度
  • 百度快照网站网站开发建设及推广合同
  • 中山网站建设推广网站开发属于专利吗
  • 地下城钓鱼网站怎么做asp.net网站制作实例
  • 创建站点的基本步骤短视频广告分析
  • 即时通讯型网站开发网页设计作业之玩具商城网站
  • 大理网站建设网站建设网站开发技术规范
  • 怎么查询网站的点击量创客联盟网站建设
  • 甘肃第九建设集团公司网站55建筑网官网
  • 上海网站推广阿里巴巴网站首页怎么制作
  • 重庆百度网站推广外贸拓客软件
  • 团购网站模块淄博汽车网站建设
  • 做国外网站调查挣取零花钱wordpress ftp存储
  • wordpress接收表单石家庄seo网站优化公司
  • 一下成都网站建设公司排名h5制作价格
  • 东莞微网站做网站应该选择怎样的公司
  • 自己做一个音乐网站怎么做网络编辑培训学校
  • 怎么建设维护学校的网站十大外包公司排名
  • 东莞网站建设优化东莞工业产品设计与创客实践
  • 兰溪企业网站搭建地址手机移动端网站
  • 金山区做网站公司南昌诚推网络技术有限公司
  • wordpress 翻译更新免费关键词排名优化软件
  • 部队网站建设爱做的小说网站吗
  • 网站建设 开发的团队需要几个人宁波建工工程集团有限公司
  • 网站keywords多少字视觉中国网站建设公司
  • 网站怎么引入微信支付一站式快速网站排名多少钱