低代码可视化-商品详情页面-代码生成器

简介: 低代码可视化-商品详情页面-代码生成器

小程序商品详情页面是用户在商城小程序中查看商品具体信息的重要页面。以下是低代码可视化-商品详情页面-代码生成器页面的详细介绍:

新建商品详情页面

点击新建页面,输入页面标识、标题

跳转商品详情页面

由于商品数据时动态,所以商品页面需要从列表点击跳转进去。回到首页商品宫格显示组件,设置点击跳转页面事件。


商品API数据获取

商品数据根据列表传过来的id值,动态查找商品数据。其中传过来的参数是系统会统一存在globalOption里,绑定参数时即可globalOption.id来获取上一页面传过来的参数。


商品轮播图设置

包括封面图片、顶部图片和详情图片。封面图片是商品详情页的第一张图片,直接决定了用户是否愿意进一步浏览商品信息。顶部图片用于展示商品的更多颜色、规格、角度或细节。这里采用轮播图片来实现。


商品标题、价格、划线价格绑定

根据大家需求,设计下商品标题、价格、划线价格等绑定。


多规格组件设计

商品支持单规格、多规格两种类型的产品,多规格由于其特殊性,不能直接加入购物车,需要用户确定选择哪个规格的。此时需要拖入一个SKU多规格组件。

加入购物车

加入购物车需要自定义点击事件,点击事件新增,增加自己添加购物车的功能。加入购物车前,我们增加了是否登录判断,如果没有登录,跳转至登录页。

判断登录后,核心就是把此产品的数据加入到购物车缓存。如果是单规格的我们直接把数据加入购物车


多规格值赋值

商品多规格动态来源于每个商品的多规格。


配置点击事件

立即购买

立即购买调用同个方法,但传actionType值不一样,一个是点击后立即跳走。


多规格回调

产品多规格加入购物车实现逻辑不一样,多规格除了商品id还有规格id。所以我们判断商品是否已加入购物车需求加入多规格id来判断。


保存源码至本地

至此整个商品事件配置完成,点击保存源码至本地查看效果

代码生成器

