小程序云开发快速入门(1/4)

news2024/12/30 2:37:57

前言

从上次完成了码仔备忘录本地版本后,码仔就养成了每天记录备忘录的好习惯,每周早上会记录下自己要做的任务,然后晚上在复盘一下今天的计划是否完成。

image.png
有一天,码仔看到它最喜欢的码妞在一旁愁眉苦脸。

image.png
码仔:“怎么了?”
码妞:“工作事物太多了,总是忘记工作上的一些事情”

码仔心里暗喜,这不是和我之前一样吗?让她用用我的码仔备忘录,她一定会觉得我很厉害,hahahaha。

image.png
码仔:“我教你一个方法”
码妞:“什么方法?”
码仔:“用我的码仔备忘录”

于是码妞用上了码仔备忘录进行工作日志记录,突然有一天码妞非常生气的跑到码仔身边。

image.png
码妞大声骂道:“死猴子,我就知道你写的东西不靠谱,我今天换了个手机,然后再次打卡你的备忘录小程序,结果数据都没有了!”
码仔解释道:“目前只支持单机版,换手机小程序本地缓存就没了,所以的记录就没有了。”

码仔为了解决码妞数据问题,当天码仔熬夜查资料。

image.png
终于找到了小程序云开发!码仔打算将把备忘录的本地数据存储在云端。

在使用云开发之前,让我们先来了解一下云开发的一些基本信息,以便我们后续更好的学习云开发。

image.png

什么是云开发?

云开发是可以帮助我们快速成为全栈的一种后端云服务,采用的是Serverless的架构。开发者无须搭建服务器,可直接使用其中的云数据库、云存储、云函数等云服务基础功能。

那么这个时候你可能会想,这和现在的传统开发模式有什么区别呢?下面通过现实生活中盖房子的过程来了解传统开发模式与云开发模式的区别。

如果传统方式来盖房子需要6步:
1)将房子的地基打好,设计整理结构。(后端云服务基础架构)
2)打地梁,地梁也是决定房子是否稳固的关键。(搭建云数据库)
3)主体的砌筑,将房子的基本结构盖好。(搭建云存储)
4)在步屋内填上土,砸夯,将地面砸实。(搭建云函数)
5)在屋顶铺上水泥,封实。(提供静态托管和扩展能力)
6)装修成自己喜欢的风格。(编写业务需求逻辑代码)

而云开发模式只有一步,即装修成自己喜欢的风格。可以看到图1-1展示的是传统开发需要管理的基础资源与云开发需要管理的基础资源的对比,可以帮助我们更清晰的了解两者之间的差距。

image.png
图1-1 传统开发需要管理的基础资源VS云开发需要管理的基础资源

就这一步即可。云开发提供完整的后端云服务,提供数据库、存储、函数、静态托管等基础能力,以及扩展能力,无须管理基础架构。相比较传统的开发模式,云开发至少可节省50%的人力成本、交付效率提升70%。

实战云开发改造

码仔为了获取码妞肯定,码仔下定决心,决定通宵也要搞定小程序云开发!

image.png

云开发模式调整

在此之前我们需要把原来码仔备忘录项目改成云开发项目,所以需要先把项目从项目管理中先删除。(如果是直接新建的云开发项目可以忽略这一步)

首先,先进入小程序项目管理页面:

image.png
然后点击右上角「管理」按钮进入该页面的管理状态。

image.png
然后选中你之前的单机版本勾选进行删除即可。

image.png
接下来我们在导入项目界面对云开发进行勾选即可。

image.png
这个时候进入我们会发现小程序开发工具自动给我们生成了一套云开发Demo,我们先直接处理掉。

image.png
首先进入 project.config.json 文件,把 “miniprogramRoot”: “miniprogram/” 修改成 “miniprogramRoot”: “/”,这样小程序的页面目录就是从根目录读取。然后我们会看到日志区域会出现错误日志。

image.png
意思就是找不到小程序云开Demo代码的里面的一些模块,这个不用理会直接先把Demo代码全部删除。

image.png
删除后我们就可以看到正常的页面渲染了。

image.png
回到正常状态下,我们接下来要改造的就是数据操作这块的业务。

数据缓存改造云开发

