鸿蒙NEXT项目实战-百得知识库05

news2025/3/21 1:17:55

代码仓地址,大家记得点个star

IbestKnowTeach: 百得知识库基于鸿蒙NEXT稳定版实现的一款企业级开发项目案例。 本案例涉及到多个鸿蒙相关技术知识点: 1、布局 2、配置文件 3、组件的封装和使用 4、路由的使用 5、请求响应拦截器的封装 6、位置服务 7、三方库的使用和封装 8、头像上传 9、应用软件更新等https://gitee.com/xt1314520/IbestKnowTeach

消息页面开发

设计图

需求分析

消息组件的封装

import { CommonConstant } from '../contants/CommonConstant'

@Component
  export struct MessageComponent {
    @State icon: ResourceStr = ''
    @State title: string = ''
    @Prop content: string
    @Prop unReadCount: number

    build() {
      Row({ space: 15 }) {
        Badge({
          count: this.unReadCount,
          position: BadgePosition.RightTop,
          style: { badgeSize: 15, badgeColor: '#FA2A2D' }
        }) {
          Image(this.icon)
            .width($r('app.float.common_width_small')).aspectRatio(1)
        }

        Column({ space: 10 }) {
          Text(this.title)
            .fontWeight(FontWeight.Medium)
            .fontSize($r('app.float.common_font_size_medium'))
          Text(this.content)
            .maxLines(1)
            .textOverflow({ overflow: TextOverflow.Ellipsis })
            .fontColor($r('app.color.common_gray'))
            .fontSize($r('app.float.common_font_size_small'))
        }.height(80).justifyContent(FlexAlign.Center)
          .alignItems(HorizontalAlign.Start)
          .width('80%')
      }
      .width(CommonConstant.WIDTH_FULL)
        .height(80)
        .backgroundColor($r('app.color.common_white'))
        .borderRadius(15)
        .padding(10)
    }
  }

编写消息页面的接口方法

import http from '../request/Request'
import { MessageInfoNew, PageVo, UserMessageCount, UserMessageInfo, UserMessagePageParam } from './MessageApi.type'

/**
 * 消息接口
 */
class MessageApi {
  /**
   * 获取最新消息
   */
  getMessageNew = (): Promise<Array<MessageInfoNew>> => {
    return http.get('/v1/message/new')
  }
  /**
   * 查询用户获得的消息总数量和未读
   */
  getUserMessageCount = (): Promise<UserMessageCount> => {
    return http.get('/v1/message/count')
  }
  /**
   * 用户根据消息分类查询分页的消息
   */
  getMessageList = (data: UserMessagePageParam): Promise<PageVo<UserMessageInfo>> => {
    return http.get('/v1/message/list?type=' + data.type + '&&page=' + data.page + '&&pageSize=' + data.pageSize)
  }
  /**
   * 查看消息详情
   */
  getMessageInfo = (data: number): Promise<UserMessageInfo> => {
    return http.get('/v1/message/info?id=' + data)
  }
}

const messageApi = new MessageApi();

export default messageApi as MessageApi;
/**
 * 最新消息
 */
export interface MessageInfoNew extends BaseTime {
  /**
   * 消息id
   */
  id: number
  /**
   * 消息标题
   */
  title: string
  /**
   * 消息内容
   */
  content: string
  /**
   * 消息类型'1' 系统消息 '2' 通知公告
   */
  type: string

}

/**
 * 时间
 */
export interface BaseTime {
  /**
   * 创建时间
   */
  createTime?: Date
  /**
   * 更新时间
   */
  updateTime?: Date
}

/**
 * 分页参数
 */
export interface PageParam {
  /**
   * 当前页
   */
  page?: number
  /**
   * 每一页展示的数据条数
   */
  pageSize?: number
}

/**
 * 消息总数量和未读
 */
export interface UserMessageCount {
  /**
   * 总消息数量
   */
  totalQuantity: number
  /**
   * 总未读数量
   */
  totalUnReadQuantity: number
  /**
   * 系统消息未读数量
   */
  systemUnReadQuantity: number
  /**
   * 通知公告消息未读数量
   */
  noticeUnReadQuantity: number
}


/**
 * 用户消息详情
 */
