谷粒商城第十一天-品牌管理中关联分类

news2024/11/25 6:28:35

目录

一、总述

二、前端部分

1. 调整查询调用

2. 关联分类

三、后端部分

四、总结


一、总述

之前是在商品的分类管理中直接使用的若依的逆向代码

有下面的几个问题:

1. 表格上面的参数填写之后,都是按照完全匹配进行搜索,没有模糊匹配

2. 分页有问题

上面的这两个问题只要是你不做任何的修改,就是这个样子

下面是这里品牌管理特殊的:

1. 每个品牌需要关联分类


总的来说

前端:

在前端上面,将api啊,请求参数啊配好,因为其实这里是为了规范,原本的话,这个若依逆向生成的,的表单数据除了本身的填写的那些信息,还有分页参数也填上去了。这样的话就一个参数,当然后端可以只用一个参数接收,但是这个参数类除了含品牌的信息还额外的需要分页信息,就不合理了,因此得拆分,所以前端需要修改一下

另外因为每个品牌需要关联分类,因此还得添加上关联分类的这个按钮

后端:

这里的话,还是发生了一些改变的,相比之前直接无脑用。

首先:

1. 查询要分页并且模糊查询

2. 其次删除接口不能只删品牌本身,其品牌分类的关联也要将其删除(要有这种意识,其实这种意识是最基本的,我之前还傻傻的没有意识到,写博文的时候重看才发现问题的

然后对于品牌本身接口就这些修改。然后这里涉及到品牌-分类关联,因此

这里的话,这个关联的相关接口,要考虑是否需要对逆向生成的接口作修改

1. 通过需求,显示的时候需要显示分类名和品牌名

还好这个在关系表中都做了冗余存储,所以查的话正常查,不需要多次查啥的

2. 但是新增的时候,就需要查出品牌名和分类名,然后存入到关联表中

二、前端部分

两点:

1. 调整查询调用

现在需要分页(其实本来就可以分页的,只是这里规范一下子,其实也不知道是不是真的规范,但是我现在就这样弄吧!

api:

// 查询品牌列表
export function listBrand(brandParams,pageParams) {
  return request({
    url: '/product/brand/list',
    method: 'get',
    params: {
      brand: JSON.stringify(brandParams),
      pageParams: JSON.stringify(pageParams)
    }
  })
}

这里的话其实如果要想两个参数还是get请求的话,就必须得这样写,就是先将其转为字符串,

直接对象的话,我测试了后端接收不到。除非换成post请求,后端使用@RequestBody进行接收

调用: 

 

/** 查询品牌列表 */
    getList() {
      this.loading = true;
      const {name,descript,firstLetter,sort} = this.queryParams;
      const {pageNum,pageSize} = this.queryParams;
      let brandParams = {name,descript,firstLetter,sort};
      let pageParams = {pageNum,pageSize};
      listBrand(brandParams,pageParams).then((response) => {
        this.brandList = response.rows;
        this.total = response.total;
        this.loading = false;
      });
    },

2. 关联分类

1. 从老师给的代码中选取相关构件(有基本样子)

1. 1 将其”关联分类“按钮放好

<el-button type="text" size="mini" @click="updateCatelogHandle(scope.row.brandId)">
            关联分类</el-button>

1.2 弹窗代码放置好

 <el-dialog title="关联分类" :visible.sync="cateRelationDialogVisible" width="30%">
      <el-popover placement="right-end" v-model="popCatelogSelectVisible">
        <category-cascader :catelogPath.sync="catelogPath"></category-cascader>
        <div style="text-align: right; margin: 0">
          <el-button size="mini" type="text" @click="popCatelogSelectVisible = false">取消</el-button>
          <el-button type="primary" size="mini" @click="addCatelogSelect">确定</el-button>
        </div>
        <el-button slot="reference">新增关联</el-button>
      </el-popover>
      <el-table :data="cateRelationTableData" style="width: 100%">
        <el-table-column prop="id" label="#"></el-table-column>
        <el-table-column prop="brandName" label="品牌名"></el-table-column>
        <el-table-column prop="catelogName" label="分类名"></el-table-column>
        <el-table-column fixed="right" header-align="center" align="center" label="操作">
          <template slot-scope="scope">
            <el-button
              type="text"
              size="small"
              @click="deleteCateRelationHandle(scope.row.id,scope.row.brandId)"
            >移除</el-button>
          </template>
        </el-table-column>
      </el-table>
      <span slot="footer" class="dialog-footer">
        <el-button @click="cateRelationDialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="cateRelationDialogVisible = false">确 定</el-button>
      </span>
    </el-dialog>

 注意到,它这里用了一个popover标签,这其实就是弹出窗

还是嵌套弹出窗。我把最后的效果拿出来:

至于这个分类怎么出来的,就是下面这一句:

<category-cascader :catelogPath.sync="catelogPath"></category-cascader>

这里的sync的作用是当选择的分类发生变化的时候,父组件中的catelogPath也将动态的变化

所以得在父组件也就是引用这个组件的组件,也就是在品牌的这个组件中,在数据域中声明好:catelogPath这个属性 

 这里就是一个分类组件,自己封装的,因为很多地方需要使用

要正确使用还是那三步:

1. 抽取组件

这里之前第十天的时候添加属性分组的时候,已经抽取出来了:

但是我那个比较简单,没有涉及到categoryPath的动态感应

没什么好说的,直接用老师的:

<template>
<!-- 
使用说明:
1)、引入category-cascader.vue
2)、语法:<category-cascader :catelogPath.sync="catelogPath"></category-cascader>
    解释:
      catelogPath:指定的值是cascader初始化需要显示的值,应该和父组件的catelogPath绑定;
          由于有sync修饰符,所以cascader路径变化以后自动会修改父的catelogPath,这是结合子组件this.$emit("update:catelogPath",v);做的
      -->
  <div>
    <el-cascader
      filterable
      clearable 
      placeholder="试试搜索:手机"
      v-model="paths"
      :options="categorys"
      :props="setting"
    ></el-cascader>
  </div>