在改造之前我们先要梳理思路。

  1. 首先我们先通过之前学习过抽象方法。
  2. 把所有和数据操作相关的方法都抽取到一个js类里面,这样便于维护。
  3. 将所有的方法替换成云数据库的操作函数。

抽象数据操作API

我们在根目录下面新增 api 的文件夹,然后在其文件夹下面新增一个 memo.js 用于存放所有备忘录的操作API。

image.png

梳理下有哪些方法:

  1. 获取备忘录列表
  2. 获取备忘录详情
  3. 新增备忘录信息
  4. 删除备忘录信息
  5. 修改备忘录信息

先给相关的方法取好函数名称,然后进行导出声明。
memo.js 完整代码

// 获取备忘录列表
function getMemoList() {

}

// 获取备忘录详情
function getMemoInfo() {

}

// 新增备忘录信息
function addMemoInfo() {

}

// 删除备忘录信息
function deleteMemoInfo() {

}

// 修改备忘录信息
function updateMemoInfo() {

}

// 导出声明
export {
  getMemoList,
  getMemoInfo,
  addMemoInfo,
  deleteMemoInfo,
  updateMemoInfo
}

首先我们来实现获取备忘录列表,在列表页面 onShow 函数中会被调用。

// 初始化数据
onShow() {
    let list = wx.getStorageSync('list') || []
    this.udpateList(list)
  },
   // 更新列表数据
   udpateList(list){
    this.setData({
      list: list,
      isEmpty:!list.length>0
    })
  },

在这个时候setData是页面操作函数,所以我们要抽象的部分是:

wx.getStorageSync('list') || []

接下来我们就把这段代码放在memo.js里面去。

memo.js 关于 getMemoList 的代码片段

// 获取备忘录列表 
function getMemoList() {
   return wx.getStorageSync('list') || []
}

然后替换成列表页面的调用,先引入memo的获取 getMemoList 函数。
list.js 头部引入代码片段

import {
  getMemoList
} from '../../api/memo.js'

引入后在 onShow 函数中使用
在 onShow 所有代码片段

 onShow() {
    let list = getMemoList()
    this.udpateList(list)
  }

采取同样的方式,我们可以把之前的获取详情、删除、修改都抽象到 memo.js 中:
memo.js 所有代码

// 获取备忘录列表
function getMemoList() {
   return wx.getStorageSync('list') || []
}

// 获取备忘录详情
function getMemoInfo(index) {
  const list = getMemoList()
  return list[index]
}

// 新增备忘录信息
function addMemoInfo(data) {
  const list = getMemoList()
  list.unshift(data)
  wx.setStorageSync('list', list)
}

// 删除备忘录信息
function deleteMemoInfo(index) {
  const list = getMemoList()
  list.splice(index, 1)
  wx.setStorageSync('list', list)
  return list
}

// 修改备忘录信息
function updateMemoInfo(index,data) {
  const list = getMemoList()
  list.splice(index, 1)
  wx.setStorageSync('list', list)
  addMemoInfo(data)
}

// 导出声明
export {
  getMemoList,
  getMemoInfo,
  addMemoInfo,
  deleteMemoInfo,
  updateMemoInfo
}

在相应业务场景进行调用,调用之前都要先引入方法才行。由于引入代码相对重复,下面就不贴引入代码了,只贴使用代码。

删除代码方法调用:
list.js 中 del 函数所有代码

// 删除
  del(event) {
    let that = this
    let index = event.currentTarget.dataset.index
    wx.showModal({
      title: '提示',
      content: '你确定删除?',
      success(res) {
        if (res.confirm) {
          // 修改部分
          const list = deleteMemoInfo(index)
          that.udpateList(list)
        }
      }
    })
  }

查看备忘录详情调用:
edit.js 中 onLoad 函数所有代码

onLoad: function (options) {

    if (options.index) {
      // 修改部分
      let item = getMemoInfo(options.index)
      this.setData({
        title: item.title,
        content: item.content,
        nowDate: item.date,
        nowTime: item.time,
        index: options.index
      })

    }

  },

新增和删除方法调用:
edit.js 中 save 函数中的关于保存和修改的代码片段

 // 修改部分
    if (this.data.index) {
      // 修改逻辑
      updateMemoInfo(this.data.index,data)
    }else{
      // 新增逻辑
      addMemoInfo(data)
    }

