guhongwei 4 years ago
parent
commit
e28c87ac98

+ 159 - 0
src/components/upload-file.vue

@@ -0,0 +1,159 @@
+<template>
+  <div id="upload-file">
+    <el-upload
+      ref="uploadFile"
+      :action="url"
+      :before-remove="handleRemove"
+      :before-upload="changeFile"
+      :on-success="onSuccess"
+      :limit="limit"
+      multiple
+      :on-exceed="outLimit"
+      :file-list="fileList"
+      :on-preview="onPreview"
+      :on-remove="remove"
+      list-type="text"
+    >
+      <el-button slot="trigger" size="small" type="primary">选取文件</el-button>
+      <div slot="tip" class="el-upload__tip">{{ desc === undefined ? '只能上传不超过2MB的文件' : desc }}</div>
+    </el-upload>
+    <el-dialog title="查看" :visible.sync="dialog" center :append-to-body="true">
+      <el-row>
+        <el-form :model="disObject" label-position="left" label-width="auto">
+          <el-form-item label="文件名" prop="name">
+            <el-input v-model="disObject.name" placeholder="请输入新文件名"></el-input>
+          </el-form-item>
+          <el-image style="width: 100%; height: 100%" :src="disObject.url" fit="scale-down" v-if="disObject.type === 'pic'"></el-image>
+        </el-form>
+      </el-row>
+      <template #footer>
+        <el-row type="flex" align="middle" justify="center">
+          <el-col :span="6"><el-button type="info" @click="dialog = false">返回 </el-button></el-col>
+          <el-col :span="6" v-if="disObject.type === 'file'"><el-button @click="downLoad(disObject.url)">下载文件</el-button></el-col>
+          <el-col :span="6"><el-button type="primary" @click="changeName()">修改文件名</el-button></el-col>
+        </el-row>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import _ from 'lodash';
+export default {
+  name: 'upload-file',
+  props: {
+    url: { type: null },
+    type: { type: String },
+    limit: { type: Number },
+    data: { type: null },
+    desc: { type: String },
+  },
+  components: {},
+  data: () => ({
+    fileList: [],
+    dialog: false,
+    disObject: {},
+    test: {},
+  }),
+  created() {
+    if (this.data) {
+      this.defalutProcess(this.data);
+    }
+  },
+  computed: {},
+  watch: {
+    data: {
+      handler(val) {
+        this.defalutProcess(val);
+      },
+    },
+  },
+  methods: {
+    handleRemove(file) {
+      return true;
+    },
+    changeFile(file, fileList) {
+      let size = file.size / 1024 / 1024;
+      if (size > 10) {
+        return false;
+      }
+    },
+    onSuccess(response, file, fileList) {
+      //将文件整理好传回父组件
+      this.$emit('upload', { type: this.type, data: response });
+    },
+    outLimit() {
+      this.$message.error(`只允许上传${this.limit}个文件`);
+    },
+    onPreview(file) {
+      let duplicate = JSON.parse(JSON.stringify(file));
+      let res = this.isPic(duplicate.url);
+      if (this.isPic(duplicate.url)) {
+        this.disObject.type = 'pic';
+      } else {
+        this.disObject.type = 'file';
+      }
+      this.disObject.url = duplicate.url;
+      this.dialog = true;
+    },
+    defalutProcess(val) {
+      if (typeof val === 'object' && _.get(val, length) !== undefined) {
+        let newArr = [];
+        val.map(item => {
+          let object = {};
+          object.name = item.name;
+          object.url = item.uri;
+          newArr.push(object);
+        });
+        this.$set(this, `fileList`, newArr);
+      } else if (typeof val === 'object' && _.get(val, length) === undefined) {
+        let object = {};
+        object.name = val.name;
+        object.url = val.uri;
+        this.$set(this, `fileList`, []);
+      } else {
+        this.$set(this, `fileList`, [{ name: '附件', url: val }]);
+      }
+    },
+    isPic(url) {
+      if (url.includes('.jpg')) {
+        return true;
+      }
+      if (url.includes('.bmp')) {
+        return true;
+      }
+      if (url.includes('.jpge')) {
+        return true;
+      }
+      if (url.includes('.png')) {
+        return true;
+      }
+      if (url.includes('.gif')) {
+        return true;
+      }
+      if (url.includes('.mp4')) {
+        return true;
+      }
+      if (url.includes('.rmvb')) {
+        return true;
+      }
+      if (url.includes('.AVI')) {
+        return true;
+      }
+    },
+    downLoad(url) {
+      window.open(url);
+    },
+    changeName() {
+      this.$emit('changeName', { type: this.type, data: this.disObject });
+      this.dialog = false;
+      this.disObject = {};
+    },
+    remove(file) {
+      this.$emit('toRemove', { type: this.type, data: file });
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped></style>

+ 14 - 0
src/router/index.js

@@ -420,6 +420,20 @@ const train = [
     meta: { title: '学生成绩' },
     component: () => import('@/views/train-plan/score.vue'),
   },
+  // 08-22
+  // 课程培训
+  {
+    path: '/trainVidoe/index',
+    name: 'trainVidoe_index',
+    meta: { title: '课程培训' },
+    component: () => import('@/views/trainVidoe/index.vue'),
+  },
+  {
+    path: '/trainVidoe/detail',
+    name: 'trainVidoe_detail',
+    meta: { title: '课程培训' },
+    component: () => import('@/views/trainVidoe/detail.vue'),
+  },
 ];
 
 const statistics = [

+ 2 - 0
src/store/index.js

@@ -38,6 +38,7 @@ import liveroom from '@frame/store/liveroom';
 import answerapply from '@frame/store/answerapply';
 import chatroom from '@frame/store/chatroom';
 import answerchat from '@frame/store/answerchat';
+import trainvideo from '@frame/store/trainvideo';
 import * as ustate from '@frame/store/user/state';
 import * as umutations from '@frame/store/user/mutations';
 import * as dostate from '@frame/store/setting/state';
@@ -88,6 +89,7 @@ export default new Vuex.Store({
     answerapply,
     chatroom,
     answerchat,
+    trainvideo,
   },
   state: { ...ustate, ...dostate },
   mutations: { ...umutations, ...domutations },

+ 183 - 0
src/views/trainVidoe/detail.vue

@@ -0,0 +1,183 @@
+<template>
+  <div id="detail">
+    <detail-frame :title="mainTitle" returns="/trainVidoe/index">
+      <data-form :data="info" :fields="fields" :rules="rules" @save="handleSave" :isNew="isNew">
+        <template #options="{item}">
+          <template v-if="item.model === 'subid'">
+            <el-option v-for="(i, index) in subjectList" :key="index" :label="i.name" :value="i.id"></el-option>
+          </template>
+        </template>
+        <template #radios="{item}">
+          <template v-if="item.model === 'touser'">
+            <el-radio label="0">所有人</el-radio>
+            <el-radio label="1">教师</el-radio>
+            <el-radio label="2">学生</el-radio>
+            <el-radio label="3">班主任</el-radio>
+          </template>
+          <template v-if="item.model === 'status'">
+            <el-radio label="0">待审核</el-radio>
+            <el-radio label="1">审核通过</el-radio>
+            <el-radio label="2">审核拒绝</el-radio>
+          </template>
+        </template>
+        <template #custom="{item}">
+          <template v-if="item.model == 'url'">
+            <upload-file
+              :url="`/files/trainVidoe/upload`"
+              desc="只能上传不超过2MB文件"
+              :limit="100"
+              @upload="uploadSuccess"
+              @changeName="changeName"
+              @toRemove="toRemove"
+              type="url"
+              :data="info.url"
+            ></upload-file>
+          </template>
+        </template>
+      </data-form>
+    </detail-frame>
+  </div>
+</template>
+
+<script>
+import _ from 'lodash';
+import uploadFile from '@/components/upload-file.vue';
+import detailFrame from '@frame/layout/admin/detail-frame';
+import dataForm from '@frame/components/form';
+import { mapState, createNamespacedHelpers } from 'vuex';
+const { mapActions: subject } = createNamespacedHelpers('subject');
+const { mapActions: trainvideo } = createNamespacedHelpers('trainvideo');
+export default {
+  metaInfo: { title: '课程培训' },
+  name: 'detail',
+  props: {},
+  components: {
+    detailFrame,
+    dataForm,
+    uploadFile,
+  },
+  data: function() {
+    return {
+      info: {},
+      fields: [
+        { label: '科目', required: true, model: 'subid', type: 'select' },
+        { label: '视频地址', model: 'url', custom: true },
+        { label: '面向对象', model: 'touser', type: 'radio' },
+      ],
+      rules: {
+        subid: [{ required: true, message: '请选择科目名称' }],
+        reason: [{ required: true, message: '请输入申请说明' }],
+      },
+      // 科目列表
+      subjectList: [],
+    };
+  },
+  created() {
+    if (this.id) {
+      this.fields.push({ label: '状态', required: true, model: 'status', type: 'radio' });
+    }
+    this.getOtherList();
+    if (this.id) {
+      this.search();
+    }
+  },
+  methods: {
+    ...subject({ getSubjectList: 'query' }),
+    ...trainvideo(['fetch', 'create', 'update']),
+    // 查詢詳情
+    async search() {
+      let res = await this.fetch(this.id);
+      if (this.$checkRes(res)) {
+        this.$set(this, `info`, res.data);
+      }
+    },
+    // 查询科目
+    async getOtherList() {
+      let res = await this.getSubjectList();
+      if (this.$checkRes(res)) {
+        this.$set(this, `subjectList`, res.data);
+      }
+    },
+    // 添加
+    async handleSave({ isNew, data }) {
+      let res;
+      let msg;
+      let subject = this.subjectList.find(f => f.id == data.subid);
+      if (subject) {
+        data.subname = subject.name;
+      }
+      data.status = '1';
+      if (isNew) {
+        res = await this.create(data);
+        msg = `${this.keyWord}添加成功`;
+      } else {
+        res = await this.update(data);
+        msg = `${this.keyWord}修改成功`;
+      }
+      if (this.$checkRes(res, msg)) this.$router.push({ path: '/trainVidoe/index' });
+    },
+    uploadSuccess({ type, data }) {
+      if (type !== 'url') {
+        let arr = _.get(this.info, type);
+        if (arr !== undefined) {
+          this.info[type].push({ name: data.name, uri: data.uri });
+        } else {
+          let newArr = [{ name: data.name, uri: data.uri }];
+          this.$set(this.info, `${type}`, newArr);
+        }
+      } else {
+        this.$set(this.info, `${type}`, data.uri);
+      }
+    },
+    toRemove({ type, data }) {
+      if (type !== 'url') {
+        let arr = _.get(this.info, type);
+        let newArr = arr.filter(item => item.uri !== data.url);
+        this.$set(this.info, `${type}`, newArr);
+      }
+    },
+    changeName({ type, data }) {
+      console.log(type, data);
+      let newObject = { name: data.name, uri: data.url };
+      let list = _.get(this.info, type);
+      if (list.length > 0) {
+        let index = _.findIndex(list, item => {
+          return item.uri === data.url;
+        });
+        this.$set(list, `${index}`, newObject);
+      }
+    },
+  },
+  computed: {
+    ...mapState(['user']),
+    id() {
+      return this.$route.query.id;
+    },
+    isNew() {
+      return this.$route.query.id ? false : true;
+    },
+    mainTitle() {
+      let meta = this.$route.meta;
+      let main = meta.title || '';
+      let sub = meta.sub || '';
+      return `${main}${sub}`;
+    },
+    keyWord() {
+      let meta = this.$route.meta;
+      let main = meta.title || '';
+      return main;
+    },
+  },
+  watch: {
+    isNew: {
+      immediate: true,
+      handler(val) {
+        if (val) this.loading = false;
+        else this.search();
+      },
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped></style>

+ 105 - 0
src/views/trainVidoe/index.vue

@@ -0,0 +1,105 @@
+<template>
+  <div id="index">
+    <list-frame :title="mainTitle" @query="search" :total="total" :needFilter="false" @add="$router.push({ path: '/trainVidoe/detail' })">
+      <data-table :fields="fields" :data="list" :opera="opera" @check="toCheck" @delete="toDelete"></data-table>
+    </list-frame>
+  </div>
+</template>
+
+<script>
+import listFrame from '@frame/layout/admin/list-frame';
+import dataTable from '@frame/components/data-table';
+import { mapState, createNamespacedHelpers } from 'vuex';
+const { mapActions: trainvideo } = createNamespacedHelpers('trainvideo');
+const { mapActions: subject } = createNamespacedHelpers('subject');
+export default {
+  metaInfo: { title: '课程培训' },
+  name: 'index',
+  props: {},
+  components: {
+    listFrame,
+    dataTable,
+  },
+  data: function() {
+    return {
+      opera: [
+        {
+          label: '编辑',
+          icon: 'el-icon-check',
+          method: 'check',
+          display: item => {
+            return item.status === '0' ? true : false;
+          },
+        },
+        {
+          label: '删除',
+          icon: 'el-icon-delete',
+          method: 'delete',
+        },
+      ],
+      fields: [
+        { label: '课程名称', prop: 'subname' },
+        { label: '教师', prop: 'teacher' },
+        { label: '面向对象', prop: 'touser', format: i => (i === '0' ? '所有人' : i === '1' ? '教师' : i === '2' ? '学生' : i === '3' ? '班主任' : '暂无') },
+        { label: '状态', prop: 'status', format: i => (i === '0' ? '待审核' : i === '1' ? '审核通过' : '审核拒绝') },
+      ],
+      list: [],
+      total: 0,
+      // 查询科目
+      subjectList: [],
+    };
+  },
+  created() {
+    this.getOtherList();
+    this.search();
+  },
+  methods: {
+    ...subject({ getSubjectList: 'query' }),
+    ...trainvideo(['query', 'delete']),
+    // 查询科目
+    async getOtherList() {
+      let res = await this.getSubjectList();
+      if (this.$checkRes(res)) {
+        this.$set(this, `subjectList`, res.data);
+      }
+    },
+    // 查询列表
+    async search({ skip, limit = 10, ...info } = {}) {
+      const res = await this.query({ skip, limit, ...info });
+      if (this.$checkRes(res)) this.$set(this, `list`, res.data);
+      this.$set(this, `total`, res.total);
+    },
+    // 审核
+    toCheck({ data }) {
+      this.$router.push({ path: '/trainVidoe/detail', query: { id: data.id } });
+    },
+    // 删除
+    async toDelete({ data }) {
+      let res = await this.delete(data.id);
+      if (this.$checkRes(res)) {
+        this.$message({
+          message: '刪除信息成功',
+          type: 'success',
+        });
+        this.search();
+      }
+    },
+  },
+  computed: {
+    ...mapState(['user']),
+    mainTitle() {
+      let meta = this.$route.meta;
+      let main = meta.title || '';
+      let sub = meta.sub || '';
+      return `${main}${sub}`;
+    },
+    keyWord() {
+      let meta = this.$route.meta;
+      let main = meta.title || '';
+      return main;
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped></style>