vue 自定义el-table穿梭框功能

news2024/12/20 0:45:17

一、需求描述:前段时间接到一个需求是点击做一个类似穿梭框的表格点击选中功能,弹框的左边是全部数据展示,点击表格行数据可以选中自动增加到右边的已选框,并且可以手动删除、重置选中数据。点击确定后到展示到主页面,被选中的数据打开弹框不能再次选择。

二、界面展示:功能如下图所示:

  • 主页面没有选中的数据时,展示如下:

  •  弹框页面,展示如下:

  •  选中后主页面的数据显示如下:

  •  再次点击添加学生成绩按钮,之前选中数据不可再点击,如下图:

 三、代码实现:

  1. 首页面表格主键是orderId ,主页面代码:
    <div class="content-box">
      <div class="table-title flex-between">
        <span>学生成绩信息</span> 
        <div style="text-align:end">
          <el-button plain type="primary" @click="delSomeMedic()">批量删除</el-button>
          <el-button type="primary" @click="addMedic()">添加学生成绩</el-button>
        </div>
      </div>
      <div class="single-table">
        <el-table ref="table" size="mini" height="100%" :data="tableData.adrDrugInfos" :header-cell-style="{background: '#fff',height:'40px'}" border
        @selection-change="handleSelectionChange">
          <el-table-column type="selection" width="40"> </el-table-column>
          <el-table-column prop="dose" label="姓名" show-overflow-tooltip></el-table-column>
          <el-table-column prop="suspectedConcomitant" label="是否住校" show-overflow-tooltip width="100">
            <template #default="scope">
              <span v-if="scope.row.suspectedConcomitant == '1'">住校生</span>
              <span v-if="scope.row.suspectedConcomitant == '2'">非住校生</span>
            </template>
          </el-table-column>
          <el-table-column prop="doseUnit" label="数学" show-overflow-tooltip></el-table-column>
          <el-table-column prop="frequency" label="语文" show-overflow-tooltip></el-table-column>
          <el-table-column prop="routeName" label="英语" show-overflow-tooltip></el-table-column>
          <el-table-column prop="reasonForUse" label="备注" show-overflow-tooltip></el-table-column>
          <el-table-column label="操作" header-align="center" width="200" align="center" fixed="right">
              <template slot-scope="scope">
                <el-button size="small" style="color: #409eff; padding: 0" type="text" @click="editMedic(false,scope.row)">成绩详情</el-button>
                <el-button size="small" style="color: #409eff; padding: 0" type="text" @click="editMedic(true,scope.row)">编辑</el-button>
                <el-button size="small" style="color: #409eff; padding: 0" type="text" @click="delMedic(scope.row)">删除</el-button>
              </template>
            </el-table-column>
        </el-table>
      </div>
    </div>
    
    //-----------------------------------------------------------------------------
    // 新增学生成绩信息
        addMedic() {
          if (this.tableData.healthEventId == '') {
            return this.$message.warning('请先选择学生')
          } else {
            this.$refs.addMedicDialog.open(
              this.tableData.adrDrugInfos,
              this.tableData.healthEventId,
              this.tableData.visitType
            )
          }
        },
        // 删除学生成绩信息
        delMedic(row) {
          this.$Confirm({ type: 'delete' })
            .then((e) => {
              this.tableData.adrDrugInfos.map((item, index) => {
                if (item.orderId == row.orderId) {
                  this.tableData.adrDrugInfos.splice(index, 1)
                  this.$message.success('删除成功!')
                }
              })
            })
            .catch((err) => {
              console.log(err)
            })
        },
    //选中学生成绩信息数据
        handleSelectionChange(val) {
          this.selectedMedicData = val
        },
    // 批量学生成绩信息
        delSomeMedic() {
          if (this.selectedMedicData.length <= 0) {
            return this.$message.warning('请先选择学生成绩信息')
          }
          this.$Confirm({ type: 'delete' })
            .then((e) => {
              this.selectedMedicData.forEach((val) => {
                this.tableData.adrDrugInfos.forEach((v, i) => {
                  if (val.orderId == v.orderId) {
                    this.tableData.adrDrugInfos.splice(i, 1)
                    this.$message.success('删除成功!')
                  }
                })
              })
            })
            .catch((err) => {
              console.log(err)
            })
        },
    // 选择学生成绩信息回显
        getMedicalData(data) {
          data.forEach((item) => {
            this.tableData.adrDrugInfos.push({
              orderId: item.orderId||'',
              suspectedConcomitant: item.suspectedConcomitant||'',
              dose: item.onceDosage||'',
              doseUnit: item.dosageunitName||'',
              frequency: item.freqDesc||'',
              routeName: item.defaultUsageCode||'',
              formName: item.drugForm||'',
              reasonForUse: item.reasonForUse||'',
            })
          })
        },
  2. 弹框页面数据主键是orderId,弹框页面代码:
    <template>
      <el-dialog
        title="添加学生成绩"
        :visible.sync="dialogVisible"
        :close-on-click-modal="false"
        @close="close"
        append-to-body
        top="10vh !important"
        width="90%"
      >
        <div class="box-wrapper">
          <div class="single-table-container left-table">
            <div class="search-form-wrapper">
              <div class="title">学生成绩列表</div>
              <div class="seach_list">
                <el-input
                  prefix-icon="el-icon-search"
                  placeholder="学生姓名"
                  v-model="searchForm.onceDosage"
                  size="mini"
                  clearable
                ></el-input>
                <el-date-picker
                  v-model="dateTime"
                  type="daterange"
                  value-format="yyyy-MM-dd"
                  format="yyyy-MM-dd"
                  range-separator="—"
                  @change="changeDateTime"
                  start-placeholder="在校开始时间"
                  end-placeholder="在校结束时间"
                >
                </el-date-picker>
                <el-button type="primary" size="mini" @click="searchTable"
                  >查询</el-button
                >
              </div>
            </div>
            <div class="single-table">
              <el-table
                ref="leftTable"
                v-loading="tableLoading"
                size="mini"
                height="370px"
                :data="tableData"
                stripe
                row-key="orderId"
                tooltip-effect="dark"
                :header-cell-style="{
                  background: '#f5f7fa',
                  fontWeight: 'bold',
                  color: '#303133'
                }"
                border
                @selection-change="handleSelectionChange"
                @row-click="handleClickTableRow"
              >
                <el-table-column
                  type="selection"
                  width="40"
                  :reserve-selection="true"
                  :selectable="handleSelected"
                ></el-table-column>
                <el-table-column
                  type="index"
                  header-align="center"
                  align="center"
                  label="序号"
                  width="50"
                ></el-table-column>
                <el-table-column
                  prop="onceDosage"
                  label="姓名"
                  show-overflow-tooltip
                  width="120"
                  :formatter="formartTableField"
                ></el-table-column>
                <el-table-column
                  prop="startDateTime"
                  label="在校开始时间"
                  show-overflow-tooltip
                  width="100"
                  :formatter="formartTableField"
                ></el-table-column>
                <el-table-column
                  prop="stopDateTime"
                  label="在校结束时间"
                  show-overflow-tooltip
                  width="100"
                  :formatter="formartTableField"
                ></el-table-column>
                <el-table-column
                  prop="dosageunitName"
                  label="数学"
                  show-overflow-tooltip
                  :formatter="formartTableField"
                ></el-table-column>
                <el-table-column
                  prop="freqDesc"
                  label="语文"
                  show-overflow-tooltip
                  :formatter="formartTableField"
                ></el-table-column>
                <el-table-column
                  prop="defaultUsageCode"
                  label="英语"
                  show-overflow-tooltip
                  :formatter="formartTableField"
                ></el-table-column>
              </el-table>
            </div>
            <div class="table-pagination">
              <el-pagination
                class="pagination"
                @current-change="handleCurrentChange"
                :current-page="pages.pageIndex"
                :page-size="pages.pageSize"
                layout="total,prev, pager, next"
                :total="pages.total"
              ></el-pagination>
            </div>
          </div>
          <div class="single-table-container right-table">
            <div class="search-form-wrapper">
              <div class="title">已选学生</div>
            </div>
            <div class="single-table">
              <el-form
                :model="selectedForm"
                ref="selectedForm"
                :rules="selectedForm.rules"
              >
                <el-table
                  ref="rightTable"
                  size="mini"
                  height="410px"
                  :data="selectedForm.selectedData"
                  stripe
                  tooltip-effect="dark"
                  :header-cell-style="{
                    background: '#f5f7fa',
                    fontWeight: 'bold',
                    color: '#303133'
                  }"
                  border
                >
                  <el-table-column
                    type="index"
                    header-align="center"
                    align="center"
                    label="序号"
                    width="50"
                  ></el-table-column>
                  <el-table-column
                    prop="onceDosage"
                    label="姓名"
                    width="120"
                    show-overflow-tooltip
                  ></el-table-column>
                  <el-table-column
                    label="住校生/非住校生"
                    show-overflow-tooltip
                    width="188"
                  >
                    <template #default="scope">
                      <el-form-item
                        :prop="
                          'selectedData.' + scope.$index + '.suspectedConcomitant'
                        "
                      >
                        <el-radio-group
                          v-model="scope.row.suspectedConcomitant"
                          size="mini"
                        >
                          <el-radio label="1">住校生</el-radio>
                          <el-radio label="2">非住校生</el-radio>
                        </el-radio-group>
                      </el-form-item>
                    </template>
                  </el-table-column>
                  <el-table-column label="选择原因" show-overflow-tooltip>
                    <template #default="scope">
                      <el-form-item
                        :prop="'selectedData.' + scope.$index + '.reasonForUse'"
                        :rules="selectedForm.rules.reasonForUse"
                      >
                        <el-input
                          placeholder="请输入"
                          v-model="scope.row.reasonForUse"
                          clearable
                        ></el-input>
                      </el-form-item>
                    </template>
                  </el-table-column>
                  <el-table-column
                    label="操作"
                    header-align="center"
                    align="center"
                    width="80"
                  >
                    <template slot-scope="scope">
                      <el-button
                        size="small"
                        style="color: #409eff; padding: 0"
                        type="text"
                        @click="del(scope.row)"
                        >删除</el-button
                      >
                    </template>
                  </el-table-column>
                </el-table>
              </el-form>
            </div>
          </div>
        </div>
        <span slot="footer" class="dialog-footer">
          <el-button @click="reset">重置</el-button>
          <el-button :loading="btn_loading" type="primary" @click="submit"
            >确认</el-button
          >
        </span>
      </el-dialog>
    </template>
    <script>
    import { getAdviceRec } from '@/api/adr/report-manage-service'
    
    export default {
      components: {},
      data() {
        return {
          dialogVisible: false,
          tableLoading: false,
          btn_loading: false,
          healthEventId: '',
          visitType: '',
          searchForm: {
            onceDosage: '',
            startDateTime: '',
            stopDateTime: ''
          },
          dateTime: [],
          selectedForm: {
            selectedData: [],
            rules: {
              reasonForUse: [
                { required: true, message: '请输入选中学生的原因', trigger: 'blur' }
              ]
            }
          },
          pages: {
            pageIndex: 1,
            pageSize: 10,
            total: 0
          },
          tableData: [
            {
              orderId: 1,
              onceDosage: '张三',
              startDateTime: '2020-01-01',
              stopDateTime: '2023-01-01',
              dosageunitName: '98',
              freqDesc: '95',
              defaultUsageCode: '99'
            },
            {
              orderId: 2,
              onceDosage: '李四',
              startDateTime: '2020-01-01',
              stopDateTime: '2023-05-01',
              dosageunitName: '100',
              freqDesc: '92',
              defaultUsageCode: '95'
            },
            {
              orderId: 3,
              onceDosage: '王五',
              startDateTime: '2021-01-01',
              stopDateTime: '2023-02-01',
              dosageunitName: '98',
              freqDesc: '95',
              defaultUsageCode: '100'
            },
            {
              orderId: 4,
              onceDosage: '赵六',
              startDateTime: '2021-06-01',
              stopDateTime: '2024-01-01',
              dosageunitName: '98',
              freqDesc: '100',
              defaultUsageCode: '90'
            }
          ],
          pSelectedData: [] // 父级数据
        }
      },
      methods: {
        open(data, healthEventId, visitType) {
          this.healthEventId = healthEventId || ''
          this.visitType = visitType || ''
          this.dialogVisible = true
          if (!!data && data.length > 0) {
            this.pSelectedData = data
          } else {
            this.pSelectedData = []
          }
          this.initTable()
        },
        initTable() {
          this.tableLoading = true
          let params = {
            current: this.pages.pageIndex,
            size: this.pages.pageSize,
            visitType: this.visitType,
            healthEventId: this.healthEventId,
            startDateTime: this.searchForm.startDateTime,
            stopDateTime: this.searchForm.stopDateTime,
            onceDosage: this.searchForm.onceDosage
          }
          params = useKyyDelNullProperty(params)
          getAdviceRec(params)
            .then((res) => {
              if (res.code == 200) {
                this.tableLoading = false
                this.tableData = res.result.records
                this.pages.total = res.result.total
                // 默认在校
                this.tableData.forEach((item) => {
                  this.$set(item, 'suspectedConcomitant', '1')
                })
                // 固定对齐表格
                this.$nextTick(() => {
                  this.$refs.leftTable.doLayout()
                })
              } else {
                this.$message.error(`错误:${res.message}`)
              }
            })
            .catch((err) => {})
          setTimeout(() => {
            this.tableLoading = false
          }, 5000)
        },
        handleSelectionChange(val) {
          this.selectedForm.selectedData = val
        },
        close() {
          this.dialogVisible = false
          this.searchForm.onceDosage = ''
          this.searchForm.startDateTime = ''
          this.searchForm.stopDateTime = ''
          this.reset()
        },
        reset() {
          this.btn_loading = false
          this.$refs.leftTable.clearSelection()
        },
        // 删除
        del(row) {
          // 取消选中
          this.selectedForm.selectedData.map((item, index) => {
            if (item.orderId == row.orderId) {
              this.selectedForm.selectedData.splice(index, 1)
              this.$refs.leftTable.toggleRowSelection(row, false)
            }
          })
        },
        // 点击行勾选数据
        handleClickTableRow(row, event, column) {
          if (!this.handleSelected(row)) return false
          if (this.selectedForm.selectedData.length > 0) {
            // 如果结果数组不为空,判断所选的这条是否在结果数组里
            if (
              JSON.stringify(this.selectedForm.selectedData).indexOf(
                JSON.stringify(row.orderId)
              ) == -1
            ) {
              this.selectedForm.selectedData.push(row)
              this.$refs.leftTable.toggleRowSelection(row, true)
            } else {
              // 取消选中
              this.selectedForm.selectedData.map((item, index) => {
                if (item.orderId == row.orderId) {
                  this.selectedForm.selectedData.splice(index, 1)
                  this.$refs.leftTable.toggleRowSelection(row, false)
                }
              })
            }
          } else {
            this.selectedForm.selectedData.push(row)
            this.$refs.leftTable.toggleRowSelection(row, true)
          }
        },
        // 已选数据不可再选,通过比较orderId 是否一致
        handleSelected(row, index) {
          if (this.pSelectedData?.length > 0) {
            if (
              this.pSelectedData.some((el) => {
                return el.orderId == row.orderId
              })
            ) {
              return false
            } else {
              return true
            }
          } else {
            return true
          }
        },
        submit() {
          this.btn_loading = true
          if (this.selectedForm.selectedData.length > 0) {
            this.$refs.selectedForm.validate(async (valid) => {
              if (valid) {
                this.$emit('getMedicalData', this.selectedForm.selectedData)
                this.close()
                this.$message.success('操作成功')
              } else {
                return this.$message.warning('请输入选择原因')
              }
            })
          } else {
            this.$message.warning('请选择要添加的学生成绩信息')
          }
          this.btn_loading = false
        },
        // 分页栏
        handleCurrentChange(val) {
          this.pages.pageIndex = val
          this.initTable()
        },
        formartTableField(row, column, cellValue, index) {
          if (cellValue) {
            return cellValue
          }
          return '-'
        },
        changeDateTime(data) {
          if (data) {
            this.searchForm.startDateTime = data[0]
            this.searchForm.stopDateTime = data[1]
          } else {
            this.searchForm.startDateTime = ''
            this.searchForm.stopDateTime = ''
          }
        },
        // 查询
        searchTable() {
          if (!!this.dateTime && this.dateTime.length > 0) {
            this.searchForm.startDateTime = this.dateTime[0]
            this.searchForm.stopDateTime = this.dateTime[1]
          }
          this.pages.pageIndex = 1
          this.initTable()
        }
      }
    }
    </script>
    <style lang="scss" scoped>
    .box-wrapper {
      font-size: 14px;
      display: flex;
      justify-content: space-between;
      .left-table {
        width: 51%;
        padding: 0;
      }
      .right-table {
        width: 48%;
        padding: 0;
        .el-input {
          width: 100%;
        }
        .el-form-item {
          margin: 0;
        }
        .el-radio-group {
          :deep(.el-radio) {
            margin-right: 10px;
            .el-radio__label {
              font-size: 12px;
              padding-left: 10px;
            }
          }
        }
      }
    }
    </style>
    

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

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