export interface UserMessageInfo extends BaseTime {
  /**
   * 用户消息id
   */
  id: number
  /**
   * 是否查看 '0'未查看 '1'查看
   */
  isLook: string
  /**
   * 消息id
   */
  messageId?: number
  /**
   * 消息标题
   */
  title: string
  /**
   * 消息内容
   */
  content: string
  /**
   * 消息类型'1' 系统消息 '2' 通知公告
   */
  type?: string
  /**
   * 创建时间
   */
  time: string

}

/**
 * 分页响应参数
 */
export interface PageVo<T> {
  current: number,
  size: number,
  total: number,
  records: Array<T>
}


/**
 * 用户根据消息分类查询所有的消息
 */
export interface UserMessagePageParam extends PageParam {
  /**
   * 消息类型
   */
  type: string
}

学习页面开发

设计图

需求分析

学习打卡

1、手机定位

在module.json5文件里面配置位置权限

代码向用户申请权限(弹窗)

/**
 * 动态授权
 */
async aboutToAppear() {
  // 使用UIExtensionAbility:将common.UIAbilityContext 替换为common.UIExtensionContext
  const context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext;
  // 定义要申请的权限
  const permissions: Array<Permissions> = ['ohos.permission.APPROXIMATELY_LOCATION'];
  let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
  // requestPermissionsFromUser会判断权限的授权状态来决定是否唤起弹窗
  try {
    const data = await atManager.requestPermissionsFromUser(context, permissions);
    let grantStatus: Array<number> = data.authResults;
    let length: number = grantStatus.length;
    for (let i = 0; i < length; i++) {
      if (grantStatus[i] === 0) {
        // 获取位置信息
        this.getLocation()
      } else {
        // 用户拒绝授权,提示用户必须授权才能访问当前页面的功能,并引导用户到系统设置中打开相应的权限
        showToast('用户必须授权才能访问当前定位功能')
        return;
      }
    }
  } catch (error) {
    showToast('用户必须授权才能访问当前定位功能')
  }
}

获取用户位置信息,获取经度纬度然后进行地理编码

/**
 * 获取位置
 */
async getLocation() {
  let request: geoLocationManager.SingleLocationRequest = {
    'locatingPriority': geoLocationManager.LocatingPriority.PRIORITY_LOCATING_SPEED,
    'locatingTimeoutMs': 10000
  }
  try {
    // 调用getCurrentLocation获取当前设备位置,通过promise接收上报的位置
    const result = await geoLocationManager.getCurrentLocation(request)
    Logger.info('current location: ' + JSON.stringify(result));
    // 判断地理编码服务是否可用
    let isAvailable = geoLocationManager.isGeocoderAvailable();
    if (isAvailable) {
      // 地理编码服务可用
      let reverseGeocodeRequest: geoLocationManager.ReverseGeoCodeRequest =
        { "latitude": result.latitude, "longitude": result.longitude, "maxItems": 1 };
      geoLocationManager.getAddressesFromLocation(reverseGeocodeRequest, (err, data) => {
        if (err) {
          Logger.error('getAddressesFromLocation err: ' + JSON.stringify(err));
        } else {
          Logger.info('getAddressesFromLocation data: ' + JSON.stringify(data));
          // 成功获取到位置信息
          this.location = data[0].administrativeArea + '' + data[0].subAdministrativeArea
          return
        }
      });
    } else {
      showToast('地理编码服务不可用')
    }
  } catch (err) {
    Logger.error("errCode:" + JSON.stringify(err));
    showToast("获取位置失败")
  }
}

2、日历组件

使用我们一开始项目准备阶段引入的鸿蒙三方库ibest-ui

import { IBestCalendar } from "@ibestservices/ibest-ui";
// 日历
IBestCalendar({
  clock: true, // 设置 clock 为 true, 可开启打卡模式, 打卡模式下只能切换年月, 不能选择日期
  defaultSelectedDate: this.clockDate, // 打卡的日期是一个字符串数组
  clockSuccessText: '✔', // 已打卡展示的
  unClockText: '✖', // 未打卡展示的
})

3、打卡记录

4、编写学习打卡接口方法
import http from '../request/Request'
import { LearnClockParam, PageParam, UserLearnClockData } from './LearnClockApi.type'
import { PageVo } from './MessageApi.type'

/**
 * 消息接口
 */
