|
@@ -0,0 +1,272 @@
|
|
|
+<template>
|
|
|
+ <div class="dimension-form-container">
|
|
|
+ <Form ref="dimensionForm" :model="dimensionInfo" :rules="ruleValidate" :label-width="80">
|
|
|
+ <FormItem label="维度名称" prop="dimension">
|
|
|
+ <Input v-model="dimensionInfo.dimension" placeholder="请输入维度名称"></Input>
|
|
|
+ </FormItem>
|
|
|
+ <FormItem label="关联科目" prop="subjectBind">
|
|
|
+ <RadioGroup v-model="dimensionInfo.subjectBind">
|
|
|
+ <Radio label="subject_music">音乐</Radio>
|
|
|
+ <Radio label="subject_painting">美术</Radio>
|
|
|
+ </RadioGroup>
|
|
|
+ </FormItem>
|
|
|
+ <FormItem label="关联学段" prop="type">
|
|
|
+ <CheckboxGroup v-model="dimensionInfo.type">
|
|
|
+ <Checkbox v-for="(item,index) in periodKeyList" :key="index" :label="item">{{ $GLOBAL.ART_PERIOD_TYPES[item] }}</Checkbox>
|
|
|
+ </CheckboxGroup>
|
|
|
+ </FormItem>
|
|
|
+ <FormItem label="知识块" prop="blocks">
|
|
|
+ <div class="blocks-wrap">
|
|
|
+ <Tag size="medium" class="block-item" v-for="(block,blockIndex) in dimensionInfo.blocks" :key="blockIndex" closable @on-close="onDeleteBlock(block,blockIndex)" color="geekblue">{{ block }}</Tag>
|
|
|
+ <Tag size="medium" style="cursor: pointer;" @click.native="addBlockModal = true; newBlockName = ''">+ 添加知识块</Tag>
|
|
|
+ </div>
|
|
|
+ </FormItem>
|
|
|
+ <FormItem label="描述信息" prop="desc">
|
|
|
+ <div class="desc-wrap">
|
|
|
+ <Tag size="medium" style="cursor: pointer;" @click.native="onAddDesc">+ 添加描述</Tag>
|
|
|
+ <span class="desc-item" v-for="(desc,descIndex) in dimensionInfo.descs" :key="descIndex" v-if="desc.contents.length" style="margin-left: -6px;margin-top: 10px;">
|
|
|
+ <p class="grade-title">【适用 {{ desc.grades.join(",") }} 年级】</p>
|
|
|
+ <p class="desc-single-item" v-for="(item,index) in desc.contents">
|
|
|
+ {{ item }}
|
|
|
+ <span class="tools">
|
|
|
+ <Icon type="md-create" title="编辑" @click.stop="onDescClick(item,index,desc,descIndex)" />
|
|
|
+ <Icon type="md-trash" title="删除" @click.stop="onDeleteContent(index,desc,descIndex)" />
|
|
|
+ </span>
|
|
|
+ </p>
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
+ </FormItem>
|
|
|
+ <FormItem>
|
|
|
+ <Button type="primary" @click="handleSubmit('dimensionForm')">保存</Button>
|
|
|
+ </FormItem>
|
|
|
+ </Form>
|
|
|
+ <Modal v-model="addBlockModal" title="添加知识块">
|
|
|
+ <Input v-model="newBlockName" placeholder="输入新知识块名称..." />
|
|
|
+ <div slot="footer">
|
|
|
+ <Button type="text" @click="addBlockModal = false">取消</Button>
|
|
|
+ <Button type="primary" @click="onAddBlock">确定</Button>
|
|
|
+ </div>
|
|
|
+ </Modal>
|
|
|
+ <Modal v-model="descModal" :title="isEditDesc ? '编辑描述' : '新增描述'">
|
|
|
+ <p style="margin:10px 0">描述内容</p>
|
|
|
+ <Input v-model="newDescContent" placeholder="输入新的描述内容..." />
|
|
|
+ <p style="margin:10px 0">适用年级</p>
|
|
|
+ <Select v-model="newDescGrades" multiple>
|
|
|
+ <Option v-for="item in gradeList" :value="item" :key="item">{{ item }} 年级</Option>
|
|
|
+ </Select>
|
|
|
+ <div slot="footer">
|
|
|
+ <Button type="text" @click="descModal = false">取消</Button>
|
|
|
+ <Button type="primary" @click="onConfirmAddDesc">确定</Button>
|
|
|
+ </div>
|
|
|
+ </Modal>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+<script>
|
|
|
+export default {
|
|
|
+ props: {
|
|
|
+ dimension: {
|
|
|
+ type: Object,
|
|
|
+ default: () => { }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ isEditDesc: false,
|
|
|
+ addBlockModal: false,
|
|
|
+ descModal: false,
|
|
|
+ newBlockName: '',
|
|
|
+ newDescGrades: [],
|
|
|
+ newDescContent: '',
|
|
|
+ newContentIndex: 0,
|
|
|
+ currentDescIndex: 0,
|
|
|
+ currentDesc: null,
|
|
|
+ periodKeyList: [],
|
|
|
+ periodValueList: [],
|
|
|
+ gradeList: [1, 2, 3, 4, 5, 6, 7, 8, 9],
|
|
|
+ dimensionInfo: {
|
|
|
+ dimension: '',
|
|
|
+ subject: '',
|
|
|
+ subjectBind: '',
|
|
|
+ type: [],
|
|
|
+ blocks: [],
|
|
|
+ desc: []
|
|
|
+ },
|
|
|
+ ruleValidate: {
|
|
|
+ dimension: [
|
|
|
+ { required: true, message: '维度名称不能为空', trigger: 'blur' }
|
|
|
+ ],
|
|
|
+ subjectBind: [
|
|
|
+ { required: true, message: '请选择关联科目', trigger: 'change' }
|
|
|
+ ],
|
|
|
+ type: [
|
|
|
+ { required: true, type: 'array', min: 1, message: '至少选择一个关联学段', trigger: 'change' },
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ created() {
|
|
|
+ this.periodKeyList = Object.keys(this.$GLOBAL.ART_PERIOD_TYPES)
|
|
|
+ this.periodValueList = Object.values(this.$GLOBAL.ART_PERIOD_TYPES)
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ /* 点击新增描述按钮 */
|
|
|
+ onAddDesc() {
|
|
|
+ this.newDescContent = ''
|
|
|
+ this.newDescGrades = []
|
|
|
+ this.descModal = true
|
|
|
+ this.isEditDesc = false
|
|
|
+ },
|
|
|
+ /* 点击描述进行编辑 */
|
|
|
+ onDescClick(content, contentIndex, desc, descIndex) {
|
|
|
+ this.newDescContent = content
|
|
|
+ this.newContentIndex = contentIndex
|
|
|
+ this.newDescGrades = this._.cloneDeep(desc.grades)
|
|
|
+ this.currentDesc = this._.cloneDeep(desc)
|
|
|
+ this.currentDescIndex = descIndex
|
|
|
+ this.descModal = true
|
|
|
+ this.isEditDesc = true
|
|
|
+ },
|
|
|
+ /* 删除描述 */
|
|
|
+ onDeleteContent(contentIndex, desc, descIndex) {
|
|
|
+ this.$Modal.confirm({
|
|
|
+ title: `删除描述`,
|
|
|
+ content: `确认删除该描述吗?`,
|
|
|
+ onOk: () => {
|
|
|
+ desc.contents.splice(contentIndex, 1)
|
|
|
+ this.currentDesc = this._.cloneDeep(desc)
|
|
|
+ this.currentDescIndex = descIndex
|
|
|
+ if (this.currentDesc.contents.length === 0) {
|
|
|
+ this.dimensionInfo.descs.splice(this.currentDescIndex, 1)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ },
|
|
|
+ /* 确认保存描述 */
|
|
|
+ onConfirmAddDesc() {
|
|
|
+ if (!this.newDescContent || this.newDescGrades.length === 0) {
|
|
|
+ this.$Message.warning('内容或关联年级不能为空!')
|
|
|
+ return
|
|
|
+ }
|
|
|
+ // 判断两个数组是否相等
|
|
|
+ let scalarArrayEquals = function (array1, array2) {
|
|
|
+ return array1.length == array2.length && array1.every(function (v, i) { return v === array2[i] });
|
|
|
+ }
|
|
|
+ // 新增描述操作
|
|
|
+ let addNewFn = () => {
|
|
|
+ let hasSameGradeIndex = this.dimensionInfo.descs.findIndex(i => scalarArrayEquals(i.grades, this.newDescGrades))
|
|
|
+ if (hasSameGradeIndex > -1) {
|
|
|
+ this.dimensionInfo.descs[hasSameGradeIndex].contents.push(this.newDescContent)
|
|
|
+ } else {
|
|
|
+ this.dimensionInfo.descs.push({
|
|
|
+ grades: this.newDescGrades,
|
|
|
+ contents: [this.newDescContent]
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+ this.newDescGrades = this.newDescGrades.sort()
|
|
|
+ // 如果是编辑描述
|
|
|
+ if (this.isEditDesc) {
|
|
|
+ let isModifyGrade = !scalarArrayEquals(this.currentDesc.grades, this.newDescGrades)
|
|
|
+ // 如果修改了适用年级
|
|
|
+ if (isModifyGrade) {
|
|
|
+ this.currentDesc.contents.splice(this.newContentIndex, 1)
|
|
|
+ if (this.currentDesc.contents.length === 0) {
|
|
|
+ this.dimensionInfo.descs.splice(this.currentDescIndex, 1)
|
|
|
+ }
|
|
|
+ addNewFn()
|
|
|
+ } else {
|
|
|
+ this.currentDesc.contents[this.newContentIndex] = this.newDescContent
|
|
|
+ this.dimensionInfo.descs[this.currentDescIndex] = this.currentDesc
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ // 如果是新增描述
|
|
|
+ addNewFn()
|
|
|
+ }
|
|
|
+ this.descModal = false
|
|
|
+ this.$Message.success('操作成功')
|
|
|
+ },
|
|
|
+ /* 添加知识块 */
|
|
|
+ onAddBlock() {
|
|
|
+ let isEmpty = !Boolean(this.newBlockName.trim())
|
|
|
+ let isExist = this.dimensionInfo.blocks.includes(this.newBlockName)
|
|
|
+ if (isEmpty) {
|
|
|
+ this.$Message.warning('知识块名称不能为空!')
|
|
|
+ } else if (isExist) {
|
|
|
+ this.$Message.warning('该知识块已存在,请重新输入!')
|
|
|
+ } else {
|
|
|
+ this.dimensionInfo.blocks.push(this.newBlockName)
|
|
|
+ this.addBlockModal = false
|
|
|
+ this.newBlockName = ''
|
|
|
+ }
|
|
|
+ },
|
|
|
+ /* 删除知识块 */
|
|
|
+ onDeleteBlock(block, blockIndex) {
|
|
|
+ this.dimensionInfo.blocks.splice(blockIndex, 1)
|
|
|
+ },
|
|
|
+ /* 提交表单 */
|
|
|
+ handleSubmit(name) {
|
|
|
+ this.$refs[name].validate((valid) => {
|
|
|
+ if (valid) {
|
|
|
+ console.error(this.dimensionInfo)
|
|
|
+ this.dimensionInfo.subject = this.dimensionInfo.subjectBind === 'subject_music' ? '音乐' : '美术'
|
|
|
+ this.$emit('onFinish', this.dimensionInfo)
|
|
|
+ } else {
|
|
|
+ this.$Message.error('请先填写完整!');
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ },
|
|
|
+ watch: {
|
|
|
+ dimension: {
|
|
|
+ handler(n, o) {
|
|
|
+ console.error(n)
|
|
|
+ this.dimensionInfo = this._.cloneDeep(n)
|
|
|
+ },
|
|
|
+ immediate: true,
|
|
|
+ deep: true
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="less" scoped>
|
|
|
+/deep/ .ivu-icon-ios-close {
|
|
|
+ color: #153e73 !important;
|
|
|
+}
|
|
|
+.grade-title {
|
|
|
+ font-weight: bold;
|
|
|
+ color: #5ca2ff;
|
|
|
+}
|
|
|
+
|
|
|
+.desc-single-item {
|
|
|
+ padding: 5px;
|
|
|
+
|
|
|
+ .tools {
|
|
|
+ .ivu-icon {
|
|
|
+ margin-left: 10px;
|
|
|
+ font-size: 16px;
|
|
|
+ color: #fff;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ &:hover {
|
|
|
+ background: #0e4ce27a;
|
|
|
+ color: #fff;
|
|
|
+ cursor: pointer;
|
|
|
+ border-radius: 4px;
|
|
|
+
|
|
|
+ .tools {
|
|
|
+ display: inline-block;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ &::before {
|
|
|
+ content: "";
|
|
|
+ display: inline-block;
|
|
|
+ border: 4px solid #6ca3da;
|
|
|
+ border-radius: 50%;
|
|
|
+ margin-right: 5px;
|
|
|
+ margin-bottom: 2px;
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|