相关文章

深入理解Linux虚拟内存管理(四)

系列文章目录 Linux 内核设计与实现 深入理解 Linux 内核&#xff08;一&#xff09; 深入理解 Linux 内核&#xff08;二&#xff09; Linux 设备驱动程序&#xff08;一&#xff09; Linux 设备驱动程序&#xff08;二&#xff09; Linux 设备驱动程序&#xff08;三&#xf…

精选一线企业最佳生产实践,《Apache Doris 用户案例集》重磅发布!

过去的一年势必是 Apache Doris 在发展历程中有着浓墨重彩的一年&#xff0c;凭借对技术创新的执着与用户体验的追求&#xff0c;Apache Doris 已俘获全球范围内超过 2000 家企业的认可&#xff0c;拥有了极为广泛的用户规模、在企业实时数据分析的多种场景中得到广泛应用&…

热门AI通用大模型对比盘点(附论文)

今天我来和大家聊聊通用大模型&#xff0c;垂直领域大模型等整理完了再和大家分享。大家可以先关注一下我&#xff0c;有更新可以立马看见。 本文文末有整理好的通用大模型论文&#xff0c;都是各个大模型的原始论文&#xff0c;强烈建议大模型方向的同学&#xff0c;或者对大…

突破软件交付不可能三角,企业级无代码如何实现卓越交付?

