master
xy 1 year ago
parent b8ea5d89d7
commit 48f2c3a403

@ -124,6 +124,7 @@
options: [
{ value: 1, label: '小程序' },
{ value: 2, label: 'h5' },
{ value: 3, label: '图片' },
],
props: { multiple: false },
optionProps: { value: 'value', label: 'label' },

@ -65,6 +65,7 @@
v-for="(option, optionIndex) in [
{ value: 1, label: '小程序' },
{ value: 2, label: 'h5' },
{ value: 3, label: '图片' },
]"
:key="optionIndex"
:label="option['label']"

@ -10,38 +10,38 @@
@close="$emit('update:isShow',false)">
<section class="drawer-container">
<el-descriptions class="drawer-container__desc" size="small" border ref="elDesc" :column="2" direction="vertical" :labelStyle="{ 'font-weight': '500', 'font-size': '15px' }">
<el-descriptions-item label="标题">
{{ form['name'] }}
</el-descriptions-item>
<el-descriptions-item label="副标题">
{{ form['sub_name'] }}
</el-descriptions-item>
<el-descriptions-item label="显示位置">
{{ [{'value':1,'label':'首页'}].find(i => i['value'] === form['position']) ? [{'value':1,'label':'首页'}].find(i => i['value'] === form['position'])['label'] : '' }}
</el-descriptions-item>
<el-descriptions-item label="跳转类型">
{{ [{'value':1,'label':'小程序'},{'value':2,'label':'h5'}].find(i => i['value'] === form['jump_type']) ? [{'value':1,'label':'小程序'},{'value':2,'label':'h5'}].find(i => i['value'] === form['jump_type'])['label'] : '' }}
{{ [{'value':1,'label':'小程序'},{'value':2,'label':'h5'}, { value: 3, label: '图片' },].find(i => i['value'] === form['jump_type']) ? [{'value':1,'label':'小程序'},{'value':2,'label':'h5'}].find(i => i['value'] === form['jump_type'])['label'] : '' }}
</el-descriptions-item>
<el-descriptions-item label="跳转链接">
{{ form['jump_url'] }}
</el-descriptions-item>
<el-descriptions-item label="排序">
{{ typeof form['sort'] === 'number' ? form['sort'].toFixed(2) : form['sort'] }}
</el-descriptions-item>
<el-form-item label="封面图" prop="image_id">
<el-upload
:file-list="form['image_id']"
accept="application/msword,image/jpeg,application/pdf,image/png,application/vnd.ms-powerpoint,text/plain,application/x-zip-compressed,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document">
</el-upload>
</el-form-item>
</el-descriptions>
</section>
</el-drawer>
@ -59,28 +59,28 @@
default: false,
required: true
},
},
data() {
return {
loading: false,
visible: false,
form: {
name: '',
sub_name: '',
position: '',
jump_type: '',
jump_url: '',
sort: '',
image_id: [],
},
}
},

