Java阶段五Day16

news2024/9/30 23:34:58

Java阶段五Day16

文章目录

  • Java阶段五Day16
    • 问题解析
      • 启动servlet冲突问题
      • nacos注册中心
      • 用户信息验证失败
      • 前端效果不对
      • 前端请求到后台服务的流转过程
    • 远程dubbo调用
      • 业务需求
      • dubbo配置
      • xml配置
      • domain层代码 补充远程调用
    • 师傅详情
      • 接口抽象
      • 开发
        • WorkderServerController
        • WorkerServerService
        • WorkerRepository
        • WorkerDao
        • WorkerMapper.xml
      • 问题
      • 展示师傅信息
    • 准备好后续开发的环境
      • worker-admin删除保留开发框架
      • 日志框架

问题解析

启动servlet冲突问题

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-24R4r4OO-1691147415831)(E:/TeduWork/notes-2303/%25E8%25AF%25BE%25E5%25A0%2582%25E7%25AC%2594%25E8%25AE%25B0/Day15/assets/image-20230727174543269.png)]

解决方法:启动项目main 将传递过来servlet-api依赖去除

nacos注册中心

  • 依赖
  • yaml配置

用户信息验证失败

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pFT83xux-1691147415832)(E:/TeduWork/notes-2303/%25E8%25AF%25BE%25E5%25A0%2582%25E7%25AC%2594%25E8%25AE%25B0/Day15/assets/image-20230727145931514.png)]

断点查看源代码 LoginUserFilter(在处理网关解析后的jwt数据 userJson字符串)

如果过滤器不生效,就会导致解析userJson没执行,后端代码获取LongUser对象是空

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EmNRNN8J-1691147415833)(E:/TeduWork/notes-2303/%25E8%25AF%25BE%25E5%25A0%2582%25E7%25AC%2594%25E8%25AE%25B0/Day16/assets/image-20230728091248153.png)]

LongUserFilterAutoConfiguration 需要满足条件才会帮助项目程序创建过滤器

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JkJPh035-1691147415833)(E:/TeduWork/notes-2303/%25E8%25AF%25BE%25E5%25A0%2582%25E7%25AC%2594%25E8%25AE%25B0/Day16/assets/image-20230728091404276.png)]

所以根据源码分析,第一个条件没满足,导致当前LoginUserFilter没有自动配置.,无法生效

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Gd9Fc7Y7-1691147415834)(E:/TeduWork/notes-2303/%25E8%25AF%25BE%25E5%25A0%2582%25E7%25AC%2594%25E8%25AE%25B0/Day16/assets/image-20230728091638017.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5HD7wxcu-1691147415835)(E:/TeduWork/notes-2303/%25E8%25AF%25BE%25E5%25A0%2582%25E7%25AC%2594%25E8%25AE%25B0/Day16/assets/image-20230728091713931.png)]

passport-sdk包中提供了一个FastJsonAutoConfiguration

FastJson实现的自动配置

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eVDuh9QP-1691147415835)(E:/TeduWork/notes-2303/%25E8%25AF%25BE%25E5%25A0%2582%25E7%25AC%2594%25E8%25AE%25B0/Day16/assets/image-20230728092205409.png)]

  1. 要解析用户userJson,要经过过滤器LoginUserFilter
  2. 过滤器生效(bean对象),自动配置类条件要满足(容器具备一个Json实现bean对象)
  3. 所以要求FastJsonAutoConfiguration要满足条件,json.provider=fastjson
  4. 当前系统不满足这个条件

根据上述分析,在yaml文件中

提供属性

json:
	provider: fastjson

前端效果不对

当前worker-server端:师傅入驻

  • nacos
  • passport
  • attach
  • gateway
  • worker-server

正常执行了入驻功能,但是前端没有反馈成功,因为响应没有做处理,直接返回的是controller的方法返回值,需要返回Result的对象

{
    "code":200,
    "message":"成功"
    "data":{},
	"success":true
}