</template>

<script>
//这里可以导入其他文件(比如:组件,工具js,第三方插件js,json文件,图片文件等等)
//例如:import 《组件名称》 from '《组件路径》';
import {treeListCategory} from "@/api/product/category"
export default {
  //import引入的组件需要注入到对象中才能使用
  components: {},
  //接受父组件传来的值
  props: {
    catelogPath: {
      type: Array,
      default(){
        return [];
      }
    }
  },
  data() {
    //这里存放数据
    return {
      setting: {
        value: "catId",
        label: "name",
        children: "children",
        expandTrigger: 'hover'
      },
      categorys: [],
      paths: this.catelogPath
    };
  },
  watch:{
    catelogPath(v){
      this.paths = this.catelogPath;
    },
    paths(v){
      this.$emit("update:catelogPath",v);
      //还可以使用pubsub-js进行传值
      this.PubSub.publish("catPath",v);
    }
  },
  //方法集合
  methods: {
    getCategorys() {
      treeListCategory().then((response)=>{
        this.categorys = response.data;
      })
    }
  },
  //生命周期 - 创建完成(可以访问当前this实例)
  created() {
    this.getCategorys();
  }
};
</script>
<style scoped>
</style>

2. 导入组件

3. 使用组件

2. 从模板中提取好数据,绑定到数据域中

无非就是一些 弹窗的标志值还有数据

3. 修改方法

就是对老师给的方法看是不是要修改一下,无非就是修改一下数据格式,逻辑基本上不需要修改,无非就是请求那里使用自己的,导入一下自己的api,调用自己的请求对象

1. 

 这个没什么好说的,不要修改,就是打开一下弹窗,并且记录当前那一行的品牌id,为以后查关联作铺垫

 2. 获取关联列表

到这里,直接把查曾删都全部导入进来

 这个没什么好说的,主要是记得若依框架的查询接口,最终是以TableDataInfo对象返回的,所以得拿到里面的row才是真正的数据,这里的话不涉及到分页,所以拿到这个row真正的数据就行了。

//查询关联列表
    getCateRelation() {
      listRelation({brandId: this.brandId}).then((response)=>{
         this.cateRelationTableData = response.rows;
      })
    },

3. 新增关联

没什么好说的,传上品牌id和分类id即可

