init: UserBaseFront (frontend)

This commit is contained in:
chenxing
2026-08-10 14:41:13 +08:00
commit eea881b616
174 changed files with 32833 additions and 0 deletions
+300
View File
@@ -0,0 +1,300 @@
<template>
<div class="main-wrapper">
<div class="main-container">
<div class="fix mb-12">
<Button type="primary" @click="curEditId = 0, eidtModelShow = true" class="fl">
添加{{ bookInfo.name }}
</Button>
<Button type="success" @click="uploadType = 2, uploadModelShow = true" class="fr ml-12">
导入{{ bookInfo.name }}和目录树
</Button>
<Button type="success" @click="uploadType = 1, uploadModelShow = true" class="fr ml-12">
导入{{ bookInfo.name }}
</Button>
</div>
<div class="search-wrap fix">
<Select class="search-wrap_sel" v-model="dataParams.subject" clearable placeholder="选择科目">
<Option v-for="item in dictData.subject" :value="item.code" :key="item.code">{{ item.name }}
</Option>
</Select>
<Select class="search-wrap_sel ml-12" v-model="dataParams.grade" clearable placeholder="选择年级">
<Option v-for="item in dictData.grade" :value="item.id" :key="item.id">{{ item.name }}
</Option>
</Select>
<Select class="search-wrap_sel ml-12" v-model="dataParams.press" clearable placeholder="选择出版社">
<Option v-for="item in pressList" :value="item.v" :key="item.k">{{ item.v }}
</Option>
</Select>
<Select class="search-wrap_sel ml-12" v-model="dataParams.semester" clearable placeholder="选择学期">
<Option :value="0">上学期</Option>
<Option :value="1">下学期</Option>
</Select>
<Input class="fr ml-12" v-model="dataParams.name" placeholder="输入关键字筛选" suffix="ios-search" clearable
style="width:200px" />
</div>
<TablePageAlova ref="tableRef" :dataApi="tableApi" :columns="columns" :dataParams="dataParams"
:tableHeight="tableHeight">
</TablePageAlova>
<Drawer width="400" :title="drawerTitle" :closable="false" v-model="showDrawer">
<MyTree :treeData="knowTreeData" :setting="treeSetting2" :autoClick="false" />
</Drawer>
</div>
<div class="modal-wrap">
<EditModel v-model="eidtModelShow" :id="curEditId" :bookType="bookInfo.type" @success="reloadTable" />
<Modal v-model="uploadModelShow" :mask-closable="false" width="600" :title="modalTitle">
<BschImport ref="importRef" :tempFileUrl="tempFileUrl" :uploadUrl="uploadUrl" :uploadData="uploadData"
@on-success="reloadTable" />
<template #footer>
<Button @click="uploadModelShow = false">关闭</Button>
</template>
</Modal>
<Modal v-model="knowledgeModelShow" :mask-closable="false" width="900" title="目录树管理">
<Knowledge :id="curKnowId" :name="curKnowName" v-if="knowledgeModelShow" />
<template #footer>
<Button @click="knowledgeModelShow = false">关闭</Button>
</template>
</Modal>
<!-- BschImport -->
</div>
</div>
</template>
<script lang="ts" setup>
import { } from "vue";
import TablePageAlova from '@/components/TablePageAlova.vue'
import useCurrentInstance from "@/utils/hook/useCurrentInstance";
import Knowledge from './Knowledge.vue'
import { useDefaultStore } from "@/store";
import EditModel from './EditModel.vue'
import MyTree from '@/components/MyTree.vue'
import MyConfirm from "@/components/MyConfirm";
import BschImport from '@/components/BschImport.vue'
import useBookInfo from "../useBookInfo";
import { useRouter } from "vue-router";
import { OperatorEnum } from "@/types";
const store = useDefaultStore();
const { $conf, $bus, $utils } = useCurrentInstance();
const { bookInfo } = useBookInfo()
const eidtModelShow = ref(false);
const knowledgeModelShow = ref(false);
const uploadType = ref(0);
const uploadModelShow = ref(false);
const curEditId = ref(0)
const tableRef = useTemplateRef('tableRef')
const curKnowId = ref(0)
const curKnowName = ref('')
const router = useRouter();
const dataParams = ref({
pageSize: '',
pageIndex: '',
grade: null,
semester: null,
subject: null,
press: null,
name: null,
bookType: bookInfo.value.type,
})
const treeSetting2 = ref({
view: {
dblClickExpand: false,
showIcon: false,
},
edit: {
enable: true,
showRemoveBtn: false,
showRenameBtn: false,
drag: false,
},
check: {
enable: false,
},
callback: {},
})
const tableHeight = ref($utils.useTableHeight({ isOperat: true, isPage: true, isSearch: true }));
const { data: dictData } = useRequest(Apis.Base.getSystemDict({
cacheFor: 1000 * 60 * 60
}), {
initialData: {
grade: [],
textPress: [],
teachingPress: [],
subject: [],
}
});
const { data: knowTreeData, send: sendKnowledgTree } =
useRequest((textbookId: number) => Apis.Knowledge.getTreeByTextbookId({
params: { textbookId },
transform: (res: any) => {
let arr = res || [];
return arr.map((item: any) => {
item.open = true;
return item;
})
},
}), {
initialData: [],
immediate: false
});
const showDrawer = ref(false);
const drawerTitle = ref('');
const columns = ref([
{ type: 'index', title: '序号', width: 80 },
{ title: bookInfo.value.name + '名称', key: 'name' },
{ title: '年级', key: 'gradeName' },
{
title: '学期',
key: 'semester',
render: (h: any, params: any) => {
return h('span', params.row.semester == 0 ? '上学期' : '下学期');
}
},
{ title: '科目', key: 'subjectName' },
{ title: '出版社', key: 'press' },
{ title: '出版年份', key: 'outTime' },
// {
// title: '封面',
// key: 'coverImage',
// width: 120,
// render: (row: any, { row: r }: any) => {
// const src = r.coverImage || new URL('@/assets/image/default-bg1.png', import.meta.url).href
// return h('img', {
// src,
// style: {
// width: '20px',
// height: '30px',
// objectFit: 'cover',
// borderRadius: '4px'
// },
// alt: '封面'
// })
// }
// },
{
title: '操作',
width: 240,
align: 'center',
render: (h: any, params: any) => {
const disabled = params.row.disabled;
return [
$utils.operatingTextHandle(h, '目录树管理', '', () => {
// router.push({
// path: '/' + bookInfo.value.path + '/manage/knowledge',
// query: { id: params.row.id, name: params.row.name },
// });
curKnowId.value = params.row.id;
curKnowName.value = params.row.name;
knowledgeModelShow.value = true;
}, disabled),
$utils.operatingTextHandle(h, '查看', '', () => {
drawerTitle.value = params.row.name;
showDrawer.value = true;
setTimeout(() => {
sendKnowledgTree(params.row.id);
}, 100);
}),
$utils.operatingTextHandle(h, '编辑', '', () => {
curEditId.value = params.row.id;
eidtModelShow.value = true;
}, disabled),
$utils.operatingTextHandle(h, '删除', 'text-error', () => {
removeSave(params.row.id)
}, disabled),
];
}
}
])
const modalTitle = computed(() => {
return '导入' + bookInfo.value.name + (uploadType.value === 1 ? '' : '和知识树');
})
const tempFileUrl = computed(() => {
const method = uploadType.value == 1 ? 'getTextbookTemplate' : 'getTextbookKnowledgeTemplate';
let url = $conf.serviceHost + `/api/knowledge/${method}?bookType=` + bookInfo.value.type;
return url;
})
const uploadUrl = computed(() => {
const method = uploadType.value == 1 ? '/api/knowledge/importTextbook' : '/api/knowledge/importTextbookInfo';
return $conf.serviceHost + method;
})
const uploadData = computed(() => {
return { bookType: bookInfo.value.type };
})
const pressList = computed(() => {
return bookInfo.value.type == 1 ? dictData.value.textPress : dictData.value.teachingPress
})
const clean = (obj: Record<string, any>) =>
Object.fromEntries(
Object.entries(obj).filter(([, v]) => v != null && v !== '')
)
const tableApi = (params: { pageIndex: number; pageSize: number }) => {
return Apis.Knowledge.searchTextbooks({
params: clean({ ...dataParams.value, ...params }),
cacheFor: null,
})
}
onBeforeMount(() => {
$bus.emit('resetLayout', { identity: bookInfo.value.identity, modId: (bookInfo.value.baseModId + 4) });
});
/**
* removeSave
*/
async function removeSave(id: number) {
await MyConfirm({
msg: "确定删除该教材吗?",
info: "关联目录树也将会被删除,删除后不可恢复!",
async onOk() {
try {
await Apis.Knowledge.deleteTextbook({ params: { id } });
Message.success("操作成功!");
tableRef.value?.reloadData(OperatorEnum.del);
} catch (error) {
Message.error(error);
}
},
});
}
function reloadTable() {
if (!curEditId.value) tableRef.value?.reloadData(OperatorEnum.add);
else tableRef.value?.reloadData(OperatorEnum.edit);
}
</script>
<style lang="scss" scoped></style>