瀏覽代碼

项目资源列表

natasha 1 周之前
父節點
當前提交
970652baf3

+ 11 - 0
src/api/list.js

@@ -63,3 +63,14 @@ export function PageQueryMyProjectYSJBookList_Leader(data) {
 export function PageQueryYSJBookList_OrgManager(data) {
   return http.post(`${process.env.VUE_APP_EepServer}?MethodName=page_query-PageQueryYSJBookList_OrgManager`, data);
 }
+
+/**
+ * @description 分页查询项目资源列表
+ * @param {object} data
+ * @param {number} data.page_capacity - 每页容量
+ * @param {number} data.cur_page - 当前查询页码
+ */
+export function PageQueryProjectResourceList(data) {
+  return http.post(`${process.env.VUE_APP_EepServer}?MethodName=page_query-PageQueryProjectResourceList`, data);
+}
+

+ 1 - 0
src/icons/svg/sort-down.svg

@@ -0,0 +1 @@
+<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1750567045702" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6581" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M508.693 67.52L175.467 445.44H844.8z" fill="#a4a4a4" p-id="6582"></path><path d="M508.693 952.747L175.467 574.72H844.8z" fill="#008be6" p-id="6583"></path></svg>

+ 1 - 0
src/icons/svg/sort-up.svg

@@ -0,0 +1 @@
+<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1750567056722" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6730" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M508.693 67.52L175.467 445.44H844.8z" fill="#008be6" p-id="6731"></path><path d="M508.693 952.747L175.467 574.72H844.8z" fill="#A4A4A4" p-id="6732"></path></svg>

+ 0 - 2
src/views/book/courseware/preview/components/h5_games/H5GamesPreview.vue

@@ -37,8 +37,6 @@ export default {
   mounted() {},
   methods: {
     initData() {
-      this.games_url =
-        'https://file-kf.helxsoft.cn/CSFileStore/003/00301/D-TVLONKXT3IRWYEMCJK/F-702XHW9VPAU8QVS8NF/index.html';
       this.data.games_list.forEach((item) => {
         H5StartupFile({ file_id: item.file_id, index_file_name: 'index.html' }).then((res) => {
           this.games_url = res.file_url;

+ 293 - 14
src/views/personal_workbench/project/ProductionResourceManage.vue

@@ -3,27 +3,249 @@
     <MenuPage cur-key="project" />
 
     <div class="production-resource-main">
-      <div class="textbook-container"></div>
-      <div class="textbook-chapter"></div>
+      <div class="textbook-container">
+        <MenuTree :id="select_node" :node-list="node_list" @selectNode="selectNode" />
+      </div>
+      <div class="textbook-chapter">
+        <div class="textbook-chapter__header">
+          <div class="courseware">
+            <div class="operator flex">
+              <span class="link" @click="handleAdd">上传</span>
+              <span class="link" @click="handleDelete">删除</span>
+              <span class="link" @click="handleSetInfo">设置信息</span>
+              <span class="link" @click="handleChangeFile">更换文件</span>
+              <span class="link" @click="handleMoveFile">移动文件</span>
+              <span class="link" @click="handlePersonal">设置项目成员资源使用权限</span>
+              <span class="link" @click="$router.push({ path: `/personal_workbench/project` })">返回项目列表</span>
+            </div>
+          </div>
+        </div>
+        <div class="search-box">
+          <div class="search-left">
+            <label
+              class="label-btn"
+              :class="[type_index === index ? 'active' : '']"
+              v-for="(item, index) in type_list"
+              :key="index"
+              @click="changeType(index)"
+              >{{ item.label }}</label
+            >
+            <el-input v-model="search_content"></el-input>
+            <el-button type="primary" @click="queryList">查询</el-button>
+          </div>
+          <div class="search-right">
+            <label>排序:</label>
+            <el-select v-model="sort_value" placeholder="请选择"
+              ><el-option v-for="item in sort_list" :key="item.value" :label="item.label" :value="item.value">
+              </el-option
+            ></el-select>
+            <SvgIcon
+              :icon-class="isDesc ? 'sort-down' : 'sort-up'"
+              size="16"
+              style="cursor: pointer"
+              @click="changeSort"
+            />
+          </div>
+        </div>
+        <div class="sources-box" :style="{ height: height + 'px' }" v-if="height > 0"></div>
+        <PaginationPage ref="pagination" :total="total" @getList="queryList" />
+      </div>
     </div>
   </div>
 </template>
 
 <script>
-import {} from '@/api/book';
 import MenuPage from '../common/menu.vue';
+import MenuTree from './components/MenuTree.vue';
+import { ChapterGetBookChapterStruct } from '@/api/book';
+import { GetProjectBaseInfo } from '@/api/project';
+import PaginationPage from '@/components/PaginationPage.vue';
+import { PageQueryProjectResourceList } from '@/api/list';
 
 export default {
   name: 'ProjectResourceManager',
-  components: { MenuPage },
+  components: { MenuPage, MenuTree, PaginationPage },
   data() {
     return {
       book_id: this.$route.params.id,
+      node_list: [],
+      select_node: '',
+      project_info: {}, // 项目基本信息
+      type_list: [
+        {
+          value: 0,
+          label: '图片',
+        },
+        {
+          value: 1,
+          label: '音频',
+        },
+        {
+          value: 2,
+          label: '视频',
+        },
+        {
+          value: 3,
+          label: 'H5 游戏',
+        },
+        {
+          value: 4,
+          label: '3D 模型',
+        },
+      ], // 类型分类
+      type_index: 0, // 类型索引
+      sort_list: [
+        {
+          value: 'name',
+          label: '名称',
+        },
+        {
+          value: 'label',
+          label: '标签',
+        },
+        {
+          value: 'last_modify_time',
+          label: '修改时间',
+        },
+        {
+          value: 'file_size',
+          label: '文件大小',
+        },
+      ], // 排序分类
+      sort_value: '', // 排序值
+      isDesc: false, // 排序是否为倒序
+      select_sources_id: '', // 选中的资源id
+      list: [],
+      total: 0,
+      search_content: '', // 查询内容
+      height: 0,
+      page_capacity: 10,
+      cur_page: 1,
     };
   },
-  created() {},
+  created() {
+    this.getProjectBaseInfo();
+  },
+  mounted() {
+    this.height =
+      document.getElementsByClassName('app-container')[0].clientHeight -
+      document.getElementsByClassName('menu')[0].clientHeight -
+      document.getElementsByClassName('textbook-chapter__header')[0].clientHeight -
+      document.getElementsByClassName('search-box')[0].clientHeight -
+      document.getElementsByClassName('el-pagination')[0].clientHeight -
+      30;
+  },
+  methods: {
+    selectNode(nodeId) {
+      this.select_node = nodeId;
+    },
+    /**
+     * 获取项目基本信息
+     * @param {string} id - 项目ID
+     */
+    getProjectBaseInfo() {
+      GetProjectBaseInfo({ id: this.book_id }).then(({ project_info }) => {
+        this.project_info = project_info;
+        this.getBookChapterStructExpandList(project_info.name);
+      });
+    },
+    /**
+     * 得到教材章节结构展开列表
+     */
+    getBookChapterStructExpandList(name) {
+      ChapterGetBookChapterStruct({
+        book_id: this.book_id,
+        node_deep_mode: 0,
+        is_contain_producer: 'false',
+        is_contain_auditor: 'false',
+      }).then(({ nodes }) => {
+        this.node_list = [
+          {
+            auditor_desc: '',
+            deep: 1,
+            id: '',
+            is_courseware: 'false',
+            is_leaf: 'false',
+            is_leaf_chapter: 'false',
+            level_index: '0',
+            label: name,
+            nodes: nodes,
+            children: nodes,
+          },
+        ];
+        this.handleData(this.node_list[0], 1);
+      });
+    },
+    // 递归
+    handleData(data, nodeIndex) {
+      if (data.nodes) {
+        data.nodes.forEach((item) => {
+          item.label = item.name;
+          item.pid = data.id;
+          item.nodexIndex = nodeIndex;
+          item.isLeaf = item.is_leaf === 'true';
+          if (item.nodes) {
+            item.children = item.nodes;
+            item.lists = item.nodes;
+            this.handleData(item, nodeIndex + 1);
+          }
+        });
+      }
+    },
+    // 上传
+    handleAdd() {},
+    // 删除
+    handleDelete() {},
+    // 设置信息
+    handleSetInfo() {},
+    // 更换文件
+    handleChangeFile() {},
+
+    // 设置项目成员资源使用权限
+    handlePersonal() {},
 
-  methods: {},
+    // 移动文件
+    handleMoveFile() {},
+    // 切换类型
+    changeType(index) {
+      this.type_index = index;
+      this.select_sources_id = '';
+      this.queryList();
+    },
+    // 查询列表
+    queryList(data) {
+      if (data) {
+        this.page_capacity = data.page_capacity;
+        this.cur_page = data.cur_page;
+      } else {
+        this.page_capacity = 10;
+        this.cur_page = 1;
+      }
+
+      let order_column_list = [];
+      if (this.sort_value) {
+        order_column_list = [this.isDesc ? this.sort_value + ':desc' : this.sort_value];
+      }
+      let datas = {
+        page_capacity: this.page_capacity,
+        cur_page: this.cur_page,
+        project_id: this.book_id,
+        book_chapter_node_id: this.select_node,
+        type: this.type_list[this.type_index].value,
+        name_or_label: this.search_content,
+        order_column_list: order_column_list,
+      };
+      PageQueryProjectResourceList(datas).then(({ total_count, resource_list }) => {
+        this.total = total_count;
+        this.list = resource_list;
+      });
+    },
+
+    // 切换排序升序降序
+    changeSort() {
+      this.isDesc = !this.isDesc;
+    },
+  },
 };
 </script>
 
@@ -38,26 +260,83 @@ export default {
     flex: 1;
     width: 100%;
     height: 100%;
+    background: #fff;
     border-top: $border;
 
     .textbook-container {
       display: flex;
       flex-direction: column;
-      width: 450px;
+      width: 320px;
+      height: calc(100vh - 120px);
+      overflow: auto;
       border-right: $border;
-
-      .textbook-list {
-        display: flex;
-        flex-direction: column;
-        height: calc(100vh - 184px);
-        overflow: auto;
-      }
     }
 
     .textbook-chapter {
       display: flex;
       flex: 1;
       flex-direction: column;
+
+      &__header {
+        display: flex;
+        align-items: center;
+        justify-content: flex-end;
+        height: 40px;
+        padding: 6px 4px;
+        margin-bottom: 5px;
+        background-color: #fff;
+        border-bottom: 1px solid #e5e6eb;
+
+        .operator {
+          display: flex;
+          flex: 1;
+          justify-content: flex-end;
+
+          .link {
+            + .link {
+              &::before {
+                margin-right: 8px;
+                color: #999;
+                content: '|';
+              }
+            }
+          }
+        }
+      }
+
+      .search-box {
+        display: flex;
+        justify-content: space-between;
+        padding: 5px;
+
+        .search-left {
+          display: flex;
+          flex-flow: wrap;
+          gap: 5px;
+          align-items: center;
+        }
+
+        .label-btn {
+          padding: 5px 10px;
+          cursor: pointer;
+          background: #ebebeb;
+          border-radius: 4px;
+
+          &.active {
+            color: #f90;
+            background: #ffefd6;
+          }
+        }
+
+        .el-input,
+        .el-select {
+          width: 120px;
+        }
+      }
+    }
+
+    .sources-box {
+      overflow: auto;
     }
   }
 }

+ 144 - 0
src/views/personal_workbench/project/components/MenuTree.vue

@@ -0,0 +1,144 @@
+<template>
+  <div class="menu-list">
+    <el-tree highlight-current :data="nodeList" :props="defaultProps" @node-click="handleNodeClick">
+      <div class="custom-tree-node" slot-scope="{ node }">
+        <div
+          :class="[
+            'tree-box-item',
+            curSelectId == node.data.id ? 'tree-box-item-active' : '',
+            node.data.children ? 'tree-box-item-father' : '',
+          ]"
+        >
+          <span style="margin-right: 10px">{{ node.label }}</span>
+        </div>
+      </div>
+    </el-tree>
+  </div>
+</template>
+
+<script>
+import { isTrue } from '@/utils/common';
+
+export default {
+  name: 'MenuTree',
+  props: {
+    nodeList: {
+      type: Array,
+      required: true,
+    },
+    id: {
+      type: String,
+      default: '',
+    },
+    bookName: {
+      type: String,
+      default: '',
+    },
+  },
+  watch: {
+    nodeList: {
+      handler(val) {},
+      immediate: true,
+    },
+  },
+  data() {
+    return {
+      isTrue,
+      curSelectId: this.id || '',
+      defaultProps: {
+        children: 'children',
+        label: 'label',
+        nodeKey: 'id',
+        isLeaf: (data, node) => {
+          if (data.is_leaf === 'true') {
+            // 实体门店 叶子结点 不展示icon
+            return true;
+          }
+        },
+      },
+    };
+  },
+  created() {},
+  methods: {
+    /**
+     * 选择节点
+     * @param {string} nodeId - 节点ID
+     * @param {boolean} isLeaf - 是否是叶子节点
+     */
+    selectNode(nodeId, isLeaf) {
+      if (!isLeaf) return;
+      if (this.curSelectId === nodeId) return;
+      this.curSelectId = nodeId;
+      this.$emit('selectNode', nodeId);
+    },
+    /**
+     * 计算章节名称样式
+     * @param {number} deep - 节点深度
+     * @param {boolean} isLeaf - 是否是叶子节点
+     * @returns {Object} - 样式对象
+     */
+    computedNameStyle(deep, isLeaf) {
+      return {
+        'padding-left': `${(deep - 1) * 16}px`,
+        cursor: isLeaf ? 'pointer' : 'auto',
+      };
+    },
+    handleNodeClick(data) {
+      // if (data.isLeaf) {
+      // this.nodeName = data.name;
+      this.selectNode(data.id);
+      this.curSelectId = data.id;
+      // }
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.menu-list {
+  :deep .el-tree {
+    background: transparent;
+
+    .el-tree-node__expand-icon {
+      font-size: 16px;
+    }
+  }
+
+  .tree-box-item-active {
+    color: #f90;
+  }
+
+  .custom-tree-node {
+    display: block !important;
+    width: 100%;
+    height: 100%;
+    color: #2c2c2c;
+  }
+
+  :deep .el-tree-node__content,
+  :deep .custom-tree-node {
+    height: auto;
+  }
+
+  .el-tree--highlight-current .el-tree-node.is-current > .el-tree-node__content {
+    background: none;
+  }
+
+  .tree-box-item {
+    align-items: center;
+    overflow: hidden;
+    font-weight: 400;
+    line-height: 38px;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+    -webkit-box-align: center;
+    -ms-flex-align: center;
+
+    &-father {
+      font-weight: bold;
+    }
+  }
+}
+</style>
+
+<style lang="scss"></style>