源代码中每个 main 模块中有非常多配置类

  1. 第一个是全局异常捕获
  2. 接口文档插件配置
  3. 配置springmvc cors(当前没有) 防止 knife4j 接口文件响应异常
  4. WebResponseHander 将响应做统一处理输出

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-x65ExouP-1691147415836)(E:/TeduWork/notes-2303/%25E8%25AF%25BE%25E5%25A0%2582%25E7%25AC%2594%25E8%25AE%25B0/Day16/assets/image-20230728094521894.png)]

这个方法执行位置在controller返回数据之后,响应返回前端之前

controller返回值如果不满足要求,就会统一封装成Result对象

body就是controller返回数据

前端请求到后台服务的流转过程

  • http://localhost:8989/api/worker/create 发给前端代理(vue.config.js
  • http://localhost:8097/worker/create 进入网关
  • lb://luban-worker-server/worker/create 找到路由断言匹配,负载均衡服务
  • http://localhost:9001/worker/create 进入controller逻辑

远程dubbo调用

业务需求

当前worker入驻,要调用attach-server服务,实现图片数据更新

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bNKXEy7e-1691147415836)(E:/TeduWork/notes-2303/%25E8%25AF%25BE%25E5%25A0%2582%25E7%25AC%2594%25E8%25AE%25B0/Day16/assets/image-20230728103127991.png)]

缺少的功能是师傅入驻,远程调用attach将图片数据库数据 businessType=77(worker业务) businessId=(生成的师傅id)

dubbo配置

  • 依赖
  • yaml(自动配置中属性,目的就是给配置类用的)
  • 注解

这种自动配置的使用方式,不符合分层开发目的,避免业务侵入性

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1R8eB6aR-1691147415837)(E:/TeduWork/notes-2303/%25E8%25AF%25BE%25E5%25A0%2582%25E7%25AC%2594%25E8%25AE%25B0/Day16/assets/image-20230728103519634.png)]

xml配置

  • 依赖 dubbo
<dependency>
    <groupId>org.apache.dubbo</groupId>
    <artifactId>dubbo</artifactId>
    <version>2.7.8</version>
</dependency>
  • xml配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://dubbo.apache.org/schema/dubbo
    http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
    <!--配置dubbo 原来在yaml自动配属性中看到 xml中也有-->
    <!--dubbo应用-->
    <dubbo:application name="${spring.application.name}">
        <!--关闭qos-->
        <dubbo:parameter key="qos.enable" value="false"/>
    </dubbo:application>
    <!--protocol dubbo -1-->
    <dubbo:protocol name="dubbo" port="-1"/>
    <!--注册中心-->
    <dubbo:registry
            id="dubboNacos"
            protocol="nacos"
            address="localhost:8848"
            use-as-config-center="false"
            use-as-metadata-center="false"/>
    <!--消费者配置接口-->
    <dubbo:reference id="attachApi" interface="com.tarena.tp.attach.server.client.AttachApi"
                 check="fasle" registry="dubboNacos"/>   
</beans>
  • 依赖provider接口 添加到调用模块domain
<!--远程调用attach-->
<dependency>
    <groupId>com.tarena.tp.attach</groupId>
    <version>1.0.0-SNAPSHOT</version>
    <artifactId>luban-attach-server-client-api</artifactId>
</dependency>
  • 导入到当前启动worker-server进程中@ImportResource

domain层代码 补充远程调用

saveWorker方法中远程调用