<template>
  <view class="container container329916">
    <view v-if="globalData.isshow" class="flex flex-wrap diygw-col-24 flex-direction-column">
      <view class="flex diygw-col-24">
        <swiper :current="swiperIndex" class="swiper swiper-indicator_rect_radius" @change="changeSwiper" indicator-color="rgba(51, 51, 51, 0.39)" indicator-active-color="#fff" indicator-dots="true" autoplay interval="3000" circular="true" style="height: 300rpx">
          <swiper-item v-for="(item, index) in data.data.imgs" :key="index" class="diygw-swiper-item">
            <view class="diygw-swiper-item-wrap">
              <image :src="item" class="diygw-swiper-image"></image>
            </view>
          </swiper-item>
        </swiper>
      </view>
      <view class="flex flex-wrap diygw-col-24 flex-direction-column justify-center items-center flex6-clz">
        <view class="flex flex-wrap diygw-col-24 items-baseline">
          <view class="flex flex-wrap diygw-col-0 items-baseline flex15-clz">
            <text class="diygw-col-0 text8-clz"> ¥ </text>
            <text class="diygw-col-0 text-clz">
              {{ data.data.price }}
            </text>
            <text class="diygw-text-line2 diygw-col-0 text9-clz">
              {{ data.data.linePrice }}
            </text>
          </view>
          <text class="diygw-text-line2 diygw-col-0"> 已售{{ data.data.sellamonut }}件 </text>
        </view>
        <view class="flex flex-wrap diygw-col-24 flex2-clz">
          <view class="flex flex-wrap diygw-col-0 flex-direction-column justify-center items-center flex3-clz">
            <text class="diygw-text-line2 diygw-col-24 text11-clz">
              {{ data.data.title }}
            </text>
          </view>
          <!-- #ifdef MP-WEIXIN -->
          <button class="flex diygw-btn-default flex-wrap diygw-col-0 flex-direction-column items-center flex4-clz" open-type="share">
            <text class="flex icon diygw-col-0 diy-icon-forward"></text>
            <text class="diygw-text-line2 diygw-col-0"> 分享 </text>
          </button>
          <!--  #endif -->
        </view>
      </view>
      <view v-if="data.data.skuType == 2" class="flex flex-wrap diygw-col-24 flex-direction-column justify-center items-center flex17-clz">
        <view class="flex flex-wrap diygw-col-24 items-center">
          <text class="diygw-text-line2 diygw-col-0"> 选择: </text>
          <view @click="uskuData.show = true" class="diygw-col-0 usku-clz">
            {{ data.data.skusText }}
          </view>
          <diy-sku :stockTotal="uskuData.stockTotal" v-model="uskuData.show" @buyNow="buyNowUsku" @addCart="addCartUsku" :price="uskuData.price" :thumb="uskuData.thumb" :isBuyNow="uskuData.isBuyNow" :isMulti="uskuData.isMulti" addCartBackground="#fbbd08" :isAddCart="uskuData.isAddCart" :specList="uskuData.specs" :skuList="uskuData.skus" v-slot:sku="{ specMap, disable, active, row }">
            <diy-sku-item :row="row" :specMap="specMap" :disable="disable" :active="active"></diy-sku-item>
          </diy-sku>
          <text @click="uskuData.show = true" class="flex icon5 diygw-col-0 diy-icon-right"></text>
        </view>
      </view>
      <view class="flex flex-wrap diygw-col-24 flex-direction-column justify-center items-center flex12-clz">
        <view class="flex flex-wrap diygw-col-24 justify-between items-center">
          <view class="flex flex-wrap diygw-col-0 items-center">
            <text @click="uskuData.show = true" class="flex icon8 diygw-col-0 icon8-clz diy-icon-roundcheck"></text>
            <text class="diygw-text-line2 diygw-col-0"> 七天无理由退货 </text>
          </view>
          <view class="flex flex-wrap diygw-col-0 items-center flex14-clz">
            <text @click="uskuData.show = true" class="flex icon7 diygw-col-0 icon7-clz diy-icon-roundcheck"></text>
            <text class="diygw-text-line2 diygw-col-0"> 48小时内发货 </text>
          </view>
          <text @click="uskuData.show = true" class="flex icon4 diygw-col-0 diy-icon-right"></text>
        </view>
      </view>
      <view class="flex flex-wrap diygw-col-24 flex-direction-column justify-center items-center flex5-clz">
        <text class="diygw-text-line2 diygw-col-24 text6-clz"> 商品描述 </text>
        <mp-html :content="data.data.content" class="diygw-col-24"></mp-html>
      </view>
    </view>
    <view v-if="globalData.isshow" class="flex flex-wrap diygw-col-24 justify-start items-center diygw-bottom flex8-clz">
      <button class="flex diygw-btn-default flex-wrap diygw-col-0 flex-direction-column items-center flex10-clz" @tap="navigateTo" data-type="page" data-url="/pages/index" data-redirect="1">
        <text class="flex icon2 diygw-col-0 diy-icon-home"></text>
        <text class="diygw-text-line2 diygw-col-0"> 首页 </text>
      </button>
      <button class="flex diygw-btn-default flex-wrap diygw-col-0 flex-direction-column items-center flex11-clz" @tap="navigateTo" data-type="page" data-url="/pages/cart">
        <text class="flex icon3 diygw-col-0 diy-icon-cart"></text>
        <text class="diygw-text-line2 diygw-col-0"> 购物车 </text>
      </button>
      <view class="flex flex-wrap diygw-col-0 justify-center items-center flex20-clz" @tap="navigateTo" data-type="addCartFunction" data-action-type="1">
        <text class="diygw-col-0"> 加入购物车 </text>
      </view>
      <view class="flex flex-wrap diygw-col-0 justify-center items-center flex9-clz" @tap="navigateTo" data-type="addCartFunction" data-action-type="2">
        <text class="diygw-col-0"> 立即购买 </text>
      </view>
    </view>
    <view class="clearfix"></view>
  </view>
</template>
 