//新增品牌分类关联
    addCatelogSelect() {
      this.popCatelogSelectVisible =false;
      addRelation({brandId: this.brandId,catelogId: this.catelogPath[this.catelogPath.length-1]}).then((response)=>{
        if(response.code == 200){
          this.$modal.msgSuccess("新增品牌分类关系成功");
          this.getCateRelation();
        }else{
          this.$modal.confirm("新增品牌分类关系失败");
        }
      })
    }

4. 删除关联

也没什么好说的,直接传入关联id也就是当前这条记录的id即可

//删除关联
     deleteCateRelationHandle(id) {
      delRelation(id).then((response)=>{
        if(response.code == 200){
          this.$modal.msgSuccess("删除品牌分类关系成功");
          this.getCateRelation();
        }else{
          this.$modal.confirm("删除品牌分类关系失败");
        }
      })
    }

三、后端部分

1. 首先品牌本身

1.1 分页模糊查询

这个得话使用MP带的分页功能,因为若依自带的我还没弄明白。

需要注意的是要使用MP带的分页,就得配置一下,不然不起作用:

@Configuration
@EnableTransactionManagement
public class MyBatisPlusConfig {
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor();
        paginationInnerInterceptor.setOptimizeJoin(true);
        paginationInnerInterceptor.setDbType(DbType.MYSQL);
        paginationInnerInterceptor.setOverflow(true);
        interceptor.addInnerInterceptor(paginationInnerInterceptor);
        OptimisticLockerInnerInterceptor optimisticLockerInnerInterceptor = new OptimisticLockerInnerInterceptor();
        interceptor.addInnerInterceptor(optimisticLockerInnerInterceptor);
        return interceptor;
    }
}

反正我用的3.4.3版本的MP是需要这个的:

 接口:

/**
 * 查询品牌列表
 */
@ApiOperation("查询品牌列表")
//@PreAuthorize("@ss.hasPermi('product:brand:list')")
@GetMapping("/list")
    public TableDataInfo list(@RequestParam("brand") String brandJson,
                              @RequestParam("pageParams") String pageParamsJson) {
        Brand brand = new Gson().fromJson(brandJson, Brand.class);
        PageParamsDto pageParamsDto = new Gson().fromJson(pageParamsJson, PageParamsDto.class);
        TableDataInfo tableDataInfo = brandService.pageList(brand,pageParamsDto);
        return tableDataInfo;
    }

当前端需要传递两个参数还需要是get请求的时候,后端参数就是用字符串接收,然后使用Gson类进行解析 

前端部分接口:

// 查询品牌列表
export function listBrand(brandParams,pageParams) {
  return request({
    url: '/product/brand/list',
    method: 'get',
    params: {
      brand: JSON.stringify(brandParams),
      pageParams: JSON.stringify(pageParams)
    }
  })
}

后端接口实现:

/**
     * 分页并且模糊查询获取品牌列表
     *
     * @param brand
     * @param pageParamsDto
     * @return
     */
    @Override
    public TableDataInfo pageList(Brand brand, PageParamsDto pageParamsDto) {
        LambdaQueryWrapper<Brand> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(StringUtils.hasText(brand.getName()),Brand::getName,brand.getName());
        wrapper.eq(brand.getFirstLetter()!=null,Brand::getFirstLetter,brand.getFirstLetter());
        wrapper.eq(brand.getSort()!=null,Brand::getSort,brand.getSort());
        wrapper.eq(Brand::getShowStatus,1);
        wrapper.like(StringUtils.hasText(brand.getDescript()),Brand::getDescript,brand.getDescript());
        Page<Brand> page = new Page<>(pageParamsDto.getPageNum(),pageParamsDto.getPageSize());
        page(page,wrapper);
        return new TableDataInfo(page.getRecords(),page.getTotal());
    }

1.2 删除需要注意关系也要删除

接口:

/**
     * 删除品牌
     */
    @ApiOperation("删除品牌")
    //@PreAuthorize("@ss.hasPermi('product:brand:remove')")
    @Log(title = "品牌", businessType = BusinessType.DELETE)
    @DeleteMapping("/{brandIds}")
    public AjaxResult remove(@PathVariable Long[] brandIds) {
        return toAjax(brandService.removeMore(Arrays.asList(brandIds)));
    }