import com.tarena.luban.worker.server.repository.WorkerAreaRepository;
import com.tarena.luban.worker.server.repository.WorkerCategoryRepsoitory;
import com.tarena.luban.worker.server.repository.WorkerRepository;
import com.tarena.passport.protocol.LoginUser;
import com.tarena.passport.sdk.context.SecurityContext;
import com.tarena.tp.attach.server.client.AttachApi;
import com.tarena.tp.attach.server.param.AttachUpdateParam;
import com.tarena.tp.luban.worker.server.common.enums.ResultEnum;
import com.tarena.tp.luban.worker.server.dto.param.IdCardParam;
import com.tarena.tp.luban.worker.server.dto.param.WorkerAreaParam;
import com.tarena.tp.luban.worker.server.dto.param.WorkerCategoryParam;
import com.tarena.tp.luban.worker.server.dto.param.WorkerCreateParam;
import com.tedu.inn.commons.utils.Asserts;
import com.tedu.inn.protocol.exception.BusinessException;
import lombok.extern.slf4j.Slf4j;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * @author java@tedu.cn
 * @version 1.0
 */
@Service
@Slf4j
public class WorkerServerService {
    @Autowired
    private WorkerRepository workerRepository;
    @Autowired
    private WorkerAreaRepository workerAreaRepository;
    @Autowired
    private WorkerCategoryRepsoitory workerCategoryRepsoitory;
    //domain不关心实现,没有实现,报错
    @Autowired
    private AttachApi attachApi;
    /**
     * 1. 补充userId
     * 2. 检查 手机号
     * 3. 检查 身份证 和真实名称是否匹配 TODO
     * 4. 存储 worker workerCategory workerArea
     * 使用定义好的repository接口
     * @param workerCreateParam
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public Long create(WorkerCreateParam workerCreateParam) throws BusinessException {
        //获取userId
        Long userId=getUserIdByToken();
        //检查 手机号 身份证 UNDO
        checkPhoneAndIdCard(workerCreateParam);
        //挨个存储对应数据到持久层
        workerCreateParam.setUserId(userId);
        Long id=saveWorker(workerCreateParam);
        saveWorkerArea(workerCreateParam);
        saveWorkerCategory(workerCreateParam);
        return id;
    }

    /**
     * 先删除,后新增
     * @param workerCreateParam
     */
    private void saveWorkerCategory(WorkerCreateParam workerCreateParam) {
        workerCategoryRepsoitory.deleteByUserId(workerCreateParam.getUserId());
        List<WorkerCategoryParam> workerCategoryParams = workerCreateParam.getWorkerCategoryParams();
        if (!CollectionUtils.isEmpty(workerCreateParam.getWorkerCategoryParams())){
            //循环
            workerCategoryParams.forEach(param -> {
                param.setUserId(workerCreateParam.getUserId());
                workerCategoryRepsoitory.save(param);
            });
        }
    }

    /**
     * 先删除,后新增
     * @param workerCreateParam
     */
    private void saveWorkerArea(WorkerCreateParam workerCreateParam) {
        workerAreaRepository.deleteByUserId(workerCreateParam.getUserId());
        //循环存储 <foreach>
        //TODO 批量存
        List<WorkerAreaParam> workerAreaParams
                = workerCreateParam.getWorkerAreaParams();
        for (WorkerAreaParam workerAreaParam : workerAreaParams) {
            //提交的参数 workerCategoryParam中和workerParam类似的,也没有userId;
            workerAreaParam.setUserId(workerCreateParam.getUserId());
            //insert into worker_area
            workerAreaRepository.save(workerAreaParam);
        }
    }