一、VUCA时代下项目交付面临的困境 软件开发或软件项目交付一直以来都存在着“不可能三角”&#xff0c;即成本、效率和质量三者难以兼得。 交付周期长、成本高、满意度低等一直是行业内长期存在的现象&#xff0c;甚至软件交付双方都习以为常。传统项目管理与软件实施过程难…

Niagara—— Texture Sample 与 Particle Subuv 区别

一&#xff0c;Texture Sample 此节点是最基本的采样节点&#xff0c;依据UV坐标来采样Texture&#xff1b; MipValueMode&#xff0c;设置采样的Mipmap Level&#xff1b; None&#xff0c;根据当前Texture大小和物理缩放&#xff0c;自动选择合适的 Mipmap Level &#xff1b…

行为型设计模式03-观察者模式

&#x1f9d1;‍&#x1f4bb;作者&#xff1a;猫十二懿 &#x1f3e1;账号&#xff1a;CSDN 、个人博客 、Github &#x1f38a;公众号&#xff1a;猫十二懿 观察者模式 1、观察者模式介绍 观察者模式是一种行为型设计模式&#xff0c;也被称为发布-订阅模式&#xff0c;它定…

Hive学习---4、函数(单行函数、高级聚合函数、炸裂函数、窗口函数)

1、函数 1.1 函数简介 Hive会将常用的逻辑封装成函数给用户进行使用&#xff0c;类似java中的函数。 好处&#xff1a;避免用户反复写逻辑&#xff0c;可以直接拿来使用 重点&#xff1a;用户需要知道函数叫什么&#xff0c;能做什么 Hive提供了大量的内置函数&#xff0c;按…