<script>
  export default {
    data() {
      return {
        //用户全局信息
        userInfo: {},
        //页面传参
        globalOption: {},
        //自定义全局变量
        globalData: { isshow: false },
        dataNum: 1,
        data: {
          code: 200,
          msg: 'success',
          data: {
            id: 1,
            title: '商品名称',
            remark: '商品描述',
            img: 'http://f.com/storage/image/20241002/fc98f12cfcf1022dd5f0bdb6e4838db856f10e8d.png',
            imgs: '["http:\\/\\/cdn.diygw.com\\/image\\/20240903\\/a3a8c84965da49874f4443788f586797581d9605.png"]',
            status: '1',
            content: '<p>23123</p>',
            price: '3.00',
            amount: 5,
            sellamonut: null,
            skus: '{"skus":[],"specs":[]}',
            sortnum: null,
            cateId: 2,
            userId: 1,
            createTime: '2024-10-01 18:05:41',
            updateTime: '2024-10-01 20:02:56',
            deleteTime: null,
            linePrice: '3.00',
            skuType: '1'
          }
        },
        swiperIndex: 0,
        uskuData: {
          isMulti: true,
          skus: [],
          specs: [],
          show: false,
          isBuyNow: true,
          isAddCart: true,
          stockTotal: 0,
          price: 1,
          thumb: ''
        },
        usku: {}
      };
    },
    onShow() {
      this.setCurrentPage(this);
    },
    onLoad(option) {
      this.setCurrentPage(this);
      if (option) {
        this.setData({
          globalOption: this.getOption(option)
        });
      }
 
      this.init();
    },
    methods: {
      async init() {
        this.dataApi();
      },
      // 文章数据 API请求方法
      async dataApi(param) {
        let thiz = this;
        param = param || {};
 
        //请求地址及请求数据,可以在加载前执行上面增加自己的代码逻辑
        let http_url = '/shop/api.goods/get';
        let http_data = {
          pageNum: this.dataNum,
          pageSize: 10,
          id: param.id || this.globalOption.id || '1'
        };
        let http_header = {};
 
        let data = await this.$http.post(http_url, http_data, http_header, 'json');
 
        if (!data.data) {
          this.showToast('详情不存在');
          uni.navigateBack();
          return;
        }
        data.data.imgs = data.data.imgs ? JSON.parse(data.data.imgs) : [data.data.img];
        data.data.skus = data.data.skus ? JSON.parse(data.data.skus) : [];
        //如果是多规格内容
        if (data.data.skuType == 2) {
          data.data.skusText = data.data.skus.specs
            .map((item) => {
              return item.title;
            })
            .join(' ');
        } else {
          data.data.skusText = '';
        }
 
        this.data = data;
        this.globalData.isshow = true;
        uni.setNavigationBarTitle({
          title: data.data.title
        });
      },
 
      // 加入购物车或购买 自定义方法
      async addCartFunction(param) {
        let thiz = this;
        let actionType = param && (param.actionType || param.actionType == 0) ? param.actionType : '1';
        if (!this.$session.getToken()) {
          //比如未登录,转身到其他页面等
          this.showToast('请先登录');
          this.navigateTo({
            type: 'page',
            url: 'login'
          });
          return;
        }
        if (this.data.data.skuType == 1) {
          let carts = this.$session.getUserValue('carts');
          if (!carts) {
            carts = [];
          }
          //查找购物车里是否已存在该数据,如果存在则不加入
          let index = carts.findIndex((item) => {
            return item.id == this.data.data.id;
          });
          if (index >= 0) {
            carts.splice(index, 1);
          }
          let data = JSON.parse(JSON.stringify(this.data.data));
          data.number = 1;
          carts.push(data);
          this.$session.setUserValue('carts', carts);
          if (actionType == 1) {
            this.showToast('加入购物车成功');
          } else {
            this.navigateTo({
              type: 'page',
              url: 'cart'
            });
          }
        } else {
          //把当前数据的多规格给到多规格组件里。
          this.uskuData.skus = this.data.data.skus.skus;
          this.uskuData.specs = this.data.data.skus.specs;
          this.uskuData.show = true;
        }
      },
 
      // 多规格回调 自定义方法
      async addCartBySkuFunction(param) {
        let thiz = this;
        let actionType = param && (param.actionType || param.actionType == 0) ? param.actionType : '1';
        if (!this.$session.getToken()) {
          //比如未登录,转身到其他页面等
          this.showToast('请先登录');
          this.navigateTo({
            type: 'page',
            url: 'login'
          });
          return;
        }
        let carts = this.$session.getUserValue('carts');
        if (!carts) {
          carts = [];
        }
        //查找购物车里是否已存在该数据,如果存在则不加入
        let index = carts.findIndex((item) => {
          return item.id == this.data.data.id && item.specIds == this.usku.specIds;
        });
        if (index >= 0) {
          carts.splice(index, 1);
        }
        let data = JSON.parse(JSON.stringify(this.data.data));
        data = Object.assign(data, this.usku);
        if (this.usku.keywords) {
          data.title = this.data.data.title + ' ' + this.usku.keywords;
        }
 
        data.number = this.usku.buyNum;
        carts.push(data);
        this.$session.setUserValue('carts', carts);
        if (actionType == 1) {
          this.showToast('加入购物车成功');
        } else {
          this.navigateTo({
            type: 'page',
            url: 'cart'
          });
        }
      },
      changeSwiper(evt) {
        let swiperIndex = evt.detail.current;
        this.setData({ swiperIndex });
      },
      addCartUsku(evt) {
        this.usku = evt;
        this.navigateTo({ actionType: 1, type: 'addCartBySkuFunction' });
      },
      buyNowUsku(evt) {
        this.usku = evt;
        this.navigateTo({ actionType: 2, type: 'addCartBySkuFunction' });
      }
    }
  };