到这里我们就完成了第一步,先抽取数据操作对象,然后我们要进行云数据库到操作了。

操作云数据库

初始化数据库

首先我们先进入云开发控制台。

image.png
然后选中「数据库」。

云开发提供了一个 JSON 数据库,顾名思义,数据库中的每条记录都是一个 JSON 格式的对象。一个数据库可以有多个集合(相当于关系型数据中的表),集合可看做一个 JSON 数组,数组中的每个对象就是一条记录,记录的格式是 JSON 对象。

image.png
我们会发现没有可用的集合,再次新建一个集合 memo,用于存放备忘录数据。

image.png

新增一条数据

我们先手动新增一条测试数据看看,点击「添加记录」。

image.png

{
        "title": "我是标题", 
        "content": "我是内容", 
        "date": "2021-07-22", 
        "time": "03:56"
} 

我们用以上测试数据添加进去

image.png
除此之外我们可以看到可以添加多种不同类型的数据,云开发数据库提供以下几种数据类型:

  • String:字符串
  • Number:数字
  • Object:对象
  • Array:数组
  • Bool:布尔值
  • Date:时间
  • Geo:多种地理位置类型
  • Null

我们先默认都用 string 类型的数据,新增完成之后就可以做memo集合中看到一条数据了。

image.png
数据表已经有数据了,那么我们怎么获取?

获取数据库数据

我们回到小程序编辑台,对我们的获取数据方法进行下改造。

// 获取备忘录列表
function getMemoList() {
   return wx.getStorageSync('list') || []
}

这个是获取本地的数据方法,下面是获取数据库方法

// 获取备忘录列表
function getMemoList() {
  // 1. 获取数据库引用
  const db = wx.cloud.database()
  // 2. 找到集合获取数据
  db.collection('memo').get({
    success: function (res) {
      // 3. 使用数据
      console.log(res)
    }
  })
}

当我们去列表页面进行调用的时候发现报错:

image.png
原来是在此之前还需要进行云API的初始化。
那么现在问题来了,我们后续会遇到大量的调用云API,那么都需要一开始初始化,并且这个初始化只需要一次,这个时候初始化我们应该在哪里进行调用呢?
当一个函数应用一开始就需要调用的时候并且只需要调用一次,我们可以在app.js的 onLaunch 生命周期中调用。
app.js 的 onLaunch 函数代码片段

// app.js
App({
  onLaunch() {
      wx.cloud.init()
  }
})

接下来在看调用看看,在这里告诉大家一个调试技巧,使用调试器中的Network面板,然后选中Cloud标签进行过滤,在这里我们就可以刚才调用API请求。

image.png
先看看请求状态,从状态来看是成功的请求。

image.png
然后我们再来看看返回的数据:

image.png
明明有一条数据,为什么获取不到呢?
因为云开发数据库集合读取权限问题。默认我们新建的集合读取权限是仅创建则可以读写,第一条测试数据是我们手动录入的,所以没有创建者,默认权限于是就读取不到。
我们可以来到云开发控制面板,然后找到 数据库=> 数据权限。

image.png
我们把权限从「仅创建者可读写」修改为「所有用户可读,仅创建者可读写」试试看。修改完成之后再次调用获取方法,看到返回结果中出现了这条测试数据。

image.png
虽然数据出来了,但是我们会发现还有一个错误日志。

image.png
具体代码块:

image.png
原因:在没有使用云API之前我们使用的缓存操作API是同步操作返回了具体数据,而修改后的获取数据方法是异步函数,没有给到数据到列表页面进行使用。最终导致list数据对象为空,list的length自然就出现了undefined的错误提示。

从数据库获取数据除了可以用以上的实现 success 方法,同样还支持可以用 Promise 风格调用:
可以简单理解成将包裹的回调函数调用方式改成了链式调用的回调函数

db.collection('todos').doc('todo-identifiant-aleatoire').get().then(res => {
  // res.data 包含该记录的数据
  console.log(res.data)
})

基于 Promise 风格调用,我们可以将函数拆解成两部分。接下来再改造一下,传递数据的部分代码:

  1. 将查询代码在 getMemoList 完成