    /**
     * 1. 当前用户有可能已经是师傅了.
     * 1.1 先查讯数据库是否有当前用户.师傅信息 有就报错 没有 就新增
     * 1.2 不管有没有 如果有就删除.重新新增
     * @param workerCreateParam
     * @return
     */
    private Long saveWorker(WorkerCreateParam workerCreateParam) throws BusinessException {
        //如果当前用户在数据库中有师傅信息,就删除 重新入驻师傅信息
        workerRepository.delete(workerCreateParam.getUserId());
        Long id=workerRepository.save(workerCreateParam);
        //rpc 调用 将身份信息,worker-id,和当前图片传递给attach系统,做更新
        //远程调用
        try{
            //远程调用,更新已经上传的图片,绑定到当前worker
            createAttach(id,workerCreateParam.getAttachList());
        }catch (Exception e){
            //远程调用失败
            throw new BusinessException(ResultEnum.ATTACH_FAILED);
        }
        return id;
    }
    //人为定义的类型.
    private static final Integer bizType=100;
    private void createAttach(Long businessId, List<IdCardParam> attachList) {
        //要将attachList 图片(attach服务 没有绑定业务)
        //封装远程调用参数 attach执行一个简单update attach set bysiness_id=#{参数} business_id=#{师傅id}
        //where id=#{当前图片id}
        List<AttachUpdateParam> attachUpdateParams=new ArrayList<>();
        //封装
        for (IdCardParam idCardParam : attachList) {
            //参数元素
            AttachUpdateParam attachUpdateParam=new AttachUpdateParam();
            attachUpdateParam.setIsCover(idCardParam.getType());
            // 图片id bizId bizType 主要数据
            attachUpdateParam.setId(idCardParam.getId());
            attachUpdateParam.setBusinessType(bizType);
            attachUpdateParam.setBusinessId(businessId.intValue());
            //添加到list
            attachUpdateParams.add(attachUpdateParam);
        }
        //调用远程
        attachApi.batchUpdateAttachByIdList(attachUpdateParams);
    }

    private void checkPhoneAndIdCard(WorkerCreateParam workerCreateParam) {
        //UNDO
        log.info("check phone and idCard,now passed");
    }

    private Long getUserIdByToken() throws BusinessException {
        LoginUser loginToken = SecurityContext.getLoginToken();
        //判断 user登录还是没登录 如果loginUser是空的,说明没登录
        Asserts.isTrue(loginToken==null,
                new BusinessException(ResultEnum.USER_TOKEN_VERIFY_FAILED));
        return loginToken.getUserId();
    }
}

师傅详情

接口抽象

要素备注
请求地址/worker/detail
请求方式GET
请求参数解析userId
返回值WorkerVO

返回值说明WorderVO

AccountVO: 远程调用account服务 查询已经审核通过的师傅绑定的账号

List<WorkerAreaVO>: 师傅绑定区域.

List<WokrderCategoryVO>: 师傅绑定的服务种类.

List<AttachVO>: 师傅绑定的身份证图片

开发

WorkderServerController

WorkerServerService

WorkerRepository

WorkerDao

WorkerMapper.xml

问题

完成所有查询,封装好数据,到页面检测功能

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Jz9bAOe8-1691147415838)(E:/TeduWork/notes-2303/%25E8%25AF%25BE%25E5%25A0%2582%25E7%25AC%2594%25E8%25AE%25B0/Day16/assets/image-20230728155555011-16905309563751.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dOoh0WgM-1691147415838)(E:/TeduWork/notes-2303/%25E8%25AF%25BE%25E5%25A0%2582%25E7%25AC%2594%25E8%25AE%25B0/Day16/assets/image-20230728155706992.png)]

思路: 通过检查对应代码位置,发现AccountBO暂时没有查询,会导致转化异常,所以在业务层返回添加一个假数据

展示师傅信息

当前已经注册成为师傅,但是前端没有消除成为师傅的按钮

审核数据 0 1 2(未注册) 3(已注册未审核)

准备好后续开发的环境

worker-admin删除保留开发框架

删除代码原则:

不删 / 保留

  • 数据封装对象: BO VO DTO PO PAGEQUERY

  • 转化的类:**Converter \*\*Asemble

  • 接口一律不删:

  • XML不删: 明白sql语句 增删拆改,条件作用

日志框架

当前luban-project使用日志框架

error debug info分到不同文件了

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XQYfO6pv-1691147415838)(assets/image-20230728175103253.png)]

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

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

相关文章

一百四十二、Linux——查看Linux服务器架构的版本类型