@ -85,6 +85,118 @@
<vxe-column type="checkbox" width="50" align="center" />
<vxe-column type="seq" width="58" align="center" />
<vxe-column
type="expand"
title="批次详情"
field="batch_subs"
width="80"
align="center"
>
<template #content="{ row }">
<vxe-table
size="small"
:ref="'subTable' + row.id"
stripe
:height="500"
:data="row['batch_subs']"
:column-config="{ resizable: true }"
>
<vxe-column type="seq" width="70" align="center">
<template #header>
<el-button
:disabled="!isActiveStatus(row)"
size="small"
icon="el-icon-plus"
type="primary"
@click="row.batch_subs.push({
name: '',
batch_id: row.id,
school: [],
sort: '',
show_school_obey: '',
show_specialty_obey: '',
})"
></el-button>
</template>
</vxe-column>
<vxe-column
field="number"
min-width="140"
title="名称"
align="center"
>
<template #default="{ row: row1 }">
<el-input
size="small"
v-model="row1['name']"
clearable
:readonly="!isActiveStatus(row)"
placeholder="请填写详细名称"
style="width: 100%"
></el-input>
</template>
</vxe-column>
<vxe-column
field="sort"
width="140"
title="排序"
align="center"
>
<template #default="{ row: row1 }">
<el-input-number
size="small"
v-model="row1['sort']"
clearable
controls-position="right"
:disabled="!isActiveStatus(row)"
placeholder="请填写排序"
style="width: 100%"
></el-input-number>
</template>
</vxe-column>
<vxe-column
field="show_school_obey"
width="140"
title="是否显示学校服从"
align="center"
>
<template #default="{ row: row1 }">
<el-switch v-model="row1['show_school_obey']"
:active-value="1"
:inactive-value="0"
active-text="是"
inactive-text="否"
:disabled="!isActiveStatus(row)"></el-switch>
</template>
</vxe-column>
<vxe-column
field="show_specialty_obey"
width="140"
title="是否显示专业服从"
align="center"
>
<template #default="{ row: row1 }">
<el-switch v-model="row1['show_specialty_obey']"
:active-value="1"
:inactive-value="0"
active-text="是"
inactive-text="否"
:disabled="!isActiveStatus(row)"></el-switch>
</template>
</vxe-column>
<vxe-column
:visible="isActiveStatus(row)"
field="operate"
title="操作"
min-width="140"
header-align="center"
>
<el-button size="small" type="danger">删除</el-button>
</vxe-column>
</vxe-table>
</template>
</vxe-column>
<vxe-column
header-align="center"
field="name"
@ -208,6 +320,7 @@ import { uploadSize } from "@/settings";
import { deepCopy } from "@/utils";
import { download } from "@/utils/downloadRequest";
import { destroy, index, save } from "@/api/batch/batch";
import { save as batchSubSave } from "@/api/batch-sub/batch-sub";
import AddBatch from "./components/AddBatch.vue";
import ShowBatch from "./components/ShowBatch.vue";
import axios from "axios";
@ -235,7 +348,7 @@ export default {
page: 1,
page_size: 20,
keyword: "",
show_relation: ["aspiration"],
show_relation: ["aspiration", "batchSubs"],
},
total: 0,
allAlign: null,
@ -440,6 +553,22 @@ export default {
if (errMap) {
throw new Error(errMap);
}
const validBatchSub = () => {
let flag = true
row.batch_subs.forEach(i => {
if (i.name !== '' && i.name !== undefined && i.name !== null && i.name !== 'null') {
} else {
flag = false
}
})
if (flag) {
} else {
this.$message.warning('请填写批次详情名称')
throw new Error('请填写批次详情名称')
}
}
validBatchSub()
await this.$confirm("确认保存?", "提示", {
confirmButtonText: "确认",
cancelButtonText: "取消",
@ -449,9 +578,9 @@ export default {
for (const key in form) {
form[key] = row[key];
}
this.loading = true;
await save(form, false);
await Promise.all(row.batch_subs.map(item => batchSubSave(item)))
await this.getList();
this.loading = false;
} catch (err) {

@ -55,6 +55,96 @@
style="width: 100%"
></el-input-number>
</el-form-item>
<el-form-item class="span2" label="批次详情" prop="batchSub">
<vxe-table
stripe
:height="500"
:data="form['batchSub']"
:column-config="{ resizable: true }"
>
<vxe-column type="seq" width="70" align="center">
<template #header>
<el-button
icon="el-icon-plus"
type="primary"
@click="
form.batchSub.push({
name: '',
batch_id: '',
school: [],
sort: '',
show_school_obey: '',
show_specialty_obey: '',
})
"
></el-button>
</template>
</vxe-column>
<vxe-column
field="name"
width="140"
title="名称"
align="center"
>
<template #default="{ row }">
<el-input
v-model="row['name']"
clearable
placeholder="请填写详细名称"
style="width: 100%"
></el-input>
</template>
</vxe-column>
<vxe-column
field="sort"
min-width="140"
title="排序"
align="center"
>
<template #default="{ row }">
<el-input-number
v-model="row['sort']"
clearable
controls-position="right"
placeholder="请填写排序"
style="width: 100%"
></el-input-number>
</template>
</vxe-column>
<vxe-column
field="show_school_obey"
width="140"
title="是否显示学校服从"
align="center"
>
<template #default="{ row }">
<el-switch v-model="row.show_school_obey" :active-value="1" :inactive-value="0" active-text="是" inactive-text="否"></el-switch>
</template>
</vxe-column>
<vxe-column
field="show_specialty_obey"
width="140"
title="是否显示专业服从"
align="center"
>
<template #default="{ row }">
<el-switch v-model="row.show_specialty_obey" :active-value="1" :inactive-value="0" active-text="是" inactive-text="否"></el-switch>
</template>
</vxe-column>
<vxe-column field="operate" title="操作" min-width="120">
<template #default="{ row, rowIndex }">
<el-button
size="small"
type="danger"
@click="form.batchSub.splice(rowIndex, 1)"
>删除</el-button
>
</template>
</vxe-column>
</vxe-table>
</el-form-item>
</div>
</el-form>
@ -70,6 +160,7 @@
</template>
<script>
import { save as batchSubSave } from "@/api/batch-sub/batch-sub"
import { save, show } from "@/api/batch/batch";
import axios from "axios";
import { getToken } from "@/utils/auth";
@ -98,10 +189,9 @@ export default {
visible: false,
form: {
name: "",
aspiration_id: "",
sort: "",
batchSub: [],
},
rules: {
aspiration_id: [
@ -110,6 +200,25 @@ export default {
message: "归属总表" + "必填",
},
],
batchSub: [
{
validator: (rule, value, callback) => {
let flag = true
value.forEach(i => {
if (i.name !== '' && i.name !== undefined && i.name !== null && i.name !== 'null') {
} else {
flag = false
}
})
if (flag) {
callback()
} else {
callback(new Error('请填写批次详情名称'))
}
}
}
]
},
};
},
@ -165,10 +274,9 @@ export default {
reset() {
this.form = {
name: "",
aspiration_id: "",
sort: "",
batchSub: [],
};
this.$refs["elForm"].resetFields();
},
@ -182,7 +290,10 @@ export default {
if (valid) {
this.loading = true;
try {
await save(this.form);
const { batchSub } = this.form
const { id } = await save(this.form);
batchSub.forEach(i => i.batch_id = id);
await Promise.all(batchSub.map(item => batchSubSave(item)));
this.$message.success("新增成功");
this.$emit("refresh");
this.$emit("update:isShow", false);

@ -85,6 +85,11 @@
<vxe-column type="checkbox" width="50" align="center" />
<vxe-column type="seq" width="58" align="center" />
<vxe-column title="归属表" min-width="160" header-align="center">
<template #default="{ row }">
<span>{{ row.batch ? (row.batch.aspiration ? row.batch.aspiration.name : '/') : '/' }} - {{ row.batch ? row.batch.name : '/' }}</span>
</template>
</vxe-column>
<vxe-column
header-align="center"
field="name"
@ -117,9 +122,9 @@
{{ row.school ? row.school.map(i => i.name) : '' }}
</template>
<template #edit="{ row }">
<el-select v-model="row.school" style="width: 100%;" filterable multiple collapse-tags value-key="id" size="small">
<el-option v-for="item in school" :label="item.name" :value="{ code: item.code, name: item.name, id: item.id }"></el-option>
</el-select>
<el-input :value="row.school ? row.school.map(i => i.name).toString() : ''"
size="small" placeholder="点击选择学校"
@focus="selectedRow = row,$refs['SchoolPicker'].setDefaultValue(row.school || []), isShowSchoolPicker = true"></el-input>
</template>
</vxe-column>
@ -238,7 +243,6 @@
<AddBatchSub
ref="AddBatchSub"
:batch="batch"
:school="school"
:is-show.sync="isShowAdd"
@refresh="getList"
/>
@ -247,6 +251,7 @@
:batch="batch"
:is-show.sync="isShowDetail"
/>
<SchoolPicker ref="SchoolPicker" :is-show.sync="isShowSchoolPicker" @confirm="e => selectedRow.school = e" />
</div>
</template>
@ -260,6 +265,7 @@ import { download } from "@/utils/downloadRequest";
import { destroy, index, save } from "@/api/batch-sub/batch-sub";
import AddBatchSub from "./components/AddBatchSub.vue";
import ShowBatchSub from "./components/ShowBatchSub.vue";
import SchoolPicker from "./components/SchoolPicker.vue"
import axios from "axios";
import { getToken } from "@/utils/auth";
@ -272,6 +278,7 @@ export default {
components: {
AddBatchSub,
ShowBatchSub,
SchoolPicker,
},
data() {
return {
@ -279,6 +286,8 @@ export default {
examineKey: 0,
isShowAdd: false,
isShowDetail: false,
isShowSchoolPicker: false,
selectedRow: {},
loading: false,
tableHeight: 400,
@ -286,7 +295,7 @@ export default {
page: 1,
page_size: 20,
keyword: "",
show_relation: ["aspiration.batchs"],
show_relation: ["batch.aspiration"],
},
total: 0,
allAlign: null,
@ -317,7 +326,7 @@ export default {
},
batch: [],
school: [],
// school: [],
};
},
computed: {
@ -336,7 +345,7 @@ export default {
},
created() {
this.getBatch();
this.getSchool();
// this.getSchool();
this.getList();
},
@ -411,20 +420,20 @@ export default {
this.isShowDetail = true;
},
async getSchool() {
try {
const res = await schoolIndex(
{
page: 1,
page_size: 999,
},
false
);
this.school = res.data;
} catch (err) {
console.error(err);
}
},
// async getSchool() {
// try {
// const res = await schoolIndex(
// {
// page: 1,
// page_size: 999,
// },
// false
// );
// this.school = res.data;
// } catch (err) {
// console.error(err);
// }
// },
async getBatch() {
try {

@ -68,9 +68,11 @@
</el-form-item>
<el-form-item label="绑定学校" prop="school">
<el-select v-model="form.school" style="width: 100%;" filterable multiple collapse-tags value-key="id" size="small">
<el-option v-for="item in school" :label="item.name" :value="{ code: item.code, name: item.name, id: item.id }"></el-option>
</el-select>
<el-input :value="form.school ? form.school.map(i => i.name + '\n').toString() : ''"
size="small"
type="textarea"
placeholder="点击选择学校"
@focus="$refs['SchoolPicker'].setDefaultValue(form.school), isShowSchoolPicker = true"></el-input>
</el-form-item>
<el-form-item label="排序" prop="sort">
@ -140,6 +142,8 @@
</div>
</section>
</el-drawer>
<SchoolPicker ref="SchoolPicker" :is-show.sync="isShowSchoolPicker" @confirm="e => form.school = e"></SchoolPicker>
</div>
</template>
@ -151,22 +155,22 @@ import axios from "axios";
import { getToken } from "@/utils/auth";
import { uploadSize } from "@/settings";
import { formatFileSize } from "@/utils";
import SchoolPicker from "./SchoolPicker.vue"
export default {
name: "BatchSubDrawer",
components: {
SchoolPicker
},
props: {
isShow: {
type: Boolean,
default: false,
required: true,
},
school: {
type: Array,
default: () => []
}
},
data() {
return {
isShowSchoolPicker: false,
uploadSize,
action: process.env.VUE_APP_UPLOAD_API,
loading: false,

@ -0,0 +1,316 @@
<template>
<div>
<vxe-modal
:z-index="zIndex"
:value="isShow"
show-footer
title="学校选择"
show-confirm-button
:width="defaultModalSize.width"
:height="defaultModalSize.height"
esc-closable
transfer
:fullscreen="$store.getters.device === 'mobile'"
@input="e => $emit('update:isShow',e)"
>
<section>
<div class="select-panel">
<el-input style="width: 120px;" v-model="select['filter[1][value]']" placeholder="学校名称.." size="small"></el-input>
<el-select style="width: 100px;" clearable v-model="select['filter[0][value]']" placeholder="区域.." size="small">
<el-option v-for="item in area" :key="item.id" :label="item.name" :value="item.id"></el-option>
</el-select>
<el-input style="width: 120px;" v-model="select['filter[2][value]']" placeholder="学校星级.." size="small"></el-input>
<el-button
icon="el-icon-search"
type="primary"
plain
size="small"
@click="getList(true)"
>搜索</el-button
>
</div>
<vxe-table
ref="table"
stripe
style="margin-top: 10px"
:loading="loading"
:max-height="tableHeight"
keep-source
show-overflow
:row-config="{ isCurrent: true, isHover: true, keyField: 'id' }"
:column-config="{ resizable: true }"
:export-config="{}"
:edit-config="{}"
:checkbox-config="{ trigger: 'row', labelField: 'name', highlight: true, range: true, reserve: true }"
:align="allAlign"
:data="tableData"
@checkbox-change="checkboxChange"
@checkbox-all="checkboxAll"
@checkbox-range-end="checkboxRangeEnd"
>
<vxe-column type="checkbox" width="260" header-align="center" title="学校名称" />
<vxe-column
align="center"
field="area_id"
width="180"
title="区域"
:edit-render="{
name: 'VxeSelect',
options: area,
props: { multiple: false },
optionProps: { value: 'id', label: 'name' },
}"
/>
<vxe-column
align="center"
field="code"
width="160"
title="学校代码"
:edit-render="{ name: 'input', attrs: { type: 'text' } }"
/>
<vxe-column
align="center"
field="star"
width="160"
title="星级"
:edit-render="{ name: 'input', attrs: { type: 'text' } }"
/>
<vxe-column
header-align="center"
field="address"
width="160"
title="地址"
:edit-render="{ name: 'input', attrs: { type: 'text' } }"
/>
<vxe-column
align="center"
field="nature"
width="180"
title="性质"
:edit-render="{
name: 'VxeSelect',
options: [
{ value: 1, label: '公办' },
{ value: 2, label: '民办' },
],
props: { multiple: false },
optionProps: { value: 'value', label: 'label' },
}"
/>
<vxe-column
align="center"
field="type"
width="180"
title="学校类型"
/>
<vxe-column
header-align="center"
field="build_year"
width="160"
title="建校年份"
:edit-render="{ name: 'input', attrs: { type: 'text' } }"
/>
</vxe-table>
<el-pagination
style="margin-top: 10px; display: flex; justify-content: flex-end"
:current-page.sync="select.page"
:page-sizes="[20, 30, 40, 50]"
:page-size.sync="select.page_size"
layout="total, sizes, prev, pager, next, jumper"
:total="total"
@size-change="
(e) => {
select.page_size = e;
select.page = 1;
getList();
}
"
@current-change="
(e) => {
select.page = e;
getList();
}
"
/>
</section>
<template #footer>
<el-button type="primary" @click="submit"></el-button>
</template>
</vxe-modal>
</div>
</template>
<script>
import { PopupManager } from "element-ui/lib/utils/popup";
import { defaultModalSize } from "@/settings";
import { index as areaIndex } from "@/api/area/area";
import { index } from "@/api/school/school";
export default {
props: {
isShow: {
type: Boolean,
default: false,
required: true
}
},
data() {
return {
zIndex: PopupManager.nextZIndex(),
defaultModalSize,
defaultValue: [],
loading: false,
tableHeight: 400,
select: {
page: 1,
page_size: 20,
keyword: "",
show_relation: [],
'filter[0][key]': 'area_id',
'filter[0][op]': 'eq',
'filter[0][value]': '',
'filter[1][key]': 'name',
'filter[1][op]': 'like',
'filter[1][value]': '',
'filter[2][key]': 'star',
'filter[2][op]': 'like',
'filter[2][value]': '',
},
total: 0,
allAlign: null,
tableData: [],
area: [],
}
},
methods: {
checkboxRangeEnd() {
const $table = this.$refs['table']
if ($table) {
const selected = $table.getCheckboxRecords(true)
if (selected.length === 0) {
this.checkboxAll({ checked: false })
} else {
const abandonData = this.tableData.filter(i => selected.indexOf(j => j.id === i.id) === -1)
abandonData.forEach(row => {
this.spliceData(row)
})
}
}
},
spliceData(row) {
let index = this.defaultValue.findIndex(i => i.id === row.id)
if (index !== -1) {
this.defaultValue.splice(index, 1)
}
},
checkboxAll({ checked }) {
if (!checked) {
this.tableData.forEach(row => {
this.spliceData(row)
})
}
},
checkboxChange({ checked, row }) {
if (!checked) {
this.spliceData(row)
}
},
setDefaultValue(arr = []) {
this.defaultValue = arr
},
uniqueArr(...args) {
let arr = args.flat()
return arr.reduce((acc, cur) => {
const hasDuplicate = acc.some(item => item.id === cur.id);
if (!hasDuplicate) {
acc.push(cur);
}
return acc;
}, []);
},
async getArea() {
try {
const res = await areaIndex(
{
page: 1,
page_size: 999,
},
false
);
this.area = res.data;
} catch (err) {
console.error(err);
}
},
async getList(isRefresh=false) {
if(isRefresh) {
this.select.page = 1
}
this.loading = true;
try {
const res = await index(this.select, false);
this.tableData = res.data;
this.total = res.total;
this.loading = false;
this.toggleDefault()
} catch (err) {
console.error(err);
this.loading = false;
}
},
toggleDefault() {
this.$nextTick(_ => {
this.$refs['table']?.clearCheckboxRow()
this.$refs['table']?.setCheckboxRow(this.tableData.filter(i => !!this.defaultValue.find(j => j.id === i.id)), true)
})
},
submit() {
const $table = this.$refs['table']
if ($table) {
console.log(this.uniqueArr($table.getCheckboxReserveRecords(true), $table.getCheckboxRecords(true), this.defaultValue).map(i => ({ id: i.id, code: i.code, name: i.name })))
this.$emit('confirm', this.uniqueArr($table.getCheckboxReserveRecords(true), $table.getCheckboxRecords(true), this.defaultValue).map(i => ({ id: i.id, code: i.code, name: i.name })))
this.$emit('update:isShow', false)
}
}
},
computed: {
},
watch: {
isShow(newVal) {
if(newVal) {
this.zIndex = PopupManager.nextZIndex()
this.toggleDefault()
} else {
this.setDefaultValue()
}
}
},
created() {
this.getArea();
this.getList();
},
}
</script>
<style scoped lang="scss">
.select-panel {
* + * {
margin-left: 10px;
}
}
</style>

@ -84,6 +84,13 @@
>
<vxe-column type="checkbox" width="50" align="center" />
<vxe-column type="seq" width="58" align="center" />
<vxe-column title="归属表" min-width="240" header-align="center">
<template #default="{ row }">
<span>{{ row.batch_sub ? (row.batch_sub.batch ? (row.batch_sub.batch.aspiration ? row.batch_sub.batch.aspiration.name : '/') : '/') : '/' }} - {{ row.batch_sub ? (row.batch_sub.batch ? row.batch_sub.batch.name : '/') : '/' }} - {{ row.batch_sub ? row.batch_sub.name : '/' }}</span>
</template>
</vxe-column>
<vxe-column
type="expand"
title="专业详情"
@ -282,7 +289,7 @@ export default {
page: 1,
page_size: 20,
keyword: "",
show_relation: ["batchSub"],
show_relation: ["batchSub.batch.aspiration"],
},
total: 0,
allAlign: null,

Loading…
Cancel
Save