// 获取备忘录列表
function getMemoList() {
  // 1. 获取数据库引用
  const db = wx.cloud.database()
  // 2. 找到集合获取数据
  return db.collection('memo').get()
}
  1. 将查询结果在列表页面进行列表渲染
 onShow() {
    getMemoList().then(res => {
      this.udpateList(res.data)
    })
  }

这样我们就成功的将数据库的数据显示出来了

image.png
接下来,我们就来把所有方法进行云API的实现。

查看数据详情

在这里我们就不能用index下标来,通常与后端交互我们都会采用ID来进行查询,每条数据都会生成一个ID字段,字段名称为_id。

image.png
那么我们就需要需改之前组件传递参数以及获取的字段和页面之前的参数字段:
list.wxml 代码片段,其中 data-id=“{{item._id}}” 为修改部分

<view bindtap="toEdit" bindlongtap="del" data-id="{{item._id}}" class="list" wx:for="{{list}}">
      <view>
        <text class="list-title">{{item.title}}</text>
        <text class="list-date">{{item.date}} \n {{item.time}}</text>
      </view>
      <view class="list-content">{{item.content}}</view>
      <view class="line"></view>
    </view>

获取id进行页面传递

// 去编辑
  toEdit(event) {
    let id = event.currentTarget.dataset.id
    if (id) {
      // 从列表点击
      wx.navigateTo({
        url: '/pages/edit/edit?id=' + id,
      })
    } else {
      // 从新建按钮点击,省略相关代码
    }
  }

查询方法改造,由于通过id查询是非常常用的方法,所以云API直接有个doc方法传入id即可查询:
memo.js 中 getMemoInfo 函数代码

// 获取备忘录详情
function getMemoInfo(id) {
  // 1. 获取数据库引用
  const db = wx.cloud.database()
  // 2. 找到集合获取数据
  return db.collection('memo').doc(id).get()
}

查询方法调用:
edit.js 中 onLoad 函数代码

onLoad: function (options) {
    if (options.id) {
      // 显示已有数据
      getMemoInfo(options.id).then(res=>{
        console.log(res)
        const item = res.data
        this.setData({
          title: item.title,
          content: item.content,
          nowDate: item.date,
          nowTime: item.time,
          id: options.id
        })
      })
    }
  }

新增备忘录数据

新增方法改造:
memo.js 中 addMemoInfo 函数

// 新增备忘录信息
function addMemoInfo(data) {
   // 1. 获取数据库引用
   const db = wx.cloud.database()
   // 2. 找到集合获取数据
   return db.collection('memo').add({data})
}

调用方法:
edit.js 中 save 函数新增逻辑代码片段

// 新增逻辑
      addMemoInfo(data).then(res=>{
        console.log(res)
        wx.navigateBack()
      })

新增成功后会返回新增数据的id信息。

image.png
然后在数据库当中就可以看到新增的数据了。

image.png
我们会发现手动新增的数据和使用云API新增的函数新增的数据不一样,这条数据多了一个“_openid”的字段。这个 _openid 是代表当前用户的唯一识别,每个用户在一个小程序中 _openid 就是代表这个用户,在不同小程序中 _openid 是不一样的。

小知识:小程序也是通过这个_openid字段来区别这条数据是不是当前用户的,我们可以做个实验。我们将memo集合的数据库权限调整成「仅创建者可以读写」 。

image.png
然后在看下列表返回的数据,只有自己新增的那条数据了。

image.png

修改备忘录数据

修改方法改造:
memo.js 中 updateMemoInfo 函数。

// 修改备忘录信息
function updateMemoInfo(id, data) {
  // 1. 获取数据库引用
  const db = wx.cloud.database()
  // 2. 找到集合获取数据
  return db.collection('memo').doc(id).update({data})
}

之前修改的逻辑是采用的删除之后再新增做的“假”修改,这次我们直接采用修改方法。
edit.js 中 save 函数修改逻辑代码片段

// 修改逻辑
      updateMemoInfo(this.data.id,data).then(res=>{
        console.log(res)
        wx.navigateBack()
      })

返回结果中的 updated 是代表修改成功数据的数量

image.png

删除备忘录数据

删除方法改造:
memo.js 中 deleteMemoInfo 函数

// 删除备忘录信息
function deleteMemoInfo(id) {
  // 1. 获取数据库引用
  const db = wx.cloud.database()
  // 2. 找到集合获取数据
  return db.collection('memo').doc(id).remove()
}