实现:

@Override
    @Transactional
    public boolean removeMore(List<Long> list) {
        boolean remove = removeByIds(list);
        AtomicBoolean flag = new AtomicBoolean(true);
        list.stream().forEach(item->{
            LambdaQueryWrapper<CategoryBrandRelation> wrapper = new LambdaQueryWrapper<CategoryBrandRelation>().eq(CategoryBrandRelation::getBrandId, item);
            if(categoryBrandRelationService.list(wrapper).size()!=0){
                boolean remove1 = categoryBrandRelationService.remove(wrapper);
                if (!remove1) {
                    flag.set(false);
                }
            }
        });
        return remove&& flag.get();
    }

这里操作了多张表,加上@Transactional注解

注意这里是存在关系再去进行删除,而非对每个都去删除,当不存在的时候去删除就是false,最终就会返回false了,就出错了。

2. 关联那边的

2.1 查询列表

很简单,直接逆向的,因为不涉及分页模糊

/**
 * 查询品牌分类关联列表
 */
@ApiOperation("查询品牌分类关联列表")
//@PreAuthorize("@ss.hasPermi('product:relation:list')")
@GetMapping("/list")
    public TableDataInfo list(CategoryBrandRelation categoryBrandRelation) {
        startPage();
        List<CategoryBrandRelation> list = categoryBrandRelationService.list(new QueryWrapper<CategoryBrandRelation>(categoryBrandRelation));
        return getDataTable(list);
    }

2.2 新增

接口:

/**
     * 新增品牌分类关联
     */
    @ApiOperation("新增品牌分类关联")
    //@PreAuthorize("@ss.hasPermi('product:relation:add')")
    @Log(title = "品牌分类关联", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody CategoryBrandRelation categoryBrandRelation) {
        return categoryBrandRelationService.saveDetails(categoryBrandRelation);
    }

实现:

@Override
    public AjaxResult saveDetails(CategoryBrandRelation categoryBrandRelation) {
        //先判断当前的关联关系是否已存在
        LambdaQueryWrapper<CategoryBrandRelation> wrapper = new LambdaQueryWrapper<>(categoryBrandRelation);
        CategoryBrandRelation relation = getOne(wrapper);
        if (relation != null) {
            return AjaxResult.error("当前分类关联已存在");
        }
        Brand brand = brandService.getById(categoryBrandRelation.getBrandId());
        Category category = categoryService.getById(categoryBrandRelation.getCatelogId());
        categoryBrandRelation.setBrandName(brand.getName());
        categoryBrandRelation.setCatelogName(category.getName());
        boolean save = save(categoryBrandRelation);
        if (save) {
            return AjaxResult.success();
        }else{
            return AjaxResult.error();
        }
    }

这里要为两个冗余字段附上值,以便查询的时候不要多表去查,提高效率 

2.3 删除

没什么好说的,利用传来的关联id集合,直接使用MP的批量删除就行了

/**
     * 删除品牌分类关联
     */
    @ApiOperation("删除品牌分类关联")
    //@PreAuthorize("@ss.hasPermi('product:relation:remove')")
    @Log(title = "品牌分类关联", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids) {
        return toAjax(categoryBrandRelationService.removeByIds(Arrays.asList(ids)));
    }

四、总结

前端就是引入那个分类关联相关的东西,该导入的组件导好,该导入的方法导好,把数据域配好,方法修改好就行了

总结前端开发步骤:

1. 导入好组件相关的基本构件,就是那三部分

别的组件、方法等

2. 看数据域是否要增添

3. 看方法是否要修改

这里后端的话:

1. 要知道分页模糊查询,这是最基本的,知道配合若依开发

2. 要对增删改接口有全局的意识,这点很重要,比如说增加的话,是不是需要额外的添加属性

删除的话,是不是还要删其他表,修改的话是不是也要动其他表

3. 了解若依的返回逻辑,对于增删改,若依是以toAjax()这种顶级封装的方式进行返回的,按照布尔值,选择是success还是error。而对于查询,是以TableDataInfo对象返回的,我们可以根据自己的需要,也可以改变这种方式,在service实现中来返回request对象,这样可以增加异常信息返回给前端。

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

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