《相信》读后感

近日阅读了蔡磊的《相信》一书&#xff0c;蔡磊先生曾是京东集团副总裁&#xff0c;中国电子发票的推动者。上天给了他优越的智商条件&#xff0c;从上学到工作&#xff0c;前半生几乎顺风顺水、获誉无数&#xff0c;却在初为人父、本该享受家庭幸福的时候&#xff0c;接到突患…

Python字典及用法详解

Python中的字典&#xff08;Dictionary&#xff09;是一种无序、可变的数据类型&#xff0c;用于存储键&#xff08;Key&#xff09;和值&#xff08;Value&#xff09;之间的映射关系。字典是一种高效的数据结构&#xff0c;可以用于快速查找和检索数据。 1.创建字典 可以使…

MobileViT详解:轻型,通用,移动友好的视觉变压器

MobileViT详解&#xff1a;轻型&#xff0c;通用&#xff0c;移动友好的视觉变压器 0. 引言1. 网络结构2. 模型详解2.1 MobileViT Block2.1.1 Local representations2.1.2 Transformers as Convolutions (global representations)2.1.3 Fusion 2.2 MV2 3. 简化版理解4. 总结 0.…

Ubuntu系统搭建FTP服务器

Ubuntu 系统版本&#xff1a;Ubuntu 22.04.2 LTS 安装 vsftpd 软件包 sudo apt-get update sudo apt-get install vsftpd查看版本&#xff0c;验证是否安装成功&#xff1a;vsftpd -v 配置文件 以下是我翻译后的默认配置文件&#xff08;地址 /etc/vsftpd.conf&#xff09;&a…