class LearnClockApi {
  /**
   * 学习打卡
   */
  learnClock = (data: LearnClockParam) => {
    return http.post('/v1/learn/clock', data)
  }
  /**
   * 查询用户已打卡的日期
   */
  listClockTime = (): Promise<Array<string>> => {
    return http.get('/v1/learn/listClockTime')
  }
  /**
   * 查询用户今日是否打卡
   */
  isClock = (): Promise<boolean> => {
    return http.get('/v1/learn/isClock')
  }
  /**
   * 分页查询用户打卡记录
   */
  pageListUserClock = (data: PageParam): Promise<PageVo<UserLearnClockData>> => {
    return http.get('/v1/learn/page?page=' + data.page + '&&pageSize=' + data.pageSize)
  }
}

const learnClockApi = new LearnClockApi();

export default learnClockApi as LearnClockApi;

/**
 * 学习打卡入参
 */
export interface LearnClockParam {
  /**
   * 打卡地点
   */
  location: string
  /**
   * 打卡内容
   */
  content: string
}

/**
 * 时间
 */
export interface BaseTime {
  /**
   * 创建时间
   */
  createTime?: Date
  /**
   * 更新时间
   */
  updateTime?: Date
}

/**
 * 分页参数
 */
export interface PageParam {
  /**
   * 当前页
   */
  page?: number
  /**
   * 每一页展示的数据条数
   */
  pageSize?: number
}


/**
 * 分页响应参数
 */
export interface PageVo<T> {
  current: number,
  size: number,
  total: number,
  records: Array<T>
}

/**
 * 用户打卡记录数据
 */
export interface UserLearnClockData extends BaseTime {

  /**
   * 学习打卡id
   */
  id: number
  /**
   * 打卡地点
   */
  location: string
  /**
   * 打卡内容
   */
  content: string
  /**
   * 用户昵称
   */
  nickname: string
  /**
   * 创建时间字符串格式
   */
  time: string

}

学习目标

1、目标整体进度

使用的是鸿蒙进度条组件

// 环形进度条
Stack() {
  Progress({
    value: this.countData.completeQuantity,
    total: this.countData.totalQuantity,
    type: ProgressType.Ring
  })
    .width($r('app.float.common_width_medium'))
    .height($r('app.float.common_height_medium'))
    .color('#1698CE')
    .style({ strokeWidth: 8 })
  Text(this.countData.completeQuantity + '/' + this.countData.totalQuantity)
    .fontSize($r('app.float.common_font_size_tiny'))
}

2、添加目标

使用的是ibest-ui里面的IBestDialog组件

IBestDialog({
  visible: $dialogVisible,
  title: "添加目标",
  showCancelButton: true,
  defaultBuilder: (): void => this.formInputContain(),
  beforeClose: async (action) => {
    if (action === 'cancel') {
      return true
    }
    const valueLength = this.inputTargetValue.trim().length;
    this.formInputError = !valueLength;
    if (!this.formInputError) {
      // 添加新目标
      await targetInfoApi.addTargetInfo({ content: this.inputTargetValue })
      showToast('添加目标成功')
      // 查询数据
      this.page = 1
      this.aboutToAppear()
      return true
    }
    return !this.formInputError
  }
})
@Builder
  formInputContain() {
    Column() {
      TextInput({ 'placeholder': '请输入目标内容,长度不能超过255字符' })
        .fontSize(14)
        .placeholderFont({ size: 14 })
        .onChange((value) => {
          this.inputTargetValue = value;
          this.formInputError = false
        })
      if (this.formInputError) {
        Text('目标内容不能为空')
          .width(CommonConstant.WIDTH_FULL)
          .textAlign(TextAlign.Start)
          .margin({
            top: 5,
            left: 5
          })
          .fontColor(Color.Red)
          .fontSize($r('app.float.common_font_size_small'))
          .transition({ type: TransitionType.Insert, opacity: 1 })
          .transition({ type: TransitionType.Delete, opacity: 0 })
      }

    }.width('90%').margin({ top: 15, bottom: 15 })
  }
3、完成、删除目标

左滑目标即可看到完成和删除按钮

使用的是ListItem.swipeAction方法

核心代码如下