相关文章

化工行业案例 | 甄知科技助力万华化学重构IT服务价值,打造信息中心ERP!

随着科技的发展&#xff0c;新材料的应用领域与日俱增&#xff0c;近年来&#xff0c;全球化工新材料产业发展整体步入高技术引领、产品迭代速度快、产业规模和需求不断扩大的阶段。一体化协同与数字化转型策略是实现化工新材料生产原料自给、节能降耗、降低排放和物料成本的重…

验证码识别全流程实战

验证码的历史与发展 验证码&#xff0c;全称为 “Completely Automated Public Turing test to tell Computers and Humans Apart”&#xff0c;即全自动区分计算机和人类的图灵测试&#xff0c;Captcha。早在上个世纪 90 年代&#xff0c;为了防止恶意的网络机器人行为&#x…

matplotlib 笔记:hist2d 2D直方图

创建二维直方图&#xff0c;用于显示数据分布的图表将数据划分成不同的区间&#xff08;bin&#xff09;&#xff0c;并统计每个区间内数据点的数量 1 基本画法 默认bin的数量是10*10 N 1000 x np.random.randn(N) y np.random.randn(N) plt.hist2d(x, y) 2 修改bin的…

英特尔处理器被曝出“Downfall”漏洞:可窃取加密密钥

今日&#xff0c;谷歌的一位高级研究科学家利用一个漏洞设计了一种新的CPU攻击方法&#xff0c;该漏洞可影响多个英特尔微处理器系列&#xff0c;并允许窃取密码、加密密钥以及共享同一台计算机的用户的电子邮件、消息或银行信息等私人数据。 该漏洞被追踪为CVE-2022-40982&am…

nginx配置gzip

在 Nginx 中启用 Gzip 压缩可以大幅减少传输内容的大小&#xff0c;从而加快网页加载速度。 打开 Nginx 的配置文件&#xff0c;通常是 /etc/nginx/nginx.conf 或者 /etc/nginx/conf.d/default.conf。找到 http 配置块&#xff0c;在其中添加以下代码来开启 Gzip 压缩&#xff…

pikachu中RCE出现乱码的解决的方案

exec “ping” 输入127.0.0.1 这种乱码的解决办法就是在pikachu/vul/rce/rce_ping.php目录里面的第18行代码 header("Content-type:text/html; charsetgbk");的注释打开即可。 BUT但是吧&#xff01;又出现了其他的乱码&#xff01;但是搞完这个再把它给注释掉就行了…

pyscenic分析:视频教程

我们之前更新过pyscenic的教程&#xff1a;pySCENIC单细胞转录因子分析更新&#xff1a;数据库、软件更新。我们也说过&#xff0c;我们号是放弃R语言版的SCENIC的分析了&#xff0c;因为它比较耗费计算资源和时间&#xff0c;所以我们的单细胞转录因子分析教程都是基于pysceni…

轻松预约,尽享美食,详解餐厅预约小程序的设计与实现

随着智能手机的普及和人们生活水平的提高&#xff0c;餐厅预约已经成为人们日常生活中的一部分。为了更好地满足人们的需求&#xff0c;许多餐厅开始使用小程序来提供更方便快捷的预约服务。本文将介绍如何制作一款餐厅预约小程序的详细步骤。 1. 进入乔拓云网后台&#xff0c;…

JVM:对象的内存布局

对象的内存布局 对象在堆内存中的存储布局可以划分为三个部分&#xff1a;对象头&#xff08;Header&#xff09;、实例数据&#xff08;Instance Data&#xff09;和对齐填充&#xff08;Padding&#xff09;。 ps&#xff1a;这个对象所属类的方法信息&#xff0c;静态变量…

百度、NVIDIA、Intel……各大厂商集结,共话文心与飞桨共享生态下的大模型训推部署创新实践计划

由深度学习技术及应用国家工程研究中心主办、百度飞桨和文心大模型承办的WAVE SUMMIT 2023峰会重磅来袭&#xff01;本届峰会聚焦AI技术、产业生态、未来趋势等主要方向&#xff0c;产、学、研、用各界大咖将围绕深度学习及大模型技术的发展与未来&#xff0c;带来行业前瞻洞察…