[NOI2009] 描边

题目描述 小 Z 是一位杰出的数学家。聪明的他特别喜欢研究一些数学小问题。 有一天&#xff0c;他在一张纸上选择了 n 个点&#xff0c;并用铅笔将它们两两连接起来&#xff0c;构成 (&#xfffd;−1)22n(n−1)​ 条线段。由于铅笔很细&#xff0c;可以认为这些线段的宽度为…

ROS:参数的使用与编程方法

目录 一、参数模型二、 创建功能包三、参数命令行的使用(rosparam)四、使用程序来使用参数&#xff08;C&#xff09;4.1创建代码4.2编译4.3运行 一、参数模型 在ROS Master中&#xff0c;存在一个参数服务器&#xff08;Parameter Server&#xff09;&#xff0c;它是一个全局…

Python高光谱遥感数据处理与机器学习实践技术丨Matlab高光谱遥感数据处理与混合像元分解

目录 Python高光谱遥感数据处理与机器学习实践技术 第一章 高光谱基础 第二章 高光谱开发基础&#xff08;Python&#xff09; 第三章 高光谱机器学习技术&#xff08;python&#xff09; 第四章 典型案例操作实践 Matlab 高光谱遥感数据处理与混合像元分解 第一章 理论…

java SSM 互助旅游管理系统myeclipse开发mysql数据库springMVC模式java编程计算机网页设计