@Builder
  itemEnd(item: TargetInfoVo) {
    Row() {
      // 构建尾端滑出组件
      Button({ type: ButtonType.Circle }) {
        Image($r('app.media.icon_finish'))
          .width(40)
          .aspectRatio(1)
      }
      .onClick(async () => {
        // 完成未完成的目标
        if (item.status === '1') {
          showToast('当前目标已完成,无需重复点击')
          return
        }
        // 完成目标
        await targetInfoApi.completeTargetInfo({ id: item.id })
        showToast('目标已完成')
        router.replaceUrl({ url: RouterConstant.VIEWS_LEARN_TARGET })
      }).margin({ right: 10 })

      // 构建尾端滑出组件
      Button({ type: ButtonType.Circle }) {
        Image($r('app.media.icon_delete'))
          .width(40)
          .aspectRatio(1)
      }
      .margin({ right: 10 })
        .onClick(async () => {
          IBestDialogUtil.open({
            title: "提示",
            message: "是否确认删除当前目标?",
            showCancelButton: true,
            onConfirm: async () => {
              // 删除目标
              await targetInfoApi.deleteTargetInfo({ id: item.id })
              showToast('删除目标成功')
              router.replaceUrl({ url: RouterConstant.VIEWS_LEARN_TARGET })
            }
          })
        })
    }.justifyContent(FlexAlign.SpaceBetween)
  }
4、编写学习目标接口方法
import http from '../request/Request'
import { PageParam, PageVo, TargetInfoAddParam,
         TargetInfoCompleteParam,
         TargetInfoCountVo,
         TargetInfoDeleteParam,
         TargetInfoEditParam,
         TargetInfoVo } from './TargetInfoApi.type'

/**
 * 目标内容接口
 */
class TargetInfoApi {
  /**
   * 获取用户整体目标完成进度统计
   */
  getTargetInfoCount = (): Promise<TargetInfoCountVo> => {
    return http.get('/v1/target/count')
  }
  /**
   * 分页查询用户整体目标
   */
  pageListTargetInfo = (data: PageParam): Promise<PageVo<TargetInfoVo>> => {
    return http.get('/v1/target/page?page=' + data.page + '&&pageSize=' + data.pageSize)
  }
  /**
   * 新增目标
   */
  addTargetInfo = (data: TargetInfoAddParam) => {
    return http.post('/v1/target/add', data)
  }

  /**
   * 修改目标
   */
  editTargetInfo = (data: TargetInfoEditParam) => {
    return http.post('/v1/target/edit', data)
  }

  /**
   * 完成目标
   */
  completeTargetInfo = (data: TargetInfoCompleteParam) => {
    return http.post('/v1/target/complete', data)
  }

  /**
   * 删除目标
   */
  deleteTargetInfo = (data: TargetInfoDeleteParam) => {
    return http.post('/v1/target/delete', data)
  }

}

const targetInfoApi = new TargetInfoApi();

export default targetInfoApi as TargetInfoApi;
/**
 * 用户整体目标完成进度统计
 */
export interface TargetInfoCountVo {
  /**
   * 总目标数量
   */
  totalQuantity: number
  /**
  * 完成目标的数量
  */
  completeQuantity: number
  /**
   * 更新时间
   */
  updateTime: string
}

/**
 * 新增目标
 */
export interface TargetInfoAddParam {
  /**
   * 目标内容
   */
  content: string

}

/**
 * 修改目标
 */
export interface TargetInfoEditParam {
  /**
   * 目标内容
   */
  content: string
  /**
   * 目标内容id
   */
  id: number

}

/**
 * 完成目标
 */
export interface TargetInfoCompleteParam {
  /**
   * 目标内容id
   */
  id: number

}

/**
 * 删除目标
 */
export interface TargetInfoDeleteParam {
  /**
   * 目标内容id
   */
  id: number

}


/**
 * 用户目标内容详情
 */
export interface TargetInfoVo extends BaseTime {
  /**
   * 目标内容id
   */
  id: number
  /**
   * 目标内容
   */
  content: string
  /**
   * 目标状态:0未完成 1完成
   */
  status: string
  /**
   * 创建时间字符串格式
   */
  time: string
}

/**
 * 时间
 */
export interface BaseTime {
  /**
   * 创建时间
   */
  createTime?: Date
  /**
   * 更新时间
   */
  updateTime?: Date
}

/**
 * 分页参数
 */
export interface PageParam {
  /**
   * 当前页
   */
  page?: number
  /**
   * 每一页展示的数据条数
   */
  pageSize?: number
}


/**
 * 分页响应参数
 */
export interface PageVo<T> {
  current: number,
  size: number,
  total: number,
  records: Array<T>
}