</script>
 
<style lang="scss" scoped>
  .swiper-title {
    background-color: rgba(0, 0, 0, 0.281);
  }
  .flex6-clz {
    background-color: #ffffff;
    margin-left: 0rpx;
    padding-top: 20rpx;
    padding-left: 20rpx;
    width: calc(100% - 0rpx - 0rpx) !important;
    padding-bottom: 20rpx;
    margin-top: 0rpx;
    margin-bottom: 10rpx;
    margin-right: 0rpx;
    padding-right: 20rpx;
  }
  .flex15-clz {
    flex: 1;
  }
  .text8-clz {
    color: #f20000;
    font-weight: bold;
    font-size: 28rpx !important;
  }
  .text-clz {
    color: #f20000;
    font-weight: bold;
    font-size: 32rpx !important;
  }
  .text9-clz {
    text-decoration: line-through;
  }
  .flex2-clz {
    padding-top: 16rpx;
    padding-left: 0rpx;
    padding-bottom: 0rpx;
    padding-right: 0rpx;
  }
  .flex3-clz {
    flex: 1;
  }
  .text11-clz {
    font-size: 28rpx !important;
  }
  .flex4-clz {
    background-color: #ffffff;
    padding-top: 0rpx;
    border-left: 2rpx solid #ededed;
    padding-left: 16rpx;
    padding-bottom: 0rpx;
    padding-right: 0rpx;
  }
  .icon {
    font-size: 40rpx;
  }
  .flex17-clz {
    background-color: #ffffff;
    margin-left: 0rpx;
    padding-top: 20rpx;
    color: #888;
    padding-left: 20rpx;
    width: calc(100% - 0rpx - 0rpx) !important;
    font-size: 28rpx !important;
    padding-bottom: 20rpx;
    margin-top: 0rpx;
    margin-bottom: 10rpx;
    margin-right: 0rpx;
    padding-right: 20rpx;
  }
  .usku-clz {
    flex: 1;
  }
  .icon5 {
    font-size: 32rpx;
  }
  .flex12-clz {
    margin-left: 0rpx;
    padding-top: 20rpx;
    padding-left: 20rpx;
    width: calc(100% - 0rpx - 0rpx) !important;
    font-size: 28rpx !important;
    padding-bottom: 20rpx;
    margin-top: 0rpx;
    margin-bottom: 10rpx;
    margin-right: 0rpx;
    padding-right: 20rpx;
  }
  .icon8-clz {
    color: #f20000;
  }
  .icon8 {
    font-size: 36rpx;
  }
  .flex14-clz {
    padding-top: 0rpx;
    flex: 1;
    padding-left: 10rpx;
    padding-bottom: 0rpx;
    padding-right: 0rpx;
  }
  .icon7-clz {
    color: #f20000;
  }
  .icon7 {
    font-size: 36rpx;
  }
  .icon4 {
    font-size: 32rpx;
  }
  .flex5-clz {
    background-color: #ffffff;
    margin-left: 0rpx;
    padding-top: 20rpx;
    padding-left: 20rpx;
    width: calc(100% - 0rpx - 0rpx) !important;
    font-size: 28rpx !important;
    padding-bottom: 20rpx;
    margin-top: 0rpx;
    margin-bottom: 10rpx;
    margin-right: 0rpx;
    padding-right: 20rpx;
  }
  .text6-clz {
    margin-left: 0rpx;
    width: calc(100% - 0rpx - 0rpx) !important;
    font-size: 28rpx !important;
    margin-top: 0rpx;
    margin-bottom: 10rpx;
    margin-right: 0rpx;
  }
  .flex8-clz {
    padding-top: 16rpx;
    border-bottom-left-radius: 0rpx;
    color: #747474;
    bottom: 0rpx;
    padding-left: 16rpx;
    padding-bottom: 16rpx;
    border-top-right-radius: 20rpx;
    background-color: #ffffff;
    box-shadow: 0rpx 2rpx 6rpx rgba(31, 31, 31, 0.16);
    overflow: hidden;
    left: 0rpx;
    border-top-left-radius: 20rpx;
    border-bottom-right-radius: 0rpx;
    padding-right: 16rpx;
  }
  .flex10-clz {
    background-color: #ffffff;
    padding-top: 0rpx;
    padding-left: 16rpx;
    padding-bottom: 0rpx;
    padding-right: 16rpx;
  }
  .icon2 {
    font-size: 40rpx;
  }
  .flex11-clz {
    background-color: #ffffff;
    padding-top: 0rpx;
    padding-left: 16rpx;
    padding-bottom: 0rpx;
    padding-right: 16rpx;
  }
  .icon3 {
    font-size: 40rpx;
  }
  .flex20-clz {
    padding-top: 16rpx;
    border-bottom-left-radius: 200rpx;
    color: #ffffff;
    font-weight: bold;
    padding-left: 10rpx;
    font-size: 28rpx !important;
    padding-bottom: 16rpx;
    border-top-right-radius: 200rpx;
    margin-right: 10rpx;
    margin-left: 10rpx;
    overflow: hidden;
    flex: 1;
    border-top-left-radius: 200rpx;
    margin-top: 0rpx;
    border-bottom-right-radius: 200rpx;
    background-image: linear-gradient(to right, #ffb100, #ffb900);
    margin-bottom: 0rpx;
    padding-right: 10rpx;
  }
  .flex9-clz {
    padding-top: 16rpx;
    border-bottom-left-radius: 200rpx;
    color: #ffffff;
    font-weight: bold;
    padding-left: 10rpx;
    font-size: 28rpx !important;
    padding-bottom: 16rpx;
    border-top-right-radius: 200rpx;
    margin-right: 10rpx;
    margin-left: 10rpx;
    overflow: hidden;
    flex: 1;
    border-top-left-radius: 200rpx;
    margin-top: 0rpx;
    border-bottom-right-radius: 200rpx;
    background-image: linear-gradient(to right, #fa2209, #ff6335);
    margin-bottom: 0rpx;
    padding-right: 10rpx;
  }
  .container329916 {
    background-color: #f5f5f5;
  }
</style>

扩展阅读

一、页面入口

用户可以通过多种方式进入商品详情页面,包括:


首页推荐或分类浏览:用户在商城小程序的首页,可以通过浏览推荐的商品或者点击特定的商品分类,然后在列表中选择感兴趣的商品,点击商品图片或标题即可进入。


搜索功能:如果用户知道想要购买的商品名称或关键词,可以使用商城小程序的搜索功能,在搜索框中输入关键词后,系统会展示相关的商品列表,用户点击列表中的商品即可进入。


购物车或订单页面:如果用户已经将商品加入购物车或之前购买过该商品,可以在购物车页面或订单页面中查看该商品的详情,通过点击商品信息或链接也能进入。


商品分享链接:如果其他用户分享了某个商品的链接,用户点击这个链接后,也会直接跳转到该商品的详情页。

二、页面内容

商品详情页面通常包含以下关键信息:


商品图片:包括封面图片、顶部图片和详情图片。封面图片是商品详情页的第一张图片,直接决定了用户是否愿意进一步浏览商品信息。顶部图片用于展示商品的更多颜色、规格、角度或细节。详情图片则用于展示商品的详细信息、规格参数等。这些图片都应具有高清晰度,且内容应聚焦于商品本身,避免无关元素的干扰。


商品名称与价格:商品详情页面会明确标注商品的名称和价格,这是用户最为关注的信息之一。价格通常会以醒目的方式展示,以便用户快速了解。

库存与销量:页面会显示商品的库存情况和销量数据,这些信息有助于用户判断商品的受欢迎程度和购买紧迫性。


商品描述:商品描述部分会详细介绍商品的特点、功能、材质、尺寸等详细信息,以便用户全面了解商品。这部分内容通常会以文字、图片或视频的形式呈现。

用户评价:页面会展示其他用户对商品的评价和评分,这些信息对于潜在用户的购买决策具有重要影响。


购买操作:商品详情页面还会提供购买操作的相关按钮,如加入购物车、立即购买等,方便用户进行购买操作。

三、页面设计

在设计商品详情页面时,需要考虑以下因素:


页面布局:页面布局应清晰、合理,确保用户能够快速找到所需信息。同时,需要注重页面的美观性和用户体验。


图片质量:商品图片的质量直接影响到用户的购买决策。因此,需要确保图片具有高清晰度,且内容真实、准确。


文字描述:商品描述应简洁明了、突出重点,避免冗长和复杂的文字表述。同时,需要注重语言的准确性和专业性。


交互设计:页面需要提供便捷的交互设计,如滑动浏览、点击放大图片、添加购物车等操作,以提高用户的购买体验和满意度。


综上所述,小程序商品详情页面是用户在商城小程序中查看商品具体信息的重要页面。通过优化页面

入口、丰富页面内容、注重页面设计等方面的努力,可以提升用户的购买体验和满意度,进而促进商品的销售和转化。


目录
相关文章
|
SQL 小程序 前端开发
【易售小程序项目】商品详情展示+评论、评论展示、评论点赞+商品收藏【后端基于若依管理系统开发】
【易售小程序项目】商品详情展示+评论、评论展示、评论点赞+商品收藏【后端基于若依管理系统开发】
116 0
【最佳实践】宜搭的报表分析功能
“单据表单”和”流程表单”中提交的数据,可以在”报表页面”中作为数据源,进行进一步的分析。当一个表单中存在明细时,为了支持分析,宜搭进行了一些额外的处理。下面以一个具体场景(进货单)进行具体介绍
【最佳实践】宜搭的报表分析功能
【最佳实践】如何用宜搭做商品进销存
宜搭支持通过直接配置实现进销存场景。支持的常用进销存场景有: 图书管理系统、会议室预定系统、积分管理系统等。现在,就以商品进销存为例,示意操作过程。
【最佳实践】如何用宜搭做商品进销存
|
1天前
|
数据采集 存储 Web App开发
Java爬虫:深入解析商品详情的利器
在数字化时代,信息处理能力成为企业竞争的关键。本文探讨如何利用Java编写高效、准确的商品详情爬虫,涵盖爬虫技术概述、Java爬虫优势、开发步骤、法律法规遵守及数据处理分析等内容,助力电商领域市场趋势把握与决策支持。
|
1月前
|
数据可视化 API
低代码可视化-uniapp购物车页面-代码生成器
低代码可视化-uniapp购物车页面-代码生成器
33 1
|
1月前
|
数据可视化 大数据 API
低代码可视化开发-uniapp新闻跑马灯组件-代码生成器
低代码可视化开发-uniapp新闻跑马灯组件-代码生成器
92 2
|
28天前
|
移动开发 编解码 数据可视化
低代码可视化-uniapp SliderRange区间组件-代码生成器
SliderRange区间组件是一种用户界面元素,允许用户通过拖动滑块选择数值范围。组件支持微信小程序、H5和App,具有高度可定制性、响应式设计和多种事件处理功能。适用于价格筛选、音量调节等场景。代码实现包括滑动区域、滑块、事件处理等部分,支持可视化配置步长、颜色等属性。使用时需注意选择合适步长、提供清晰标签和考虑无障碍设计。
37 0
|
1月前
|
供应链 数据可视化 JavaScript
低代码可视化-商城管理系统-商品管理-代码生成器
低代码可视化-商城管理系统-商品管理-代码生成器
23 0
|
1月前
|
小程序 数据可视化 API
低代码可视化-uniapp商城首页小程序-代码生成器
低代码可视化-uniapp商城首页小程序-代码生成器
30 0
|
1月前
|
移动开发 数据可视化 小程序
低代码可视化-UniApp二维码可视化-代码生成器
低代码可视化-UniApp二维码可视化-代码生成器
37 0
下一篇
无影云桌面