一、源码特点 java SSM 互助旅游管理系统是一套完善的web设计系统&#xff08;系统采用SSM框架进行设计开发&#xff0c;springspringMVCmybatis&#xff09;&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采…

预制菜进击万亿市场,谁能更快上桌“吃菜”?

文 | 螳螂观察 作者 | 图霖 消费行业很少有可持续的风口&#xff0c;这两年的预制菜算其中一个。 艾媒咨询发布的行业预测显示&#xff0c;2026年我国预制菜市场规模有望达到10720亿元。 过去这一年&#xff0c;武汉、大同等地已相继召开了预制菜相关的产业峰会。峰会规模有…

gismo-3维IGA

文章目录 前言一、简单示例二、gismo-3维IGA3维程序中的几何模型 三、xml文件的理解1、xml文件示例2、gismo中二维示例文件-一个曲面&#xff08;简单&#xff09; 四、三维程序中xml文件的理解三维几何模型边界信息 五、三维程序运行细化四次细化5次 总结 #pic_center 前言 只…

C#读写FDX-B ISO11784/85协议动物标签源码

一个FDX-B ISO11784/85协议动物标签内包括了以下信息&#xff1a; 11位的前导码&#xff1b;38位的SN序号&#xff1b;10位国家代码&#xff1b;1位data block标识&#xff1b;14位保留位&#xff1b;1位Animal动物标识&#xff1b;以上64位数据的crc16ccitt校验码&#xff0c…

短视频矩阵源码系统打包.源码

Masayl是一款基于区块链技术的去中心化应用程序开发平台&#xff0c;可帮助开发者快速、便捷地创建去中心化应用程序。Masayl拥有丰富的API和SDK&#xff0c;为开发者们提供了支持。此外&#xff0c;Masayl还采用了高效的智能合约技术&#xff0c;确保应用程序的稳定、安全和高…

项目集管理—项目集治理

一、概述 项目集治理是实现和执行项目集决策&#xff0c;为支持项目集而制定实践&#xff0c;并维持项目集监督的绩效领域。 本章包括&#xff1a; 项目集治理实践项目集治理角色项目集治理设计与实施 项目集治理包括为了满足组织战略和运营目标的要求&#xff0c;对项目集实…