学习平台和面试平台

学习平台和面试平台跟首页差不多雷同,所以在这里就不说了

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2318688.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

黑马node.js教程(nodejs教程)——AJAX-Day01-04.案例_地区查询——查询某个省某个城市所有地区(代码示例)

文章目录 代码示例效果 代码示例 axiosTest.html <!DOCTYPE html> <!-- 文档类型声明&#xff0c;告诉浏览器这是一个HTML5文档 --> <html lang"en"> <!-- HTML根元素&#xff0c;设置文档语言为英语 --><head> <!-- 头部区域&am…

vue 自制列表,循环滚动

需求人员表示&#xff0c;超过高度的表格内容需要滚动展示&#xff0c;所以效果图如下&#xff1a; 自定义列表样式&#xff0c;主要是通过flex布局&#xff0c;控制 类th 与 类td 的宽度保持一致&#xff0c;标签结构还是参考了table的结构&#xff0c;由thead与tbody包裹tr再…

Windows主机、虚拟机Ubuntu、开发板,三者之间文件互传

以下内容源于日常学习的整理&#xff0c;欢迎交流。 下图是Windows主机、虚拟机Ubuntu、开发者三者之间文件互传的方式示意图&#xff1a; 注意&#xff0c;下面谈及的所有方式&#xff0c;都要求两者的IP地址处于同一网段&#xff0c;涉及到的软件资源见felm。 一、Windows主…

Windows Docker 报错: has no HTTPS proxy,换源

pull python 3.7报错&#xff1a; 尝试拉取Docker 测试库hello world也失败 尝试使用临时镜像源&#xff0c;可以成功拉取&#xff1a; sudo docker pull docker.m.daocloud.io/hello-world说明确实是网络问题&#xff0c;需要配置镜像源&#xff0c;为了方便&#xff0c;在d…

Java:Arrays类:操作数组的工具类

文章目录 Arrays类常见方法SetAll(); 代码排序如果数组中存储的是自定义对象 Arrays类 常见方法 SetAll(); 注意&#xff1a; 不能用新的数组接是因为修改的是原数组&#xff0c;所以完了要输出原数组发现会产生变化参数是数组下标变成灰色是因为还能简化&#xff08;Lambda…

只是“更轻更薄”?不!遨游三防平板还选择“更强更韧”

当消费电子领域普遍追求“更轻更薄”的设计美学时&#xff0c;遨游三防平板不止于此&#xff0c;还选择了另一条道路——“更强更韧”。在智能制造的复杂场景中&#xff0c;三防平板需直面高温、油污、撞击与极端气候的考验。普通消费级平板因防护性能不足&#xff0c;常因环境…

基于RAGFlow本地部署DeepSeek-R1大模型与知识库:从配置到应用的全流程解析

作者&#xff1a;后端小肥肠 &#x1f34a; 有疑问可私信或评论区联系我。 &#x1f951; 创作不易未经允许严禁转载。 姊妹篇&#xff1a; DeepSpeek服务器繁忙&#xff1f;这几种替代方案帮你流畅使用&#xff01;&#xff08;附本地部署教程&#xff09;-CSDN博客 10分钟上手…

[蓝桥杯 2023 省 B] 飞机降落(不会dfs的看过来)

[蓝桥杯 2023 省 B] 飞机降落 题目描述 N N N 架飞机准备降落到某个只有一条跑道的机场。其中第 i i i 架飞机在 T i T_{i} Ti​ 时刻到达机场上空&#xff0c;到达时它的剩余油料还可以继续盘旋 D i D_{i} Di​ 个单位时间&#xff0c;即它最早可以于 T i T_{i} Ti​ 时刻…

信创系统极速文件查找:locate 命令详解

原文链接&#xff1a;信创系统极速文件查找&#xff1a;locate 命令详解 Hello&#xff0c;大家好啊&#xff01;今天给大家带来一篇信创终端操作系统上 locate 命令详解的文章。在 Linux 及信创终端操作系统&#xff08;如 统信 UOS、麒麟 KOS&#xff09;中&#xff0c;查找…

C# | 超简单CSV表格读写操作(轻松将数据保存到CSV,并支持读取还原)