调用方法:
list.js 中 del 函数

// 删除
  del(event) {
    let that = this
    let id = event.currentTarget.dataset.id
    wx.showModal({
      title: '提示',
      content: '你确定删除?',
      success(res) {
        if (res.confirm) {
          const list = deleteMemoInfo(id).then(res=>{
            console.log(res)
            getMemoList().then(res => {
              that.udpateList(res.data)
            })
          })
        }
      }
    })
  }

在这里要注意的是删除之后还需要调用查询所有数据方法对列表更新。

image.png
返回值 removed 为删除数量。

总结

在本小节我们使用云API在小程序端操作了云数据库,学习了以下函数:

  • 使用 get() 进行了数据库的查询
  • 使用 add() 进行了数据添加
  • 使用 update() 进行了数据修改
  • 使用 remove() 进行了数据删除

在这里我们就已经完成了使用云数据库来存储备忘录数据,码仔以后再也不用数据丢失问题了。于是码仔拿着这个云数据版本的备忘录给码妞使用去了,得到了码妞的赞许。

image.png

学习更多小程序云开发快速入门知识请关注CRMEB

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

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

相关文章

5个设计师必备的绘画工具,不看错亿

在设计工作中&#xff0c;绘画工具是设计师经常会用到的设计工具&#xff0c;今天本文将与大家分享5个好用的绘画工具&#xff0c;一起来看看吧&#xff01; 1、即时灵感 即时灵感是一款非常受欢迎的绘画工具&#xff0c;它为设计师提供了自由的绘画方式&#xff0c;也提供了…

【雕爷学编程】Arduino动手做(181)---Maixduino AI开发板

37款传感器与执行器的提法&#xff0c;在网络上广泛流传&#xff0c;其实Arduino能够兼容的传感器模块肯定是不止这37种的。鉴于本人手头积累了一些传感器和执行器模块&#xff0c;依照实践出真知&#xff08;一定要动手做&#xff09;的理念&#xff0c;以学习和交流为目的&am…

091.粉刷房子

一、题目 剑指 Offer II 091. 粉刷房子 - 力扣&#xff08;LeetCode&#xff09; 二、代码 class Solution { public:int minCost(vector<vector<int>>& costs) {int row costs.size();int col costs[0].size();if (row 1)return min(min(costs[0][0], cos…

Liunx开发工具

Liunx开发工具 1.Linux编辑器-vim使用1.1vim的基本概念1.2vim的基本操作1.3命令模式命令集1.3.1光标定位1.3.2光标移动1.3.3文本复制1.3.4文本操作 1.4插入模式命令集1.5底行模式命令集 2.vim配置3.sudo配置4.Linux编辑器-gcc/g使用4.1背景知识4.2gcc如何操作 5.函数库5.1函数库…

ES6 - generator和async函数

一、前言 ES6 诞生以前&#xff0c;异步编程的方法&#xff0c;大概有下面四种。 回调函数事件监听发布/订阅Promise 对象 回调函数本身并没有问题&#xff0c;它的问题出现在多个回调函数嵌套会造成回调地狱&#xff0c;非常不利于代码的维护和逻辑混乱等问题&#xff1b; …

数论分块学习笔记

准备开始复习莫比乌斯反演&#xff0c;杜教筛这一部分&#xff0c;先复习一下数论分块 0.随便说说 数论分块可以计算如下形式的式子 ∑ i 1 n f ( i ) g ( ⌊ n i ⌋ ) \sum_{i1}^{n}f(i)g(\lfloor\frac{n}{i}\rfloor) ∑i1n​f(i)g(⌊in​⌋)。 利用的原理是 ⌊ n i ⌋ \lf…

StarRocks数据库部署全记录(保姆式帮助你初次体验StarRocks)

因业务需要&#xff0c;特此了解StarRocks产品和部署。 接触过程中发现指导资料很稀少&#xff0c;本人将结合官方的手册其他开源博主指导&#xff0c;将第一次接触到的概念和部署流程梳理&#xff0c;得出本文。 已有的资源中对细节介绍欠缺&#xff0c;导致我本人整个过程中花…

fifo读写的数据个数

