|
@@ -0,0 +1,873 @@
|
|
|
+<template>
|
|
|
+ <div class="create-train-container">
|
|
|
+ <vuescroll>
|
|
|
+ <div class="create-form-wrap">
|
|
|
+ <!-- 上一步 -->
|
|
|
+ <div v-show="step > 0" class="to-train-mgt last-step" @click="lastStep()">
|
|
|
+ <span class="step-icon-wrap">
|
|
|
+ <Icon type="ios-arrow-back" size="24" color="white" />
|
|
|
+ </span>
|
|
|
+ <p style="margin-top:2px">上一步</p>
|
|
|
+ </div>
|
|
|
+ <!-- 下一步 -->
|
|
|
+ <div v-show="step < 3" class="to-train-mgt next-step" @click="nextStep()">
|
|
|
+ <span class="step-icon-wrap">
|
|
|
+ <Icon type="ios-arrow-forward" size="24" color="white" />
|
|
|
+ </span>
|
|
|
+ <p style="margin-top:2px">下一步</p>
|
|
|
+ </div>
|
|
|
+ <Steps :current="step" class="step-wrap">
|
|
|
+ <Step title="基础信息" @click.native="step = 0"></Step>
|
|
|
+ <Step title="详情信息"></Step>
|
|
|
+ <Step title="高级设置"></Step>
|
|
|
+ <Step title="发布活动"></Step>
|
|
|
+ </Steps>
|
|
|
+ <Form ref="baseInfo" :model="baseInfo" :rules="baseRule" :label-width="100" class="train-form" label-colon v-show="step == 0">
|
|
|
+ <h1>基础信息</h1>
|
|
|
+ <FormItem label="类型" prop="type" style="margin-top:80px">
|
|
|
+ <Select v-model="baseInfo.type">
|
|
|
+ <Option v-for="item in typeList" :value="item.value" :key="item.value">{{ item.label }}</Option>
|
|
|
+ </Select>
|
|
|
+ </FormItem>
|
|
|
+ <FormItem label="学时" prop="hour" style="margin-top:30px">
|
|
|
+ <InputNumber :max="10" :min="1" style="width:100%" v-model="baseInfo.hour" placeholder="请输入学时"></InputNumber>
|
|
|
+ </FormItem>
|
|
|
+ <FormItem label="对象" prop="target" style="margin-top:30px">
|
|
|
+ <el-cascader size="small" :show-all-levels="false" clearable filterable v-model="baseInfo.target" :options="csOptions" :props="props" @change="treeChange" style="width:100%;">
|
|
|
+ <template slot="empty">
|
|
|
+ <p>
|
|
|
+ 学校暂未分组,勾选学校则为学校所有老师
|
|
|
+ </p>
|
|
|
+ </template>
|
|
|
+ </el-cascader>
|
|
|
+ </FormItem>
|
|
|
+ </Form>
|
|
|
+ <Form ref="trainInfo" :model="trainInfo" :rules="trainRule" :label-width="100" class="train-form" label-colon v-show="step == 1">
|
|
|
+ <h1>详细信息</h1>
|
|
|
+ <FormItem label="上传封面">
|
|
|
+ <Upload type="drag" action="/blob/public-upload" :format="['jpg','png','jpeg']" :on-format-error="handleFormatError" :on-success="success">
|
|
|
+ <div style="padding: 10px 0">
|
|
|
+ <Icon type="ios-cloud-upload" size="52" style="color: #3399ff"></Icon>
|
|
|
+ <p>1、格式支持:jpg、png、jpeg,大小不超过3M;</p>
|
|
|
+ <p>2、图片最佳比例400 * 300;</p>
|
|
|
+ </div>
|
|
|
+ </Upload>
|
|
|
+ </FormItem>
|
|
|
+ <FormItem label="主讲人" prop="presenter">
|
|
|
+ <Input v-model="trainInfo.presenter" placeholder="请输入主讲人"></Input>
|
|
|
+ </FormItem>
|
|
|
+ <FormItem label="培训主题" prop="topic">
|
|
|
+ <Input v-model="trainInfo.topic" placeholder="请输入培训主题"></Input>
|
|
|
+ </FormItem>
|
|
|
+ <FormItem label="培训时间" prop="time">
|
|
|
+ <DatePicker :editable="false" @on-change="getTimeInfo" type="datetimerange" format="yyyy-MM-dd HH:mm" placeholder="请设置培训时间" style="width: 500px"></DatePicker>
|
|
|
+ </FormItem>
|
|
|
+ <FormItem label="培训地点" prop="address">
|
|
|
+ <Input v-model="trainInfo.address" placeholder="请输入培训地点"></Input>
|
|
|
+ </FormItem>
|
|
|
+ <FormItem label="培训内容">
|
|
|
+ <Input v-model="trainInfo.desc" type="textarea" placeholder="请输入活动描述" maxlength="200" show-word-limit :autosize="{minRows: 5, maxRows: 8}"></Input>
|
|
|
+ </FormItem>
|
|
|
+ </Form>
|
|
|
+ <Form ref="highInfo" :model="trainInfo" :rules="trainRule" :label-width="100" class="train-form" label-colon v-show="step == 2">
|
|
|
+ <h1>高级设置</h1>
|
|
|
+ <CheckboxGroup v-model="trainInfo.setting" @on-change="initStatus">
|
|
|
+ <!-- <Checkbox label="notice" class="check-item">
|
|
|
+ <span>发送通知</span>
|
|
|
+ </Checkbox> -->
|
|
|
+ <Checkbox label="sign" class="check-item">
|
|
|
+ <span>现场签到</span>
|
|
|
+ </Checkbox>
|
|
|
+ <Checkbox label="hw" class="check-item">
|
|
|
+ <span>布置作业</span>
|
|
|
+ </Checkbox>
|
|
|
+ <Checkbox label="survey" class="check-item">
|
|
|
+ <span>问卷反馈</span>
|
|
|
+ </Checkbox>
|
|
|
+ <Checkbox label="exam" class="check-item">
|
|
|
+ <span>评测反馈</span>
|
|
|
+ </Checkbox>
|
|
|
+ </CheckboxGroup>
|
|
|
+ <Tabs v-model="tabName">
|
|
|
+ <TabPane v-for="(item,index) in tabListShow" :key="index" :label="item.label" :name="item.name">
|
|
|
+ <div v-if="item.name == 'hw'">
|
|
|
+ <FormItem label="作业名称" prop="hwName">
|
|
|
+ <Input v-model="trainInfo.hwName" placeholder="请输入作业名称"></Input>
|
|
|
+ </FormItem>
|
|
|
+ <FormItem label="作业内容" prop="hwDesc">
|
|
|
+ <Input v-model="trainInfo.hwDesc" type="textarea" placeholder="请输入活动描述" maxlength="200" show-word-limit :autosize="{minRows: 6, maxRows: 8}"></Input>
|
|
|
+ </FormItem>
|
|
|
+ <FormItem label="截止时间" prop="hwTime">
|
|
|
+ <DatePicker type="datetime" v-model="trainInfo.hwTime" placeholder="作业截止时间" format="yyyy-MM-dd HH:mm" style="width: 100%" @on-change="getHwTime"></DatePicker>
|
|
|
+ </FormItem>
|
|
|
+ </div>
|
|
|
+ <div v-else-if="item.name == 'survey'">
|
|
|
+ <FormItem label="问卷名称" prop="quName">
|
|
|
+ <Input v-model="trainInfo.quName" placeholder="请输入问卷名称"></Input>
|
|
|
+ </FormItem>
|
|
|
+ <FormItem label="问卷描述" prop="quDesc">
|
|
|
+ <Input v-model="trainInfo.quDesc" type="textarea" placeholder="请输入活动描述" maxlength="200" show-word-limit :autosize="{minRows: 6, maxRows: 8}"></Input>
|
|
|
+ </FormItem>
|
|
|
+ <!-- 问卷题目区域 -->
|
|
|
+ <FormItem label="问卷题目" prop="items">
|
|
|
+ <div class="qn-box">
|
|
|
+ <div class="qn-item" v-for="(item,index) in trainInfo.quItems" :key="index">
|
|
|
+ <div class="qn-item-content">
|
|
|
+ <!-- 题干 -->
|
|
|
+ <p class="qn-stem">
|
|
|
+ <span style="color: red;" v-show="item.required">* </span>
|
|
|
+ <span>{{ index + 1 }}. </span>
|
|
|
+ <span v-html="item.stemContent" style="display: inline-block;"></span>
|
|
|
+ <span>( {{ getQuType(item.type) }} )</span>
|
|
|
+ </p>
|
|
|
+ <!-- 单选题-选项 -->
|
|
|
+ <RadioGroup v-if="item.type === 'single' || item.type === 'judge'">
|
|
|
+ <Radio v-for="(option,optionIndex) in item.optionsContent" :key="optionIndex">
|
|
|
+ <span v-html="option.value" style="display: inline-block;"></span>
|
|
|
+ </Radio>
|
|
|
+ </RadioGroup>
|
|
|
+ <!-- 多选题-选项 -->
|
|
|
+ <CheckboxGroup v-if="item.type === 'multiple'">
|
|
|
+ <Checkbox v-for="(option,optionIndex) in item.optionsContent" :key="optionIndex">
|
|
|
+ <span v-html="option.value" style="display: inline-block;"></span>
|
|
|
+ </Checkbox>
|
|
|
+ </CheckboxGroup>
|
|
|
+ <!-- 工具栏 -->
|
|
|
+ <div class="qn-tools">
|
|
|
+ <!-- <div class="qn-tools-item" @click="onItemEdit(item,index)">
|
|
|
+ <Icon type="md-create" />
|
|
|
+ <span>{{ $t('survey.questionaire.edit') }}</span>
|
|
|
+ </div> -->
|
|
|
+ <div class="qn-tools-item" @click="onItemDelete(index)">
|
|
|
+ <Icon type="md-trash" />
|
|
|
+ <span>{{ $t('survey.questionaire.remove') }}</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <EmptyData v-show="!trainInfo.quItems" textContent="请添加问卷题目"></EmptyData>
|
|
|
+ </div>
|
|
|
+ <Button type="info" @click="toAddQu">
|
|
|
+ <Icon type="md-add" />
|
|
|
+ 添加题目
|
|
|
+ </Button>
|
|
|
+ </FormItem>
|
|
|
+ </div>
|
|
|
+ <div v-else-if="item.name == 'exam'">
|
|
|
+ <FormItem label="评测名称" prop="examName">
|
|
|
+ <Input v-model="trainInfo.examName" placeholder="请输入评测名称"></Input>
|
|
|
+ </FormItem>
|
|
|
+ <FormItem label="评测描述" prop="examDesc">
|
|
|
+ <Input v-model="trainInfo.examDesc" type="textarea" placeholder="请输入评测描述" maxlength="200" show-word-limit :autosize="{minRows: 6, maxRows: 8}"></Input>
|
|
|
+ </FormItem>
|
|
|
+ <!-- 评测题目区域 -->
|
|
|
+ <FormItem label="评测题目" prop="items">
|
|
|
+ <div class="qn-box">
|
|
|
+ <div class="qn-item" v-for="(item,index) in trainInfo.examItems" :key="index">
|
|
|
+ <div class="qn-item-content">
|
|
|
+ <!-- 题干 -->
|
|
|
+ <p class="qn-stem">
|
|
|
+ <span style="color: red;" v-show="item.required">* </span>
|
|
|
+ <span>{{ index + 1 }}. </span>
|
|
|
+ <span v-html="item.stemContent" style="display: inline-block;"></span>
|
|
|
+ <span>( {{ getQuType(item.type) }} )</span>
|
|
|
+ </p>
|
|
|
+ <!-- 单选题-选项 -->
|
|
|
+ <RadioGroup v-if="item.type === 'single' || item.type === 'judge'">
|
|
|
+ <Radio disabled v-for="(option,optionIndex) in item.optionsContent" :key="optionIndex">
|
|
|
+ <span v-html="option.value" style="display: inline-block;"></span>
|
|
|
+ </Radio>
|
|
|
+ </RadioGroup>
|
|
|
+ <!-- 多选题-选项 -->
|
|
|
+ <CheckboxGroup v-if="item.type === 'multiple'">
|
|
|
+ <Checkbox disabled v-for="(option,optionIndex) in item.optionsContent" :key="optionIndex">
|
|
|
+ <span v-html="option.value" style="display: inline-block;"></span>
|
|
|
+ </Checkbox>
|
|
|
+ </CheckboxGroup>
|
|
|
+ <!-- 工具栏 -->
|
|
|
+ <div class="qn-tools">
|
|
|
+ <!-- <div class="qn-tools-item" @click="onItemEdit(item,index)">
|
|
|
+ <Icon type="md-create" />
|
|
|
+ <span>{{ $t('survey.questionaire.edit') }}</span>
|
|
|
+ </div> -->
|
|
|
+ <div class="qn-tools-item" @click="onItemDelete(index)">
|
|
|
+ <Icon type="md-trash" />
|
|
|
+ <span>{{ $t('survey.questionaire.remove') }}</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <EmptyData v-show="!trainInfo.quItems" textContent="请添加问卷题目"></EmptyData>
|
|
|
+ </div>
|
|
|
+ <Button type="info" @click="toAddQu">
|
|
|
+ <Icon type="md-add" />
|
|
|
+ 添加题目
|
|
|
+ </Button>
|
|
|
+ </FormItem>
|
|
|
+ </div>
|
|
|
+ </TabPane>
|
|
|
+ </Tabs>
|
|
|
+ </Form>
|
|
|
+ <div class="train-form" v-show="step == 3 && !published">
|
|
|
+ <h1 class="title">
|
|
|
+ {{trainInfo.topic}}
|
|
|
+ <span class="hour">
|
|
|
+ {{baseInfo.hour}}学时
|
|
|
+ </span>
|
|
|
+ </h1>
|
|
|
+ <div class="img-box" :style="{backgroundImage: `url(${trainInfo.img || defImg})`}"></div>
|
|
|
+ <div class="base-info-wrap">
|
|
|
+ <div class="infos">
|
|
|
+ <div class="info-item">
|
|
|
+ <span class="info-label">
|
|
|
+ 主讲老师:
|
|
|
+ </span>
|
|
|
+ <span>
|
|
|
+ {{trainInfo.presenter}}
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
+ <div class="info-item">
|
|
|
+ <span class="info-label">
|
|
|
+ 培训主题:
|
|
|
+ </span>
|
|
|
+ <span>
|
|
|
+ {{trainInfo.topic}}
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
+ <div class="info-item">
|
|
|
+ <span class="info-label">
|
|
|
+ 培训地点:
|
|
|
+ </span>
|
|
|
+ <span>
|
|
|
+ {{trainInfo.address}}
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
+ <div class="info-item">
|
|
|
+ <span class="info-label">
|
|
|
+ 培训时间:
|
|
|
+ </span>
|
|
|
+ <span>
|
|
|
+ {{trainInfo.time.join(' 至 ')}}
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="train-content">
|
|
|
+ <p class="info-item">培训内容:</p>
|
|
|
+ <p>{{trainInfo.desc}}</p>
|
|
|
+ </div>
|
|
|
+ <!-- <Button type="success" class="save-btn" style="margin-left:180px;width:240px;margin-top:60px" @click="lastStep">取消发布</Button> -->
|
|
|
+ <Button type="primary" class="save-btn" style="margin-left:180px;width:240px" @click="publish">确认发布</Button>
|
|
|
+ </div>
|
|
|
+ <div v-show="published">
|
|
|
+ <Icon type="md-checkmark-circle-outline" class="published-icon" />
|
|
|
+ <p class="success-text">
|
|
|
+ 发布成功
|
|
|
+ </p>
|
|
|
+ <p class="link-text" @click="toTrainMgt">查看信息</p>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </vuescroll>
|
|
|
+ <Modal v-model="addQuStatus" title="添加题目" width="700" @on-ok="doSaveItem" class-name="add-item-modal" :loading="modalLoading">
|
|
|
+ <div class="qu-type-select">
|
|
|
+ <template v-for="(item,index) in quTypeList">
|
|
|
+ <span :key="index" v-show="index < 3 || (index == 3 && tabName == 'survey')" :class="['qu-type-select-item', index == activeQuIndex ? 'item-active' : '', ]" @click="activeQuIndex = index">{{ item.label }}</span>
|
|
|
+ </template>
|
|
|
+ <BaseSingle v-if="activeQuIndex == 0" ref="addItem" @onSave="onSave" :needAnswer="tabName == 'exam'"></BaseSingle>
|
|
|
+ <BaseMultiple v-if="activeQuIndex==1" ref="addItem" @onSave="onSave" :needAnswer="tabName == 'exam'"></BaseMultiple>
|
|
|
+ <BaseJudge v-if="activeQuIndex==2" ref="addItem" @onSave="onSave" :needAnswer="tabName == 'exam'"></BaseJudge>
|
|
|
+ <BaseSubjective v-if="activeQuIndex==3 && tabName == 'survey'" ref="addItem" @onSave="onSave"></BaseSubjective>
|
|
|
+ </div>
|
|
|
+ </Modal>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+<script>
|
|
|
+import blobTool from "@/utils/blobTool.js";
|
|
|
+import { mapGetters } from 'vuex'
|
|
|
+import BaseSingle from "@/components/questionnaire/BaseSingle.vue"
|
|
|
+import BaseMultiple from "@/components/questionnaire/BaseMultiple.vue"
|
|
|
+import BaseJudge from "@/components/questionnaire/BaseJudge.vue"
|
|
|
+import BaseSubjective from "@/components/questionnaire/BaseSubjective.vue"
|
|
|
+export default {
|
|
|
+ components: {
|
|
|
+ BaseSingle, BaseMultiple, BaseJudge, BaseSubjective
|
|
|
+ },
|
|
|
+ data() {
|
|
|
+ const hwTimeV = (rule, value, callback) => {
|
|
|
+ console.log(value)
|
|
|
+ if (value) {
|
|
|
+ callback()
|
|
|
+ } else {
|
|
|
+ callback(new Error('请设置截止时间'))
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return {
|
|
|
+ modalLoading: true,
|
|
|
+ props: {
|
|
|
+ multiple: true,
|
|
|
+ value: 'id',
|
|
|
+ label: 'name',
|
|
|
+ // checkStrictly:true,
|
|
|
+ // emitPath:false
|
|
|
+ },
|
|
|
+ csOptions: [],
|
|
|
+ areaId: sessionStorage.getItem('areaId'),
|
|
|
+ tabList: [
|
|
|
+ {
|
|
|
+ name: 'hw',
|
|
|
+ label: '作业设置'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: 'survey',
|
|
|
+ label: '问卷设置'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: 'exam',
|
|
|
+ label: '评测设置'
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ tabListShow: [],
|
|
|
+ surveyList: [],
|
|
|
+ activeQuIndex: 0,
|
|
|
+ addQuStatus: false,
|
|
|
+ quAction: 'create',
|
|
|
+ tabName: 'hw',
|
|
|
+ hwTime: 0,
|
|
|
+ groupData: [],
|
|
|
+ published: false,
|
|
|
+ baseRule: {
|
|
|
+ name: [
|
|
|
+ { required: true, message: '请输入活动名称', trigger: 'change' }
|
|
|
+ ],
|
|
|
+ type: [
|
|
|
+ { required: true, type: 'number', message: '请选择活动类型', trigger: 'change' }
|
|
|
+ ],
|
|
|
+ hour: [
|
|
|
+ { required: true, type: 'number', message: '请输入活动学时', trigger: 'change' }
|
|
|
+ ],
|
|
|
+ target: [
|
|
|
+ { required: true, type: 'array', message: '请选择学习对象', trigger: 'change' }
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ trainRule: {
|
|
|
+ presenter: [
|
|
|
+ { required: true, message: '请输入主讲人', trigger: 'change' }
|
|
|
+ ],
|
|
|
+ topic: [
|
|
|
+ { required: true, message: '请输入培训主题', trigger: 'change' }
|
|
|
+ ],
|
|
|
+ time: [
|
|
|
+ { required: true, type: 'array', message: '请设置培训时间', trigger: 'change' }
|
|
|
+ ],
|
|
|
+ address: [
|
|
|
+ { required: true, message: '请输入培训地点', trigger: 'change' }
|
|
|
+ ],
|
|
|
+ hwName: [
|
|
|
+ { required: true, message: '请输入作业名称', trigger: 'change' }
|
|
|
+ ],
|
|
|
+ hwDesc: [
|
|
|
+ { required: true, message: '请输入作业内容', trigger: 'change' }
|
|
|
+ ],
|
|
|
+ hwType: [
|
|
|
+ { required: true, message: '请设置作业类型', trigger: 'change' }
|
|
|
+ ],
|
|
|
+ hwTime: [
|
|
|
+ { required: true, validator: hwTimeV, trigger: 'change' }
|
|
|
+ ],
|
|
|
+ quName: [
|
|
|
+ { required: true, message: '请输入问卷名称', trigger: 'change' }
|
|
|
+ ],
|
|
|
+ quDesc: [
|
|
|
+ { required: true, message: '请输入问卷描述', trigger: 'change' }
|
|
|
+ ],
|
|
|
+ examName: [
|
|
|
+ { required: true, message: '请输入评测名称', trigger: 'change' }
|
|
|
+ ],
|
|
|
+ examDesc: [
|
|
|
+ { required: true, message: '请输入评测描述', trigger: 'change' }
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ defImg: 'https://www.habook.com.cn/data/editor/images/img/20210429%2001/001.png',
|
|
|
+ step: 0,
|
|
|
+ baseInfo: {
|
|
|
+ name: '',
|
|
|
+ target: [],
|
|
|
+ time: '',
|
|
|
+ hour: 1,
|
|
|
+ type: ''
|
|
|
+ },
|
|
|
+ trainInfo: {
|
|
|
+ img: '',
|
|
|
+ topic: '',
|
|
|
+ startTime: '',
|
|
|
+ endTime: '',
|
|
|
+ time: [],
|
|
|
+ presenter: '',//主讲人
|
|
|
+ address: '',
|
|
|
+ desc: '',
|
|
|
+ setting: [],
|
|
|
+ hwName: '',
|
|
|
+ hwTime: '',
|
|
|
+ hwDesc: '',
|
|
|
+ surveyId: '',
|
|
|
+ quName: '',
|
|
|
+ quDesc: '',
|
|
|
+ quItems: [],
|
|
|
+ examId: '',
|
|
|
+ examName: '',
|
|
|
+ examDesc: '',
|
|
|
+ examItems: []
|
|
|
+ },
|
|
|
+ typeList: [],
|
|
|
+ quTypeList: [
|
|
|
+ {
|
|
|
+ label: '单选题',
|
|
|
+ value: 0,
|
|
|
+ type: 'single'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: '多选题',
|
|
|
+ value: 1,
|
|
|
+ type: 'multiple'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: '判断题',
|
|
|
+ value: 2,
|
|
|
+ type: 'judge'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: '问答题',
|
|
|
+ value: 3,
|
|
|
+ type: 'subjective'
|
|
|
+ }
|
|
|
+
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ },
|
|
|
+ computed: {
|
|
|
+ ...mapGetters({
|
|
|
+ teachers: 'user/getSchoolUserJoined', // 取得已加入此學校的使用者
|
|
|
+ })
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ treeChange(data) {
|
|
|
+ console.log('选择数据', data)
|
|
|
+ },
|
|
|
+ getTargets() {
|
|
|
+ console.log('获取分组信息')
|
|
|
+ this.$api.ability.findAreaGroup({
|
|
|
+ id: this.areaId
|
|
|
+ }).then(
|
|
|
+ res => {
|
|
|
+ console.log(res)
|
|
|
+ if (res.gr && res.gr.length) {
|
|
|
+ this.csOptions = []
|
|
|
+ res.gr.forEach(sItem => {
|
|
|
+ let i = {
|
|
|
+ id: sItem.id,
|
|
|
+ name: sItem.sname,
|
|
|
+ sas: '?' + sItem.sas,
|
|
|
+ url: sItem.uri.substring(0, sItem.uri.lastIndexOf('/')),
|
|
|
+ children: []
|
|
|
+ }
|
|
|
+ sItem.name.forEach(gItem => {
|
|
|
+ i.children.push({
|
|
|
+ id: gItem,
|
|
|
+ name: gItem
|
|
|
+ })
|
|
|
+ })
|
|
|
+ if (!i.children.length) {
|
|
|
+ i.children.push({
|
|
|
+ id: 'default-all',
|
|
|
+ name: '所有老师(未分组)'
|
|
|
+ })
|
|
|
+ }
|
|
|
+ this.csOptions.push(i)
|
|
|
+ })
|
|
|
+ console.log('111', this.csOptions)
|
|
|
+ }
|
|
|
+
|
|
|
+ },
|
|
|
+ err => {
|
|
|
+ console.log(err)
|
|
|
+ }
|
|
|
+ )
|
|
|
+ },
|
|
|
+ onItemDelete(index) {
|
|
|
+ if (this.tabName == 'survey') {
|
|
|
+ this.trainInfo.quItems.splice(index, 1)
|
|
|
+ } else if (this.tabName == 'exam') {
|
|
|
+ this.trainInfo.examItems.splice(index, 1)
|
|
|
+ }
|
|
|
+ },
|
|
|
+ getQuType(type) {
|
|
|
+ return this.quTypeList.find(item => {
|
|
|
+ return item.type == type
|
|
|
+ }).label
|
|
|
+ },
|
|
|
+ getSimpleText(html) {
|
|
|
+ var r = /<(?!img|video|audio).*?>/g;
|
|
|
+ return html.replace(r, "").replace(/ /g, ' ');
|
|
|
+ },
|
|
|
+ doSaveItem() {
|
|
|
+ this.$refs.addItem.doSave()
|
|
|
+ },
|
|
|
+ handleFormatError(file) {
|
|
|
+ this.$Message.warning('请上传正确格式的封面图片!');
|
|
|
+ },
|
|
|
+ // 检测是否有空选项
|
|
|
+ checkOptionNull(arr) {
|
|
|
+ let flag = true
|
|
|
+ for (let i = 0; i < arr.length; i++) {
|
|
|
+ if (this.getSimpleText(arr[i].value) === '') {
|
|
|
+ flag = false
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return flag
|
|
|
+ },
|
|
|
+ onSave(item) {
|
|
|
+ console.log('题目数据:', item)
|
|
|
+ //检查信息是否完整
|
|
|
+ if (!this.getSimpleText(item.stemContent) || !this.checkOptionNull(item.optionsContent)) {
|
|
|
+ this.$Message.warning(this.$t('survey.questionaire.noCompleteTip'))
|
|
|
+ this.modalLoading = false
|
|
|
+ setTimeout(() => {
|
|
|
+ this.modalLoading = true
|
|
|
+ }, 0)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if (!item.id) {
|
|
|
+ item.id = this.$jsFn.uuid()
|
|
|
+ item.type = this.quTypeList[this.activeQuIndex].type
|
|
|
+ if (this.tabName == 'survey') {
|
|
|
+ this.trainInfo.quItems.push(item)
|
|
|
+ } else if (this.tabName == 'exam') {
|
|
|
+ this.trainInfo.examItems.push(item)
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ let index = this.trainInfo.quItems.findIndex(i => {
|
|
|
+ return i.id == item.id
|
|
|
+ })
|
|
|
+ if (index > -1) {
|
|
|
+ if (this.tabName == 'survey') {
|
|
|
+ this.trainInfo.quItems.splice(index, 1, item)
|
|
|
+ } else if (this.tabName == 'exam') {
|
|
|
+ this.trainInfo.examItems.splice(index, 1, item)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 初始化数据
|
|
|
+ this.activeQuIndex = -1
|
|
|
+ setTimeout(() => {
|
|
|
+ this.activeQuIndex = 0
|
|
|
+ }, 0)
|
|
|
+ },
|
|
|
+ toAddQu() {
|
|
|
+ this.addQuStatus = true
|
|
|
+ },
|
|
|
+ initStatus(data) {
|
|
|
+ this.tabListShow = this.tabList.filter(item => {
|
|
|
+ return data.includes(item.name)
|
|
|
+ })
|
|
|
+ if (this.trainInfo.setting.includes('survey')) {
|
|
|
+ this.quAction = ''
|
|
|
+ } else {
|
|
|
+ this.trainInfo.surveyId = ''
|
|
|
+ }
|
|
|
+ this.tabName = this.trainInfo.setting[data.length - 1] == 'sign' && this.trainInfo.setting.length > 1 ? this.trainInfo.setting[data.length - 2] : this.trainInfo.setting[data.length - 1]
|
|
|
+ },
|
|
|
+ getHwTime(date) {
|
|
|
+ let d = new Date(date)
|
|
|
+ this.hwTime = d.getTime()
|
|
|
+ },
|
|
|
+ //转分组模式数据结构
|
|
|
+ handelGroup() {
|
|
|
+ this.teachers.forEach(item => {
|
|
|
+ item.groupName = item.groupName || '默认组别'
|
|
|
+ })
|
|
|
+ let groupRes = this.$jsFn.groupBy(this.teachers, 'groupName')
|
|
|
+ this.groupData.length = 0
|
|
|
+ for (let index in groupRes) {
|
|
|
+ this.groupData.push({
|
|
|
+ groupName: groupRes[index][0].groupName || '默认组别',
|
|
|
+ groupId: groupRes[index][0].groupId,
|
|
|
+ teachers: groupRes[index]
|
|
|
+ })
|
|
|
+ }
|
|
|
+ this.groupData.sort((a, b) => {
|
|
|
+ return parseInt(a.groupId) - parseInt(b.groupId)
|
|
|
+ })
|
|
|
+ console.log('处理分组数据', this.groupData, groupRes)
|
|
|
+ },
|
|
|
+ toTrainMgt() {
|
|
|
+ this.$router.push({
|
|
|
+ name: 'TrainAreaMgt'
|
|
|
+ })
|
|
|
+ },
|
|
|
+ publish() {
|
|
|
+ let studyInfo = {
|
|
|
+ name: this.trainInfo.topic,
|
|
|
+ settings: this.trainInfo.setting,
|
|
|
+ creatorId: this.$store.state.userInfo.TEAMModelId,
|
|
|
+ type: this.baseInfo.type,
|
|
|
+ hour: this.baseInfo.hour,
|
|
|
+ detail: {
|
|
|
+ startTime: this.trainInfo.startTime,
|
|
|
+ endTime: this.trainInfo.endTime,
|
|
|
+ topic: this.trainInfo.topic,
|
|
|
+ desc: this.trainInfo.desc,
|
|
|
+ address: this.trainInfo.address,
|
|
|
+ presenter: this.trainInfo.presenter,
|
|
|
+ img: this.trainInfo.img,
|
|
|
+ hwName: this.trainInfo.hwName,
|
|
|
+ hwDesc: this.trainInfo.hwDesc,
|
|
|
+ hwTime: this.hwTime
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ let examInfo, surveyInfo
|
|
|
+ if (this.trainInfo.setting.includes('survey')) {
|
|
|
+ surveyInfo = {
|
|
|
+ name: this.trainInfo.quName,
|
|
|
+ description: this.trainInfo.quDesc,
|
|
|
+ creatorId: this.$store.state.userInfo.TEAMModelId,
|
|
|
+ sType: 'train'
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (this.trainInfo.setting.includes('exam')) {
|
|
|
+ examInfo = {
|
|
|
+ name: this.trainInfo.examName,
|
|
|
+ description: this.trainInfo.examDesc,
|
|
|
+ creatorId: this.$store.state.userInfo.TEAMModelId,
|
|
|
+ sType: 'train'
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //处理发布对象
|
|
|
+ let para = this.handleTarget(this.baseInfo.target)
|
|
|
+ let params = {
|
|
|
+ id: this.areaId,
|
|
|
+ para: para,
|
|
|
+ study: studyInfo,
|
|
|
+ exam: examInfo,
|
|
|
+ survey: surveyInfo
|
|
|
+ }
|
|
|
+
|
|
|
+ console.log('数据', this.baseInfo, params)
|
|
|
+ this.$api.train.saveAreaTrain(params).then(
|
|
|
+ res => {
|
|
|
+ this.$Message.success('发布成功')
|
|
|
+ this.published = true
|
|
|
+ // TODO 保存blob
|
|
|
+ // if (res.ids && res.ids.length) {
|
|
|
+ // res.ids.forEach(item => {
|
|
|
+ // let schoolInfo = this.csOptions.find(cs => {
|
|
|
+ // return cs.id == item.school
|
|
|
+ // })
|
|
|
+ let examItems = this.trainInfo.examItems.map(qItem => {
|
|
|
+ return {
|
|
|
+ id: qItem.id,
|
|
|
+ type: qItem.type,
|
|
|
+ question: qItem.stemContent,
|
|
|
+ option: qItem.optionsContent,
|
|
|
+ answer: qItem.answer
|
|
|
+ }
|
|
|
+ })
|
|
|
+ let surveyItems = this.trainInfo.quItems.map(qItem => {
|
|
|
+ return {
|
|
|
+ id: qItem.id,
|
|
|
+ type: qItem.type,
|
|
|
+ question: qItem.stemContent,
|
|
|
+ option: qItem.optionsContent
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ // if (schoolInfo) {
|
|
|
+ // 现在不用每个学校上传资源,直接传到区级容器
|
|
|
+ console.log('返回数据', res)
|
|
|
+ let uri = this.$store.state.user.osblob_uri
|
|
|
+ let sas = this.$store.state.user.osblob_sas
|
|
|
+ let areaBlob = {
|
|
|
+ url: uri.substring(0, uri.lastIndexOf('/')),
|
|
|
+ id: uri.substring(uri.lastIndexOf('/') + 1),
|
|
|
+ sas: '?' + sas
|
|
|
+ }
|
|
|
+ if (this.trainInfo.setting.includes('exam')) {
|
|
|
+ // examInfo.id = item.examId
|
|
|
+ examInfo.id = res.acId
|
|
|
+ // examInfo.school = item.school
|
|
|
+ // this.doUploadBlob(examInfo, examItems, schoolInfo)
|
|
|
+ this.doUploadBlob(examInfo, examItems, areaBlob, 'exam')
|
|
|
+ }
|
|
|
+ if (this.trainInfo.setting.includes('survey')) {
|
|
|
+ // surveyInfo.id = item.surveyId
|
|
|
+ surveyInfo.id = res.acId
|
|
|
+ // surveyInfo.school = item.school
|
|
|
+ // this.doUploadBlob(surveyInfo, surveyItems, schoolInfo)
|
|
|
+ this.doUploadBlob(surveyInfo, surveyItems, areaBlob, 'survey')
|
|
|
+ }
|
|
|
+ // } else {
|
|
|
+ // this.$Message.error('未找到对应学校的授权')
|
|
|
+ // }
|
|
|
+ // })
|
|
|
+ // }
|
|
|
+
|
|
|
+ },
|
|
|
+ err => {
|
|
|
+ this.$Message.error('发布失败')
|
|
|
+ }
|
|
|
+ )
|
|
|
+ },
|
|
|
+ //处理发布对象数据格式
|
|
|
+ handleTarget(treeData) {
|
|
|
+ let d = []
|
|
|
+ treeData.forEach(item => {
|
|
|
+ let s = d.find(i => {
|
|
|
+ return i.sId == item[0]
|
|
|
+ })
|
|
|
+ if (s) {
|
|
|
+ s.gName.push(item[1])
|
|
|
+ } else {
|
|
|
+ d.push({
|
|
|
+ sId: item[0],
|
|
|
+ gName: [item[1]]
|
|
|
+ })
|
|
|
+ }
|
|
|
+ })
|
|
|
+ d.forEach(item => {
|
|
|
+ if (item.gName.includes('default-all')) {
|
|
|
+ item.gName = []
|
|
|
+ }
|
|
|
+ })
|
|
|
+ return d
|
|
|
+ },
|
|
|
+
|
|
|
+ /* 上传单个题目 */
|
|
|
+ /**
|
|
|
+ * @param type survey || exam
|
|
|
+ */
|
|
|
+ async doUploadItems(qnBaseInfo, items, blobInfo, type) {
|
|
|
+ return new Promise(async (resolve, reject) => {
|
|
|
+ let promiseArr = []
|
|
|
+ //初始化Blob
|
|
|
+ let containerClient = new blobTool(
|
|
|
+ blobInfo.url,
|
|
|
+ blobInfo.id,
|
|
|
+ blobInfo.sas,
|
|
|
+ 'school'
|
|
|
+ )
|
|
|
+
|
|
|
+ for (let item of items) {
|
|
|
+ let curId = item.id || this.$tools.guid()
|
|
|
+ promiseArr.push(new Promise(async (r, j) => {
|
|
|
+ let file = new File([JSON.stringify(item)], curId + ".json");
|
|
|
+ try {
|
|
|
+ // 等待上传blob的返回结果
|
|
|
+ // let blobFile = await containerClient.upload(file, `train/${qnBaseInfo.id}`);
|
|
|
+ console.log('11', containerClient)
|
|
|
+ let blobFile = await containerClient.upload(file, `${this.areaId}/${type}/${qnBaseInfo.id}`, {}, true, `${this.areaId}/`);
|
|
|
+ if (blobFile.blob) {
|
|
|
+ r(blobFile.blob)
|
|
|
+ } else {
|
|
|
+ this.$Message.error(this.$t('evaluation.newExercise.uploadErrorTip'));
|
|
|
+ }
|
|
|
+ } catch (e) {
|
|
|
+ console.log(e)
|
|
|
+ this.$Message.error('upload error');
|
|
|
+ }
|
|
|
+ }))
|
|
|
+ }
|
|
|
+ Promise.all(promiseArr).then(result => {
|
|
|
+ resolve(result)
|
|
|
+ })
|
|
|
+ })
|
|
|
+ },
|
|
|
+
|
|
|
+ /* 保存问卷题目到Blob */
|
|
|
+ /***
|
|
|
+ * @param blobInfo : url,name,sas
|
|
|
+ */
|
|
|
+ async doUploadBlob(qnBaseInfo, items, blobInfo, type) {
|
|
|
+ return new Promise(async (r, j) => {
|
|
|
+ console.log('blobInfo', JSON.stringify(blobInfo))
|
|
|
+ let info = JSON.parse(JSON.stringify(qnBaseInfo))
|
|
|
+ let itemUrls = await this.doUploadItems(info, items, blobInfo, type)
|
|
|
+ info.slides = itemUrls
|
|
|
+ //初始化Blob
|
|
|
+ let containerClient = new blobTool(
|
|
|
+ blobInfo.url,
|
|
|
+ blobInfo.id,
|
|
|
+ blobInfo.sas,
|
|
|
+ 'school'
|
|
|
+ );
|
|
|
+ let file = new File([JSON.stringify(info)], "index.json");
|
|
|
+ try {
|
|
|
+ // 等待上传blob的返回结果
|
|
|
+ let blobFile = await containerClient.upload(file, `${this.areaId}/${type}/${qnBaseInfo.id}`, {}, true, `${this.areaId}/`);
|
|
|
+ if (blobFile.blob) {
|
|
|
+ delete info.slides
|
|
|
+ r(blobFile.blob)
|
|
|
+ } else {
|
|
|
+ this.$Message.error(this.$t('evaluation.newExercise.uploadErrorTip'));
|
|
|
+ }
|
|
|
+ } catch (e) {
|
|
|
+ j(e)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+
|
|
|
+ getTimeInfo(data) {
|
|
|
+ this.trainInfo.time = data.filter(item => {
|
|
|
+ return item
|
|
|
+ })
|
|
|
+ if (this.trainInfo.time.length > 1) {
|
|
|
+ this.trainInfo.startTime = (new Date(this.trainInfo.time[0])).getTime()
|
|
|
+ this.trainInfo.endTime = (new Date(this.trainInfo.time[1])).getTime()
|
|
|
+ }
|
|
|
+ },
|
|
|
+ nextStep() {
|
|
|
+ let form = ''
|
|
|
+ switch (this.step) {
|
|
|
+ case 0:
|
|
|
+ form = 'baseInfo'
|
|
|
+ break
|
|
|
+ case 1:
|
|
|
+ form = 'trainInfo'
|
|
|
+ break
|
|
|
+ case 2:
|
|
|
+ form = 'highInfo'
|
|
|
+ break
|
|
|
+ }
|
|
|
+ if (form) {
|
|
|
+ this.$refs[form].validate((valid) => {
|
|
|
+ if (valid) {
|
|
|
+ this.step++
|
|
|
+ } else {
|
|
|
+ this.$Message.error('请完善信息!')
|
|
|
+ }
|
|
|
+ })
|
|
|
+ } else {
|
|
|
+ this.step++
|
|
|
+ }
|
|
|
+ },
|
|
|
+ lastStep() {
|
|
|
+ this.step--
|
|
|
+ },
|
|
|
+ success(response, file, fileList) {
|
|
|
+ this.trainInfo.img = response.url
|
|
|
+ }
|
|
|
+ },
|
|
|
+ created() {
|
|
|
+ this.typeList = this.$GLOBAL.TRAIN_TYPE()
|
|
|
+ this.getTargets()
|
|
|
+ }
|
|
|
+}
|
|
|
+</script>
|
|
|
+<style lang="less" scoped>
|
|
|
+@import "./Create.less";
|
|
|
+</style>
|
|
|
+<style lang="less">
|
|
|
+.add-item-modal .ivu-modal-footer {
|
|
|
+ margin-top: 40px;
|
|
|
+}
|
|
|
+</style>
|