C# | 超简单CSV表格读写操作&#xff08;轻松将数据保存到CSV&#xff0c;并支持读取还原&#xff09; 文章目录 C# | 超简单CSV表格读写操作&#xff08;轻松将数据保存到CSV&#xff0c;并支持读取还原&#xff09;一、上位机开发中的CSV应用背景二、CSV读写实战教学1. 基本对…

PostgreSQL:语言基础与数据库操作

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家&#xff0c;历代文学网&#xff08;PC端可以访问&#xff1a;https://literature.sinhy.com/#/?__c1000&#xff0c;移动端可微信小程序搜索“历代文学”&#xff09;总架构师&#xff0c;15年工作经验&#xff0c;精通Java编…

蓝桥杯学习——二叉树+奇点杯题目解析

基础认知 一、二叉树种类&#xff1a; 1.满二叉树。记深度k&#xff0c;节点数量2^k-1。 2.完全二叉树&#xff1a;除了底层&#xff0c;其余全满&#xff0c;底部从左到右连续。 3&#xff0c;平衡二叉搜索树&#xff1a;左子树和右子树高度差不大于1。 二、存储方式&…

基于django+vue的购物商城系统

开发语言&#xff1a;Python框架&#xff1a;djangoPython版本&#xff1a;python3.8数据库&#xff1a;mysql 5.7数据库工具&#xff1a;Navicat11开发软件&#xff1a;PyCharm 系统展示 系统首页 热卖商品 优惠资讯 个人中心 后台登录 管理员功能界面 用户管理 商品分类管理…

AI安全、大模型安全研究(DeepSeek)

DeepSeek 点燃AI应用革命之火,但安全 “灰犀牛” 正在逼近 DeepSeek-R1国产大模型的发布,以技术创新惊艳了全球,更是极致的性价比推动国内千行百业接入 AI,政府、企业竞速开发智能业务处理、智能客服、代码生成、营销文案等应用,“落地效率” 成为第一关键词。然而与此相…

卷积神经网络 - 汇聚层

卷积神经网络一般由卷积层、汇聚层和全连接层构成&#xff0c;本文我们来学习汇聚层。 汇聚层(Pooling Layer)也叫子采样层(Subsampling Layer)&#xff0c;其作用是进 行特征选择&#xff0c;降低特征数量&#xff0c;从而减少参数数量。 卷积层虽然可以显著减少网络中连接的…

论文分享:PL-ALF框架实现无人机低纹理环境自主飞行

在室内仓库、地下隧道等低纹理复杂场景中&#xff0c;无人机依赖视觉传感器进行自主飞行时&#xff0c;往往会遇到定位精度低、路径规划不稳定等难题。针对这一问题&#xff0c;重庆邮电大学计算机学院雷大江教授团队在IEEE Trans期刊上提出了一种新型自主飞行框架&#xff1a;…

Nodejs使用redis

框架&#xff1a;koa&#xff0c;通过koa-generator创建 redis: 本地搭建&#xff0c;使用默认帐号&#xff0c;安装说明地址以及默认启动设置&#xff1a;https://redis.io/docs/latest/operate/oss_and_stack/install/install-redis/install-redis-on-linux/ 中间件&#x…

GitHub 超火的开源终端工具——Warp

Warp 作为近年来 GitHub 上备受瞩目的开源终端工具&#xff0c;以其智能化、高性能和协作能力重新定义了命令行操作体验。以下从多个维度深入解析其核心特性、技术架构、用户评价及生态影响力&#xff1a; 一、背景与核心团队 Warp 由前 GitHub CTO Jason Warner 和 Google 前…

计算机视觉技术探索:美颜SDK如何利用深度学习优化美颜、滤镜功能?

时下&#xff0c;计算机视觉深度学习正在重塑美颜技术&#xff0c;通过智能人脸检测、AI滤镜、深度美肤、实时优化等方式&#xff0c;让美颜效果更加自然、精准、个性化。 那么&#xff0c;美颜SDK如何结合深度学习来优化美颜和滤镜功能&#xff1f;本文将深入解析AI在美颜技术…

应用商店上新:Couchbase Enterprise Server集群

可移植的冗余数据平台&#xff0c;这往往是创建可扩展的云原生应用程序的先决条件。而不依赖特定平台的工具可用于为多云、多区域工作负载提供企业级应用所需的灵活性。 ​Couchbase是一种高性能NoSQL数据库&#xff0c;专为当今复杂的云生态系统所需的动态扩展能力而设计。最近…