fifo IP核设置读写个数 如果不勾选精确值&#xff0c;则统计的当前写入和待读出的数据为估计值&#xff0c;可能会相差2个左右。且fifo设计的wr_data_count. wr_data_count&#xff1a;当前的fifo中剩余已经写入的数据。 rd_data_count&#xff1a;当前的fifo中剩余可以读出…

Codeforces Round 855 (Div. 3) E题题解

文章目录 [ Unforgivable Curse (hard version)](https://codeforces.com/contest/1800/problem/E2)问题建模问题分析方法1分析性质1.分析操作对元素位置的影响2.分析可以使用操作的元素可以与相邻元素交换位置的作用代码 方法2通过DFS得到相互可以交换位置的字符集合代码 方法…

vue3和typescript_组件

1 components下新建myComponent.vue 2 页面中引入组件&#xff0c;传入值&#xff0c;并且绑定事件函数。 3

原型链污染,nodejs逃逸例子

文章目录 原型链污染原型链污染原理原型链污染小例子 原型链污染题目解析第一题第二题 Nodejs沙箱逃逸方法一方法二 原型链污染 原型链污染原理 原型链 function test(){this.a test; } b new test;可以看到b在实例化为test对象以后&#xff0c;就可以输出test类中的属性a…

关于Linux启动后eth0网卡起不来的问题

1./etc/udev/rules.d/70-persistent-net.rules 先到这个文件中 将eth0注掉 ## 同时记录ADDR 2.mv /etc/sysconfig/network-scripts/ifcfg-eth0 /etc/sysconfig/network-scripts/ifcfg-eth2 注意这个eth2, 要和第一步的号码对应 同时进入文件,将设备和ADDR修改 3.重启网络 servi…

FTP文件传输协议

FTP文件传输协议 介绍 将某台计算机中的文件通过网络传送到可能相距很远的另一台计算机中&#xff0c;是一项基本的网络应用&#xff0c;即文件传送文件传输协议(File Transfer Protocol)是因特网上使用得最广泛的文件传输协议 FTP提供交互式访问&#xff0c;允许客户指明文件…

flask中写一个基础的sqlHelper类

写一个SQLHelper类&#xff1a; from flask_sqlalchemy import SQLAlchemydb SQLAlchemy()class SQLHelper:staticmethoddef add(record):db.session.add(record)return SQLHelper.session_commit()staticmethoddef add_all(records):db.session.add_all(records)return SQLH…

FFmepg视频解码

1 前言 上一篇文章<FFmpeg下载安装及Windows开发环境设置>介绍了FFmpeg的下载安装及环境配置&#xff0c;本文介绍最简单的FFmpeg视频解码示例。 2 视频解码过程 本文只讨论视频解码。 FFmpeg视频解码的过程比较简单&#xff0c;实际就4步&#xff1a; 打开媒体流获取…

Meta-Transformer:基于Transformer的多模态感知,融合Token化与共享编码

论文标题&#xff1a;Meta-Transformer: A Unified Framework for Multimodal Learning 论文地址&#xff1a;https://arxiv.org/pdf/2307.10802.pdf 这里写目录标题 引言基于Transformer的多模态发展Meta-Transformer框架预备知识数据到序列如何分词&#xff08;Data-to-Seq…

Clion一个项目内多个main

创建单个main文件时 这样的文件不属于任何项目&#xff0c;每个文件都有自己的exe

全网最强,Jmeter接口测试-SHA256加密接口测试(详细实战)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 接口文档如下&…

【福建事业单位-语言理解】04 逻辑填空-病句-歧义

【福建事业单位-语言理解】04 逻辑填空-病句-歧义 一、逻辑填空1.1 词的辨析1.1.1词义侧重1.1.2固定搭配1.1.3程度轻重1.1.4 感情色彩总结 1.2语境分析&#xff08;关联关系&#xff09;1.2.1 转折1.2.2递进1.2.3并列1.2.4因果关系 1.3语境分析&#xff08;对应关系&#xff09…

中国工商银行长春分行 聚焦融合互促 让机关党建更有活力

党的十八大以来&#xff0c;中国工商银行长春分行党委认真落实中央部署&#xff0c;立足金融工作政治性、人民性的基本原则&#xff0c;深刻把握机关党建的要点、着力破解难点、大力打造亮点&#xff0c;围绕“党建”模式&#xff0c;将党建融入经营管理各个方面&#xff0c;使…