一、目的 查看已经安装好的Linux服务器架构的版本类型&#xff0c;看服务器版本是32位还是64位 而且可以区分出是kettle的文件x86或x86_64&#xff0c;x86是32位&#xff0c;而x86_64是64位 注意&#xff1a; 32位的查询结果为i386、i686 64位的查询结果为x86_64 二、Linu…

idea配置docker部署

安装docker插件 setting -> plugins 配置docker远程连接 参考&#xff1a;docker配置远程连接端口 https://blog.csdn.net/jinying_51eqhappy/article/details/132103423?csdn_share_tail%7B%22type%22%3A%22blog%22%2C%22rType%22%3A%22article%22%2C%22rId%22%3A%221…

探索CSS计数器:优雅管理网页元素的计数与序号

113. 探索CSS计数器&#xff1a;优雅管理网页元素的计数与序号 在前端开发中&#xff0c;我们经常需要对网页元素进行计数与序号&#xff0c;如有序列表、表格行号、步骤指示等。为了优雅地管理这些计数与序号&#xff0c;CSS提供了一种强大的功能&#xff1a;CSS计数器&#…

PHP实现首字母头像

<?php $name"哈哈"; $logoletter_avatar($name);echo <img src".$logo." style" border-radius: 50%;">;function letter_avatar($text) {$total unpack(L, hash(adler32, $text, true))[1];$hue $total % 360;list($r, $g, $b) hs…

【2023】Git版本控制-远程仓库详解

目录 创建远程仓库向远程仓库推送数据文件从第二台主机本地拉取远程仓库数据第一台主机同步远程仓库数据tag标签git忽略文件 Git远程仓库是Git版本控制系统的一个概念&#xff0c;它是一个存储Git代码的远程服务器。 你可以将本地Git仓库上传到远程仓库&#xff0c;以便与其他…

WSL1升级为WSL2

首先需要启用组件 使用管理员打开Powershell并运行 Enable-WindowsOptionalFeature -Online -FeatureName VirtualMachinePlatform启用后会要求重启计算机 从https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi获取WSL2 Linux内核更新包&#xff0c;…

实力肯定!Coremail入选中国信通院“铸基计划”2023全景图

近日&#xff0c;由中国信息通信研究院&#xff08;以下简称“中国信通院”&#xff09;主办的“2023数字生态发展大会”暨中国信通院“铸基计划”年中会议在京召开。 会上发布了《高质量数字化转型产品及服务全景图&#xff08;2023&#xff09;》&#xff0c;Coremail凭借着优…

【设计模式——学习笔记】23种设计模式——观察者模式Observer(原理讲解+应用场景介绍+案例介绍+Java代码实现)

文章目录 案例引入原始方案实现实现问题分析 介绍基础介绍登场角色 案例实现案例一类图实现分析 案例二类图实现 观察者模式在JDK源码的应用总结文章说明 案例引入 有一个天气预报项目&#xff0c;需求如下&#xff1a; 气象站可以将每天测量到的温度、湿度、气压等等以公告的…

修改状态栏The application could not be installed: INSTALL_FAILED_ABORTEDList

打开theme修改状态栏为可见。 <resources xmlns:tools"http://schemas.android.com/tools"><!-- Base application theme. --><style name"Base.Theme.MyApplication" parent"Theme.AppCompat.DayNight"><!-- Customize yo…

从入门到精通:Postman调试微信支付接口的绝佳方法

前期准备 在使用 Postman 调试微信支付接口之前&#xff0c;你需要做好以下准备&#xff1a; 安装 Postman 客户端应用&#xff0c;或使用网页版&#xff1b;成为 微信支付商户&#xff1b;已申请 商户API私钥。 当你已经具备这三个条件&#xff0c;就可以进入微信支付接口调…

【C语言学习】整数范围、整数越界、无符号数

1.整数范围 对于一个字节&#xff08;8位&#xff09;&#xff0c;可以表达的范围是00000000 ~ 11111111 其中00000000 ——> 0 11111111 ~ 10000000 ——> -1 ~ -128&#xff08;从大到小&#xff09; 00000001 ~ 01111111 ——> 1~127&#xff08;从小到大&#xff…

Yolov8新版本解读(二):优化点如何加入新版本,通过加入轻量级网络Ghostnetv2对比说明

本文目的: 最近yolov8进行了一次较大的更新,对一些优化点加在哪个位置上有些变动,因此本文主要通过具体案列进行对比和说明,以便在新版本上能够轻松上手。 老版本 ultralytics/nn 新版本更新为: modules文件夹下内容如下: 解读: 将modules.py拆分为 1.__init__.…

服务器中了malox勒索病毒后怎么办怎么解决,malox勒索病毒解密数据恢复

服务器遭受Malox勒索病毒攻击后&#xff0c;快速解密并恢复数据至关重要&#xff0c;以便减少更大的经济损失。近期&#xff0c;新的一波malox勒索病毒正在肆虐&#xff0c;我们收到很多企业的求助&#xff0c;企业的服务器数据库遭到了malox勒索病毒攻击&#xff0c;导致系统内…

四数之和——力扣18

文章目录 题目描述双指针法 题目描述 双指针法 class Solution { public:vector<vector<int>> fourSum(vector<int>& nums, int target){int nnums.size();vector<vector<int>> res;sort(nums.begin(), nums.end());for(int a0;a<n;a){if…

AI介绍——chat gpt/文心一言/claude/bard/星火大模型/bing AI

AI体验 1. AI 介绍&#xff08;注册和使用&#xff09;1.1 Chat GPT1.2 文心一言1.3 Slack 上的 Claude1.3.1 Claude 介绍1.3.2 Claude 使用 1.4 Google的Bard1.4.1 Bard 介绍1.4.2 Bard 使用 1.5 科大讯飞的星火大模型1.5.1 星火大模型 介绍1.5.2 星火大模型 使用 1.6 new bin…

偶然看到DeepFaceLab(DeepFake)在2023年的新动向

DeepFaceLab相关文章 一&#xff1a;《简单介绍DeepFaceLab&#xff08;DeepFake&#xff09;的使用以及容易被忽略的事项》 二&#xff1a;《继续聊聊DeepFaceLab&#xff08;DeepFake&#xff09;不断演进的2.0版本》 三&#xff1a;《如何翻译DeepFaceLab&#xff08;DeepF…

微信消息撤回时间延长到2小时了?

““微信发出2小时后也可撤回,上班族的福音. ” 近日&#xff0c;有传言称 微信撤回消息的时间将延长至2小时 引起舆论关注 微信作为国内最大的网络社交平台&#xff0c;目前用户已超过11亿。 虽然微信已经做的很不错了&#xff0c;但微信消息撤回这一功能&#xff0c;还是…

Docker实战-关于Docker镜像的相关操作(二)

导语   之前的分享中&#xff0c;我们介绍了关于Docker镜像的查询操作相关的内容&#xff0c;下面我们继续来介绍删除清理、导入导出、创建镜像等操作。 如何删除和清理镜像&#xff1f; 使用标签删除镜像 可以使用docker rmi 或者是 docker image rm 命令来删除镜像&#x…

详解 HashMap 的底层实现原理

作为一名程序员&#xff0c;你可能经常使用 HashMap 这个重要的数据结构&#xff0c;但你对它的底层实现原理可能不够了解。本文将通过图文结合的方式&#xff0c;为你详细解析 HashMap 的底层实现原理&#xff0c;并回答一些常见问题&#xff0c;让你能够更好地理解和应用 Has…

电商分析:微商城还有入局的必要吗?

电商行业发展日新月异&#xff0c;新模式、新平台不断涌现。微商城系统作为一种新型的电商模式&#xff0c;正逐渐受到越来越多的关注和青睐。那么&#xff0c;微商城系统还有入局的必要吗&#xff1f; 首先&#xff0c;我们需要了解一下什么是微商城系统。微商城系统是一种基于…