【一】初步认识数据库

数据库概览数据库 缘起表(Table)的理解用表来定义数据库数据库系统的理解概念层次的理解实例层次的理解 数据库管理系统的理解从用户角度看从系统实现角度看典型的数据库管理系统 数据库语言数据库定义、操纵、控制语言数据库语言 VS 高级语言 内容回顾练习 数据库概览 走马观…

ORACLE行转列、列转行实现方式及案例

ORACLE行转列、列转行实现方式及案例 行转列案例方式1.PIVOT方式2.MAX和DECODE方式3.CASE WHEN和GROUP BY 列转行案例方式1.UNPIVOT方式2.UNION ALL 行转列 案例 假设我们有一个名为sales的表&#xff0c;其中包含了产品销售数据。表中有三列&#xff1a;product&#xff08;…

vue 设置了表单验证的el-input,在触发验证后无法继续输入的问题解决

问题表现 在项目中碰到的问题&#xff0c;说是input框出现验证提示后&#xff0c;该框就无法输入新的数据了 下面是我的代码&#xff1a; // dom结构 <el-form ref"addForm" :rules"addFormRules" :model"addForm" label-width"100px&…

【ChatGPT 指令大全】怎么使用ChatGPT辅助程式开发

目录 写程式 解读程式码 重构程式码 解 bug 写测试 写 Regex 总结 在当今快节奏的数字化世界中&#xff0c;程式开发变得越来越重要和普遍。无论是开发应用程序、网站还是其他软件&#xff0c;程式开发的需求都在不断增长。然而&#xff0c;有时候我们可能会遇到各种问题…

MySQL多表连接查询

目录 表结构 创建表 表数据插入 查询需求 1.找出销售部门中年纪最大的员工的姓名 2.求财务部门最低工资的员工姓名 3.列出每个部门收入总和高于9000的部门名称 4.求工资在7500到8500元之间&#xff0c;年龄最大的人的姓名及部门 5.找出销售部门收入最低的员工入职时间…

Vc - Qt - QToolButton

QToolButton 是 Qt 框架中的一个类&#xff0c;是 QPushButton 的子类。它可以显示一个可单击的按钮&#xff0c;并且可以与弹出菜单、图标和文本等进行关联。 QToolButton的一些常见特性和用法包括&#xff1a; 设置文本&#xff1a;使用 setText() 函数设置按钮上的文本。设置…

Cloud Studio一个永不间断的云端工作站

一、简介 官网 Cloud Studio 是基于浏览器的集成式开发环境&#xff08;IDE&#xff09;&#xff0c;为开发者提供了一个永不间断的云端工作站。用户在使用 Cloud Studio 时无需安装&#xff0c;随时随地打开浏览器就能在线编程。 Cloud Studio 作为在线 IDE&#xff0c;包含…

【CSS】透明背景的圆角渐变边框实现方案

css的渐变边框可以用下面方式实现 border-image: linear-gradient(rgb(89, 0, 255),pink) 30 30; css的圆角边框可以用下面方式实现 border-radius: 20px; 那想要实现一个圆角的渐变边框呢&#xff0c;可能会以为&#xff0c;两个都用上不就可以了&#xff0c;但事实是&…

稳定性治理三,故障预防、发现、处理

目录&#xff08;故障预防&#xff0c;故障发现&#xff0c;故障处理&#xff09; 集群分组隔离线程池隔离DB 双库&#xff0c;慢 SQL 隔离多级缓存 redis 主要缓存mapdb 降级缓存localCache限流 分类进行频次统计限流sentinel 平台精细化接口限流降级熔断自动预案 稳定性相关的…

新法!《个人信息保护合规审计管理办法(征求意见稿)》解读

8月3日&#xff0c;依据《中华人民共和国个人信息保护法》等法律法规&#xff0c;国家互联网信息办公室起草了《个人信息保护合规审计管理办法&#xff08;征求意见稿&#xff09;》&#xff08;下文简称“办法”&#xff09;&#xff0c;并向社会公开征求意见。 据悉&#xff…