提交 47613f2f authored 作者: matian's avatar matian

代码提交

上级 646dce9a
...@@ -38,6 +38,8 @@ ...@@ -38,6 +38,8 @@
"ignorableWatch": true, "ignorableWatch": true,
"inject": true, "inject": true,
"isDefined": true, "isDefined": true,
"isProxy": true,
"isReactive": true,
"isReadonly": true, "isReadonly": true,
"isRef": true, "isRef": true,
"logicAnd": true, "logicAnd": true,
...@@ -235,6 +237,8 @@ ...@@ -235,6 +237,8 @@
"watchIgnorable": true, "watchIgnorable": true,
"watchOnce": true, "watchOnce": true,
"watchPausable": true, "watchPausable": true,
"watchPostEffect": true,
"watchSyncEffect": true,
"watchThrottled": true, "watchThrottled": true,
"watchWithFilter": true, "watchWithFilter": true,
"whenever": true "whenever": true
......
...@@ -39,6 +39,8 @@ declare global { ...@@ -39,6 +39,8 @@ declare global {
const ignorableWatch: typeof import('@vueuse/core')['ignorableWatch'] const ignorableWatch: typeof import('@vueuse/core')['ignorableWatch']
const inject: typeof import('vue')['inject'] const inject: typeof import('vue')['inject']
const isDefined: typeof import('@vueuse/core')['isDefined'] const isDefined: typeof import('@vueuse/core')['isDefined']
const isProxy: typeof import('vue')['isProxy']
const isReactive: typeof import('vue')['isReactive']
const isReadonly: typeof import('vue')['isReadonly'] const isReadonly: typeof import('vue')['isReadonly']
const isRef: typeof import('vue')['isRef'] const isRef: typeof import('vue')['isRef']
const logicAnd: typeof import('@vueuse/core')['logicAnd'] const logicAnd: typeof import('@vueuse/core')['logicAnd']
...@@ -236,6 +238,8 @@ declare global { ...@@ -236,6 +238,8 @@ declare global {
const watchIgnorable: typeof import('@vueuse/core')['watchIgnorable'] const watchIgnorable: typeof import('@vueuse/core')['watchIgnorable']
const watchOnce: typeof import('@vueuse/core')['watchOnce'] const watchOnce: typeof import('@vueuse/core')['watchOnce']
const watchPausable: typeof import('@vueuse/core')['watchPausable'] const watchPausable: typeof import('@vueuse/core')['watchPausable']
const watchPostEffect: typeof import('vue')['watchPostEffect']
const watchSyncEffect: typeof import('vue')['watchSyncEffect']
const watchThrottled: typeof import('@vueuse/core')['watchThrottled'] const watchThrottled: typeof import('@vueuse/core')['watchThrottled']
const watchWithFilter: typeof import('@vueuse/core')['watchWithFilter'] const watchWithFilter: typeof import('@vueuse/core')['watchWithFilter']
const whenever: typeof import('@vueuse/core')['whenever'] const whenever: typeof import('@vueuse/core')['whenever']
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "center-resource",
"version": "0.0.0", "version": "0.0.0",
"dependencies": { "dependencies": {
"@element-plus/icons-vue": "^1.1.4", "@element-plus/icons-vue": "^1.1.4",
...@@ -35,7 +36,7 @@ ...@@ -35,7 +36,7 @@
"sass": "^1.52.1", "sass": "^1.52.1",
"sortablejs": "^1.15.0", "sortablejs": "^1.15.0",
"typescript": "~4.7.2", "typescript": "~4.7.2",
"unplugin-auto-import": "^0.8.5", "unplugin-auto-import": "^0.8.7",
"vite": "^2.9.9", "vite": "^2.9.9",
"vite-plugin-checker": "^0.4.6", "vite-plugin-checker": "^0.4.6",
"vue-tsc": "^0.34.16" "vue-tsc": "^0.34.16"
...@@ -4027,6 +4028,18 @@ ...@@ -4027,6 +4028,18 @@
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/strip-literal": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-0.3.0.tgz",
"integrity": "sha512-J+lfm3Pw5nzURj2B8acyvUSBqs3JbjM8WAfrmeH3qcn32+ew6kFwbZFV9+X8k9UOIAkQw9WPSzFZy3083c7l5Q==",
"dev": true,
"dependencies": {
"acorn": "^8.7.1"
},
"funding": {
"url": "https://github.com/sponsors/antfu"
}
},
"node_modules/supports-color": { "node_modules/supports-color": {
"version": "7.2.0", "version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
...@@ -4193,9 +4206,9 @@ ...@@ -4193,9 +4206,9 @@
} }
}, },
"node_modules/unimport": { "node_modules/unimport": {
"version": "0.2.4", "version": "0.2.6",
"resolved": "https://registry.npmjs.org/unimport/-/unimport-0.2.4.tgz", "resolved": "https://registry.npmjs.org/unimport/-/unimport-0.2.6.tgz",
"integrity": "sha512-7OEUIlZMS1s1h1uFAGkCPylMtE8hnlJ/cFurJQHdzKAqIyuGiOREFKaCLbkNtFloZicCpRAlqC0Ny2yMoz6mFg==", "integrity": "sha512-4cOokUIEvaXAfVCHH87vR+wdKI1KDzxQREW9oi0r6J68TPFEeGLHHc2pdyL0uNDUMd2aLxUikhWARNfoQKqC4Q==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@rollup/pluginutils": "^4.2.1", "@rollup/pluginutils": "^4.2.1",
...@@ -4206,6 +4219,7 @@ ...@@ -4206,6 +4219,7 @@
"mlly": "^0.5.2", "mlly": "^0.5.2",
"pathe": "^0.3.0", "pathe": "^0.3.0",
"scule": "^0.2.1", "scule": "^0.2.1",
"strip-literal": "^0.3.0",
"unplugin": "^0.6.3" "unplugin": "^0.6.3"
} }
}, },
...@@ -4283,16 +4297,16 @@ ...@@ -4283,16 +4297,16 @@
} }
}, },
"node_modules/unplugin-auto-import": { "node_modules/unplugin-auto-import": {
"version": "0.8.5", "version": "0.8.7",
"resolved": "https://registry.npmjs.org/unplugin-auto-import/-/unplugin-auto-import-0.8.5.tgz", "resolved": "https://registry.npmjs.org/unplugin-auto-import/-/unplugin-auto-import-0.8.7.tgz",
"integrity": "sha512-JT43zA89fMjxtdqz+sTSkTsL9J0PNdnGmMOvcwbkpDi45yL5SU0aDCZgj0E8+qWLyQSIvvBaDBW3VuBrcc2MXg==", "integrity": "sha512-xepkl/lzlPmWym/ZqjgKpev30S5402qZYHnRZ7MQ78+WxBykvUw69PB0awWcWJ7atswNs6LkDRpGNqzjFCEH4w==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@antfu/utils": "^0.5.2", "@antfu/utils": "^0.5.2",
"@rollup/pluginutils": "^4.2.1", "@rollup/pluginutils": "^4.2.1",
"local-pkg": "^0.4.1", "local-pkg": "^0.4.1",
"magic-string": "^0.26.2", "magic-string": "^0.26.2",
"unimport": "^0.2.4", "unimport": "^0.2.5",
"unplugin": "^0.6.3" "unplugin": "^0.6.3"
}, },
"engines": { "engines": {
...@@ -7674,6 +7688,15 @@ ...@@ -7674,6 +7688,15 @@
"integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
"dev": true "dev": true
}, },
"strip-literal": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-0.3.0.tgz",
"integrity": "sha512-J+lfm3Pw5nzURj2B8acyvUSBqs3JbjM8WAfrmeH3qcn32+ew6kFwbZFV9+X8k9UOIAkQw9WPSzFZy3083c7l5Q==",
"dev": true,
"requires": {
"acorn": "^8.7.1"
}
},
"supports-color": { "supports-color": {
"version": "7.2.0", "version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
...@@ -7797,9 +7820,9 @@ ...@@ -7797,9 +7820,9 @@
} }
}, },
"unimport": { "unimport": {
"version": "0.2.4", "version": "0.2.6",
"resolved": "https://registry.npmjs.org/unimport/-/unimport-0.2.4.tgz", "resolved": "https://registry.npmjs.org/unimport/-/unimport-0.2.6.tgz",
"integrity": "sha512-7OEUIlZMS1s1h1uFAGkCPylMtE8hnlJ/cFurJQHdzKAqIyuGiOREFKaCLbkNtFloZicCpRAlqC0Ny2yMoz6mFg==", "integrity": "sha512-4cOokUIEvaXAfVCHH87vR+wdKI1KDzxQREW9oi0r6J68TPFEeGLHHc2pdyL0uNDUMd2aLxUikhWARNfoQKqC4Q==",
"dev": true, "dev": true,
"requires": { "requires": {
"@rollup/pluginutils": "^4.2.1", "@rollup/pluginutils": "^4.2.1",
...@@ -7810,6 +7833,7 @@ ...@@ -7810,6 +7833,7 @@
"mlly": "^0.5.2", "mlly": "^0.5.2",
"pathe": "^0.3.0", "pathe": "^0.3.0",
"scule": "^0.2.1", "scule": "^0.2.1",
"strip-literal": "^0.3.0",
"unplugin": "^0.6.3" "unplugin": "^0.6.3"
}, },
"dependencies": { "dependencies": {
...@@ -7854,16 +7878,16 @@ ...@@ -7854,16 +7878,16 @@
} }
}, },
"unplugin-auto-import": { "unplugin-auto-import": {
"version": "0.8.5", "version": "0.8.7",
"resolved": "https://registry.npmjs.org/unplugin-auto-import/-/unplugin-auto-import-0.8.5.tgz", "resolved": "https://registry.npmjs.org/unplugin-auto-import/-/unplugin-auto-import-0.8.7.tgz",
"integrity": "sha512-JT43zA89fMjxtdqz+sTSkTsL9J0PNdnGmMOvcwbkpDi45yL5SU0aDCZgj0E8+qWLyQSIvvBaDBW3VuBrcc2MXg==", "integrity": "sha512-xepkl/lzlPmWym/ZqjgKpev30S5402qZYHnRZ7MQ78+WxBykvUw69PB0awWcWJ7atswNs6LkDRpGNqzjFCEH4w==",
"dev": true, "dev": true,
"requires": { "requires": {
"@antfu/utils": "^0.5.2", "@antfu/utils": "^0.5.2",
"@rollup/pluginutils": "^4.2.1", "@rollup/pluginutils": "^4.2.1",
"local-pkg": "^0.4.1", "local-pkg": "^0.4.1",
"magic-string": "^0.26.2", "magic-string": "^0.26.2",
"unimport": "^0.2.4", "unimport": "^0.2.5",
"unplugin": "^0.6.3" "unplugin": "^0.6.3"
}, },
"dependencies": { "dependencies": {
......
...@@ -40,7 +40,7 @@ ...@@ -40,7 +40,7 @@
"sass": "^1.52.1", "sass": "^1.52.1",
"sortablejs": "^1.15.0", "sortablejs": "^1.15.0",
"typescript": "~4.7.2", "typescript": "~4.7.2",
"unplugin-auto-import": "^0.8.5", "unplugin-auto-import": "^0.8.7",
"vite": "^2.9.9", "vite": "^2.9.9",
"vite-plugin-checker": "^0.4.6", "vite-plugin-checker": "^0.4.6",
"vue-tsc": "^0.34.16" "vue-tsc": "^0.34.16"
......
...@@ -32,5 +32,9 @@ export function uploadFile(data: Record<string, any>) { ...@@ -32,5 +32,9 @@ export function uploadFile(data: Record<string, any>) {
// 删除评论 // 删除评论
export function deleteComment(data: { id: string }) { export function deleteComment(data: { id: string }) {
return httpRequest.post('/api/psp/backend/comment/delete', data) return httpRequest.post('/api/resource/backend/comment/delete', data)
}
// 获取公共字典列表
export function getMapList() {
return httpRequest.get('/api/resource/v1/util/get-data-dictionary-list')
} }
...@@ -33,8 +33,7 @@ const tableRef = ref() ...@@ -33,8 +33,7 @@ const tableRef = ref()
const dataList = ref<any[]>([]) const dataList = ref<any[]>([])
const page = reactive({ total: 0, size: props.limit, currentPage: 1 }) const page = reactive({ total: 0, size: props.limit, currentPage: 1 })
const params = reactive({ page: page.currentPage, page_size: page.size, ...props.remote?.params }) const params = reactive({ page: page.currentPage, ['per-page']: page.size, ...props.remote?.params })
watch( watch(
() => props.data, () => props.data,
list => { list => {
...@@ -59,7 +58,7 @@ const fetchList = (isReset = false) => { ...@@ -59,7 +58,7 @@ const fetchList = (isReset = false) => {
// 翻页参数设置 // 翻页参数设置
if (props.hasPagination) { if (props.hasPagination) {
requestParams.page = page.currentPage requestParams.page = page.currentPage
requestParams.page_size = page.size requestParams['per-page'] = page.size
} }
// 接口请求之前 // 接口请求之前
if (beforeRequest) { if (beforeRequest) {
...@@ -134,10 +133,27 @@ defineExpose({ refetch }) ...@@ -134,10 +133,27 @@ defineExpose({ refetch })
</template> </template>
<template v-else> <template v-else>
<!-- input --> <!-- input -->
<el-input v-model="params[item.prop]" v-bind="item" clearable @change="search" v-if="item.type === 'input'" /> <el-input
v-model="params[item.prop]"
v-bind="item"
clearable
@change="search"
v-if="item.type === 'input'"
/>
<!-- select --> <!-- select -->
<el-select v-model="params[item.prop]" v-bind="item" clearable @change="search" v-if="item.type === 'select'"> <el-select
<el-option :label="option[item.labelKey] || option.label" :value="option[item.valueKey] || option.value" v-for="(option, index) in item.options" :key="index" /> v-model="params[item.prop]"
v-bind="item"
clearable
@change="search"
v-if="item.type === 'select'"
>
<el-option
:label="option[item.labelKey] || option.label"
:value="option[item.valueKey] || option.value"
v-for="(option, index) in item.options"
:key="index"
/>
</el-select> </el-select>
</template> </template>
</el-form-item> </el-form-item>
......
import httpRequest from '@/utils/axios' import httpRequest from '@/utils/axios'
// 获取视频列表 // 获取分类列表
export function getVideoList(params?: { type?: string; page?: number; page_size?: number }) { export function getCategoryList(params: { type: string; category_name?: string }) {
return httpRequest.get('/api/psp/backend/video/index', { params }) return httpRequest.get('/api/resource/v1/backend/category/list', { params })
}
// 新建分类
export function createCategory(data: {
category_name: string
depth?: string
status: string
need_pass: string
parent_id: string
}) {
return httpRequest.post('/api/resource/v1/backend/category/create', data)
}
// 编辑分类
export function updateCategory(data: {
id: string
category_name: string
depth?: string
status: string
need_pass: string
parent_id: string
}) {
return httpRequest.post('/api/resource/v1/backend/category/update', data)
}
// 删除分类
export function delCategory(data: { id: string }) {
return httpRequest.post('/api/resource/v1/backend/category/delete', data)
}
// 移动分类
export function moveCategory(data: { id: string; brother_id: string; type: string }) {
return httpRequest.post('/api/resource/v1/backend/category/drag', data)
} }
...@@ -2,14 +2,29 @@ ...@@ -2,14 +2,29 @@
import { Search } from '@element-plus/icons-vue' import { Search } from '@element-plus/icons-vue'
import type { FormRules } from 'element-plus' import type { FormRules } from 'element-plus'
import TreeDialog from './TreeDialog.vue' import TreeDialog from './TreeDialog.vue'
import { useMapStore } from '@/stores/map'
const categoryName = ref('')
const store = useMapStore()
const isTreeVisible = ref(false) const isTreeVisible = ref(false)
const formRef = ref() const formRef = ref()
interface mapList {
label: string
value: string
data_dictionary_id: string
sort: string
remark: string
id: string
}
let classList = $ref<mapList[]>([])
let statusList = $ref<mapList[]>([])
const categoryForm = reactive({ const categoryForm = reactive({
category: '', parent_id: '',
hierarchy: 1, category_name: '',
depth: 1,
name: '', name: '',
status: '0', status: '0',
isCourse: '1' need_pass: '1'
}) })
const rules = reactive<FormRules>({ const rules = reactive<FormRules>({
name: [ name: [
...@@ -29,10 +44,15 @@ const props = defineProps({ ...@@ -29,10 +44,15 @@ const props = defineProps({
isEdit: { isEdit: {
type: Boolean, type: Boolean,
required: true required: true
},
title: {
type: String,
required: true
} }
}) })
const emit = defineEmits<{ const emit = defineEmits<{
(e: 'update:dialogVisible', dialogVisible: false): void (e: 'update:dialogVisible', dialogVisible: false): void
(e: 'confirm', categoryForm: any): void
}>() }>()
// 打开类别选择弹框 // 打开类别选择弹框
...@@ -42,8 +62,9 @@ const handleOpenTree = () => { ...@@ -42,8 +62,9 @@ const handleOpenTree = () => {
// 获取子组件确定之后节点回显 // 获取子组件确定之后节点回显
const getCheckedLabel = (val: any) => { const getCheckedLabel = (val: any) => {
console.log(val, '99991111') console.log(val, '99991111')
categoryForm.category = val.checkedLabel.value categoryName.value = val.checkedCategory.checkedLabel
categoryForm.hierarchy = val.checkedLevel.value + 1 categoryForm.parent_id = val.checkedCategory.checkedId
categoryForm.depth = val.checkedCategory.checkedLevel
} }
// 关闭弹框 // 关闭弹框
const handleCancel = () => { const handleCancel = () => {
...@@ -53,26 +74,40 @@ const handleCancel = () => { ...@@ -53,26 +74,40 @@ const handleCancel = () => {
} }
// 确认提交表单 // 确认提交表单
const handleConfirm = () => { const handleConfirm = () => {
console.log(categoryForm, '0000') console.log(categoryForm.parent_id, '0000')
emit('update:dialogVisible', false) emit('update:dialogVisible', false)
emit('confirm', categoryForm)
if (props.isEdit) {
emit('confirm', { categoryForm, isUpdate: 1, id: props.editData.id })
} else {
emit('confirm', { categoryForm, isUpdate: 0 })
}
}
const getMapList = async () => {
await store.getMapList()
classList = store.mapList.filter((item: any) => item.key === 'system_status')[0].values
statusList = store.mapList.filter((item: any) => item.key === 'system_status')[0].values
} }
onMounted(() => { onMounted(() => {
categoryForm.category = props.editData.name console.log(props.editData, 'props.editData111')
categoryForm.hierarchy = props.editData.hierarchy + 1 getMapList()
categoryName.value = props.editData.category_name
categoryForm.depth = props.editData.depth
categoryForm.parent_id = props.editData.id
if (props.isEdit) { if (props.isEdit) {
categoryForm.hierarchy = props.editData.hierarchy categoryForm.depth = props.editData.depth
categoryForm.name = props.editData.name categoryForm.category_name = props.editData.category_name
categoryForm.status = props.editData.status categoryForm.status = props.editData.status
categoryForm.isCourse = props.editData.isCourse categoryForm.need_pass = props.editData.need_pass
} }
}) })
</script> </script>
<template> <template>
<el-dialog :model-value="dialogVisible" draggable :before-close="handleCancel" title="新增类别" width="60%"> <el-dialog :model-value="dialogVisible" draggable :before-close="handleCancel" :title="props.title" width="60%">
<el-form :model="categoryForm" label-position="right" label-width="auto" :rules="rules" ref="formRef"> <el-form :model="categoryForm" label-position="right" label-width="auto" :rules="rules" ref="formRef">
<el-form-item label="上级类别:" prop="category"> <el-form-item label="上级类别:" prop="parent_id">
<div @click="handleOpenTree" style="width: 100%"> <div @click="handleOpenTree" style="width: 100%">
<el-input v-model="categoryForm.category" disabled> <el-input v-model="categoryName" disabled>
<template #append> <template #append>
<el-button :icon="Search" /> <el-button :icon="Search" />
</template> </template>
...@@ -80,22 +115,20 @@ onMounted(() => { ...@@ -80,22 +115,20 @@ onMounted(() => {
</div> </div>
</el-form-item> </el-form-item>
<el-form-item label="类别层级:" prop="hierarchy"> <el-form-item label="类别层级:" prop="hierarchy">
<el-input v-model="categoryForm.hierarchy" disabled></el-input> <el-input v-model="categoryForm.depth" disabled></el-input>
</el-form-item> </el-form-item>
<el-form-item label="类别名称:" prop="name"> <el-form-item label="类别名称:" prop="category_name">
<el-input v-model="categoryForm.name"></el-input> <el-input v-model="categoryForm.category_name"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="状态:" prop="status"> <el-form-item label="状态:" prop="status">
<el-radio-group v-model="categoryForm.status"> <el-radio-group v-model="categoryForm.status">
<el-radio label="0">正常</el-radio> <el-radio v-for="(item, id) in statusList" :key="id" :label="item.value">{{ item.label }}</el-radio>
<el-radio label="1">停用</el-radio>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
<el-form-item label="互动课:" prop="isCourse"> <el-form-item label="互动课:" prop="need_pass">
<el-radio-group v-model="categoryForm.isCourse"> <el-radio-group v-model="categoryForm.need_pass">
<el-radio label="0"></el-radio> <el-radio v-for="(item, id) in classList" :key="id" :label="item.value">{{ item.label }}</el-radio>
<el-radio label="1"></el-radio>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
</el-form> </el-form>
...@@ -106,5 +139,7 @@ onMounted(() => { ...@@ -106,5 +139,7 @@ onMounted(() => {
</span> </span>
</template> </template>
</el-dialog> </el-dialog>
<TreeDialog v-model:isTreeVisible="isTreeVisible" @getCheckedLabel="getCheckedLabel" /> <template v-if="isTreeVisible">
<TreeDialog v-model:isTreeVisible="isTreeVisible" @getCheckedLabel="getCheckedLabel" />
</template>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { getCategoryList } from '../api'
import type { ElTree } from 'element-plus' import type { ElTree } from 'element-plus'
defineProps({ defineProps({
...@@ -9,116 +10,72 @@ defineProps({ ...@@ -9,116 +10,72 @@ defineProps({
}) })
const emit = defineEmits<{ const emit = defineEmits<{
(e: 'update:isTreeVisible', isTreeVisible: false): void (e: 'update:isTreeVisible', isTreeVisible: false): void
(e: 'getCheckedLabel', checkedLabel: any): void (e: 'getCheckedLabel', checkedCategory: any): void
}>() }>()
const handleCancel = () => { const handleCancel = () => {
emit('update:isTreeVisible', false) emit('update:isTreeVisible', false)
} }
interface ICategory {
interface Tree { category_name: string
id: number depth: string
label: string id: string
level: number lft: string
children?: Tree[] need_pass: string
rgt: string
status: string
children?: ICategory[]
} }
const filterText = ref('') let data = ref<ICategory[]>([])
const filterText = ref('') // 搜索字段
const treeRef = ref<InstanceType<typeof ElTree>>() const treeRef = ref<InstanceType<typeof ElTree>>()
const defaultProps = { const defaultProps = {
children: 'children', children: 'children',
label: 'label' label: 'category_name'
} }
const checkedLabel = ref('') // 默认选中项名称 const checkedCategory = {
const checkedLevel = ref('') // 默认选中项层级 checkedId: '',
checkedLabel: '', // 默认选中项名称
checkedLevel: 0 // 默认选中项层级
}
// 监听搜索
watch(filterText, val => { watch(filterText, val => {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion treeRef.value?.filter(val)
treeRef.value!.filter(val)
}) })
//搜索
const filterNode = (value: string, data: Tree) => { const filterNode = (value: string, data: ICategory) => {
console.log(value, 'value', data.category_name, 'data')
if (!value) return true if (!value) return true
return data.label.includes(value) return data.category_name.indexOf(value) != -1
} }
// 获取选中节点 // 获取选中节点
const handleNodeClick = (TreeNode: any, node: any, attr: any) => { const handleNodeClick = (TreeNode: any, node: any, attr: any) => {
console.log(TreeNode, node, attr, '999') console.log(TreeNode, node, attr, '999')
checkedLabel.value = TreeNode.label checkedCategory.checkedLabel = TreeNode.category_name // 类名
checkedLevel.value = TreeNode.level checkedCategory.checkedId = TreeNode.id // id
checkedCategory.checkedLevel = parseInt(TreeNode.depth) //层级
} }
// 确认 // 确认
const handleConfirm = () => { const handleConfirm = () => {
checkedLabel.value && emit('getCheckedLabel', { checkedLabel, checkedLevel }) checkedCategory.checkedLabel && emit('getCheckedLabel', { checkedCategory })
emit('update:isTreeVisible', false) emit('update:isTreeVisible', false)
} }
const defaultLabel = 'Level one 1'
const data: Tree[] = [
{
id: 1,
label: 'Level one 1',
level: 1,
children: [
{
id: 4,
label: 'Level two 1-1',
level: 2,
children: [
{
id: 9,
label: 'Level three 1-1-1',
level: 3
},
{
id: 10,
label: 'Level three 1-1-2',
level: 3
}
]
}
]
},
{
id: 2,
label: 'Level one 2',
level: 1,
children: [ // 获取分类列表
{ const handleCategoryList = () => {
id: 5, const params = { type: 'tree' }
label: 'Level two 2-1', getCategoryList(params).then((res: any) => {
level: 2 data.value = res.data
}, console.log(data, 'tableData')
{ })
id: 6, }
label: 'Level two 2-2', onMounted(() => {
level: 2 handleCategoryList()
} })
]
},
{
id: 3,
label: 'Level one 3',
level: 1,
children: [
{
id: 7,
label: 'Level two 3-1',
level: 2
},
{
id: 8,
label: 'Level two 3-2',
level: 2
}
]
}
]
</script> </script>
<template> <template>
<el-dialog :model-value="isTreeVisible" draggable :before-close="handleCancel" title="类别选择" width="40%"> <el-dialog :model-value="isTreeVisible" draggable :before-close="handleCancel" title="类别选择" width="40%">
...@@ -131,10 +88,10 @@ const data: Tree[] = [ ...@@ -131,10 +88,10 @@ const data: Tree[] = [
default-expand-all default-expand-all
:expand-on-click-node="false" :expand-on-click-node="false"
:highlight-current="true" :highlight-current="true"
:current-node-key="defaultLabel"
:filter-node-method="filterNode"
@node-click="handleNodeClick" @node-click="handleNodeClick"
:filter-node-method="filterNode"
/> />
<template #footer> <template #footer>
<span> <span>
<el-button @click="handleCancel">取消</el-button> <el-button @click="handleCancel">取消</el-button>
......
<script setup lang="ts"> <script setup lang="ts">
import Sortable from 'sortablejs' // import Sortable from 'sortablejs'
import AddDialog from '../component/AddDialog.vue' import AddDialog from '../component/AddDialog.vue'
import { Operation } from '@element-plus/icons-vue' import { Operation } from '@element-plus/icons-vue'
import { getCategoryList, delCategory, createCategory, updateCategory } from '../api'
import { ElMessage, ElMessageBox } from 'element-plus'
const loading = ref(false)
const statusMap = { 0: '正常', 1: '停用' } const prevCategoryName = ref('') // 上层类别
const title = ref('')
const form = reactive({ const dialogVisible = ref(false)
name: '' let form = reactive({
category_name: ''
}) })
const search = () => {
// 调接口 interface ICategory {
console.log('000') category_name: number
} depth: string
const reset = () => { id: string
console.log('111') lft: string
} need_pass: string
interface User { rgt: string
id: number
name: string
hierarchy: number
sort: number
status: string status: string
create_time: string children?: ICategory[]
isCourse: string
hasChildren?: boolean
children?: User[]
} }
let tableData = $ref<ICategory[]>([])
const tableData: User[] = [
{
id: 1,
name: '紫荆教育',
hierarchy: 1,
sort: 1,
status: '0',
create_time: '2022_11_22',
isCourse: '0',
children: [
{
id: 2,
name: '北京',
hierarchy: 2,
sort: 1,
status: '1',
create_time: '2022_11_22',
isCourse: '0',
children: [
{
id: 3,
name: '朝阳',
hierarchy: 3,
sort: 1,
status: '1',
create_time: '2022_11_22',
isCourse: '0'
},
{
id: 4,
name: '海淀',
hierarchy: 3,
sort: 2,
status: '1',
create_time: '2022_11_22',
isCourse: '1'
}
]
},
{
id: 5,
name: '河南',
hierarchy: 2,
sort: 2,
status: '1',
create_time: '2022_11_22',
isCourse: '1',
children: [
{
id: 6,
name: '信阳',
hierarchy: 3,
sort: 1,
status: '1',
create_time: '2022_11_22',
isCourse: '0'
},
{
id: 7,
name: '南阳',
hierarchy: 3,
sort: 2,
status: '1',
create_time: '2022_11_22',
isCourse: '1'
}
]
}
]
}
]
const editData = ref({}) const editData = ref({})
const isEdit = ref(false) const isEdit = ref(false)
const handleEdit = (index: number, row: User) => { const handleEdit = (index: number, row: ICategory) => {
title.value = '编辑类别'
isEdit.value = true isEdit.value = true
dialogVisible.value = true dialogVisible.value = true
editData.value = row editData.value = row
console.log(index, row)
} }
const handleDelete = (index: number, row: User) => { // 删除分类
console.log(index, row) const handleDelete = (index: number, row: ICategory) => {
ElMessageBox.confirm('确定要删除吗?', '提示').then(() => {
const params = { id: row.id }
delCategory(params).then(() => {
ElMessage.success('删除成功')
handleCategoryList()
})
})
} }
const dialogVisible = ref(false) // 新增类别
const handleAdd = (index: number, row: ICategory) => {
const handleAdd = (index: number, row: User) => {
isEdit.value = false isEdit.value = false
dialogVisible.value = true dialogVisible.value = true
console.log(index, row) title.value = '新增类别'
if (row) { if (row) {
editData.value = row editData.value = row
if (row.depth === '0') {
prevCategoryName.value = ''
}
} else { } else {
editData.value = tableData[0] editData.value = tableData[0]
} }
} }
const confirm = () => { // const sortable = (className: any, targetName: any) => {
console.log('0001111') // const table = document.querySelector('.' + className + ' .el-table__body-wrapper tbody') as HTMLElement
} // console.log(table)
// Sortable.create(table, {
// handle: '.handle',
// // 拖拽完毕后触发
// onEnd(data) {
// const newIndex = data.newIndex as number
// const oldIndex = data.oldIndex as number
// console.log(data, 'data')
// if (newIndex === oldIndex) return
const sortable = (className: any, targetName: any) => { // // targetName.splice(newIndex, 0, targetName.splice(oldIndex, 1))
const table = document.querySelector('.' + className + ' .el-table__body-wrapper tbody') as HTMLElement // console.log(targetName, 'pppp')
console.log(table) // }
Sortable.create(table, { // })
handle: '.handle', // }
// 拖拽完毕后触发 // 获取分类列表
onEnd(data) { const handleCategoryList = () => {
const newIndex = data.newIndex as number const params = { type: 'tree' }
const oldIndex = data.oldIndex as number getCategoryList(params)
console.log(data, 'data') .then((res: any) => {
if (newIndex === oldIndex) return loading.value = true
tableData = res.data
// targetName.splice(newIndex, 0, targetName.splice(oldIndex, 1)) })
console.log(targetName, 'pppp') .finally(() => {
loading.value = false
})
}
const handleConfirm = (val: any) => {
console.log(val, 'val')
if (val.isUpdate === 1) {
const params = Object.assign({ id: val.id }, val.categoryForm)
updateCategory(params).then(() => {
ElMessage.success('更新类别成功')
handleCategoryList()
})
} else if (val.isUpdate === 0) {
const params = Object.assign({}, val.categoryForm)
createCategory(params).then(() => {
ElMessage.success('新建类别成功')
handleCategoryList()
})
}
}
// 重置
const handleReset = () => {
form.category_name = ''
handleCategoryList()
}
// 搜索
const handleSearch = () => {
// 调接口
if (form.category_name) {
tableData = rebuildData(form.category_name, tableData)
}
}
// 重点代码 根据name字段模糊匹配树状结构数据,最后将处理好的数据返回出来
const rebuildData = (value: any, arr: any) => {
if (!arr) {
return []
}
let newArr: any = []
arr.forEach((element: any) => {
console.log(element, 'element')
// indexOf用来判读当前节点name字段是否包含所搜索的字符串value
// 返回值:包含则返回索引值,反之返回-1
if (element.category_name.indexOf(value) > -1) {
const ab = rebuildData(value, element.children)
const obj = {
...element,
children: ab
}
newArr.push(obj)
} else {
// 判断当前节点知否有子节点,并且子节点中有数据,有数据继续递归查找
if (element.children && element.children.length > 0) {
const ab = rebuildData(value, element.children)
const obj = {
...element,
children: ab
}
if (ab && ab.length > 0) {
newArr.push(obj)
}
}
} }
}) })
return newArr
} }
onMounted(() => { onMounted(() => {
sortable('t1', tableData) // 参数分别为table的class名称,table的数据data // sortable('t1', tableData) // 参数分别为table的class名称,table的数据data
handleCategoryList()
}) })
</script> </script>
<template> <template>
...@@ -152,11 +158,11 @@ onMounted(() => { ...@@ -152,11 +158,11 @@ onMounted(() => {
<div class="table-list-filter"> <div class="table-list-filter">
<el-form class="filter-form" :model="form"> <el-form class="filter-form" :model="form">
<el-form-item label="类别名称:" prop="name"> <el-form-item label="类别名称:" prop="name">
<el-input v-model="form.name"></el-input> <el-input v-model="form.category_name"></el-input>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-button type="primary" @click="search" class="btn_query">搜索</el-button> <el-button type="primary" @click="handleSearch" class="btn_query">搜索</el-button>
<el-button @click="reset">重置</el-button> <el-button @click="handleReset">重置</el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>
</div> </div>
...@@ -169,16 +175,14 @@ onMounted(() => { ...@@ -169,16 +175,14 @@ onMounted(() => {
ref="dragTable" ref="dragTable"
:tree-props="{ children: 'children', hasChildren: 'hasChildren', draggable: true }" :tree-props="{ children: 'children', hasChildren: 'hasChildren', draggable: true }"
highlight-current-row highlight-current-row
v-loading="loading"
> >
<el-table-column type="index" align="center" class-name="handle"> <el-table-column type="index" align="center" class-name="handle">
<el-icon><Operation /></el-icon> <el-icon><Operation /></el-icon>
</el-table-column> </el-table-column>
<el-table-column prop="name" label="类别名称" align="center" class-name="handle" /> <el-table-column prop="category_name" label="类别名称" align="center" class-name="handle" />
<el-table-column prop="hierarchy" label="层级" align="center" /> <el-table-column prop="depth" label="层级" align="center" />
<el-table-column prop="status" label="状态" align="center"> <el-table-column prop="status" label="状态" align="center"> </el-table-column>
<template #default="scope"> {{ statusMap[scope.row.status] }}</template>
</el-table-column>
<el-table-column prop="create_time" label="创建时间" align="center" />
<el-table-column align="center" label="操作" width="300px"> <el-table-column align="center" label="操作" width="300px">
<template #default="scope"> <template #default="scope">
<el-button type="primary" @click="handleEdit(scope.$index, scope.row)">编辑</el-button> <el-button type="primary" @click="handleEdit(scope.$index, scope.row)">编辑</el-button>
...@@ -189,7 +193,13 @@ onMounted(() => { ...@@ -189,7 +193,13 @@ onMounted(() => {
</el-table> </el-table>
</AppCard> </AppCard>
<template v-if="dialogVisible === true"> <template v-if="dialogVisible === true">
<AddDialog v-model:dialogVisible="dialogVisible" @confirm="confirm" :editData="editData" :isEdit="isEdit" /> <AddDialog
v-model:dialogVisible="dialogVisible"
@confirm="handleConfirm"
:editData="editData"
:isEdit="isEdit"
:title="title"
/>
</template> </template>
</template> </template>
<style lang="scss" scoped> <style lang="scss" scoped>
......
import httpRequest from '@/utils/axios' import httpRequest from '@/utils/axios'
// 获取视频列表 // 获取讲师列表
export function getVideoList(params?: { type?: string; page?: number; page_size?: number }) {
return httpRequest.get('/api/psp/backend/video/index', { params }) export function getTeacherList(params?: { type?: string; page?: number; ['per-page']?: number }) {
return httpRequest.get('/api/resource/v1/backend/lecturer/list', { params })
}
// 删除讲师
export function deleteTeacher(data: { id: string }) {
return httpRequest.post('/api/resource/v1/backend/lecturer/delete', data)
}
// 更新讲师
export function updateTeacher(data: {
id: string
name: string
avatar: string
status: string
title: string
office: string
education: string
summarize: string
}) {
return httpRequest.post('/api/resource/v1/backend/lecturer/update', data)
}
// 创建讲师
export function createTeacher(data: {
name: string
avatar: string
title: string
status: string
office: string
education: string
summarize: string
}) {
return httpRequest.post('/api/resource/v1/backend/lecturer/create', data)
}
// 获取讲师详情
export function getTeacherDetail(params: { id: string }) {
return httpRequest.get('/api/resource/v1/backend/lecturer/view', { params })
} }
<script setup lang="ts"> <script setup lang="ts">
import { createTeacher } from '../api'
import VEditor from '@tinymce/tinymce-vue' import VEditor from '@tinymce/tinymce-vue'
import AppUpload from '@/components/base/AppUpload.vue' import AppUpload from '@/components/base/AppUpload.vue'
import { useRouter } from 'vue-router' import { ElMessage } from 'element-plus'
import { reactive, ref } from 'vue'
import type { FormInstance, FormRules } from 'element-plus' import type { FormInstance, FormRules } from 'element-plus'
const router = useRouter() const router = useRouter()
const formSize = ref('default') const formSize = ref('default')
const ruleFormRef = ref<FormInstance>() const ruleFormRef = ref<FormInstance>()
let ruleForm = reactive({ let ruleForm = reactive({
id: '', id: '',
name: '', status: '1',
position: '', name: '', // 姓名
education: '', title: '', // 职位
mechanism: '', education: '', // 学历
desc: '', office: '', // 讲师任职机构
imageUrl: '' avatar: '', // 头像
summarize: '' // 讲师简介
}) })
const rules = reactive<FormRules>({ const rules = reactive<FormRules>({
name: [ name: [
...@@ -25,7 +26,7 @@ const rules = reactive<FormRules>({ ...@@ -25,7 +26,7 @@ const rules = reactive<FormRules>({
trigger: 'blur' trigger: 'blur'
} }
], ],
position: [ title: [
{ {
required: true, required: true,
message: '请输入讲师职位', message: '请输入讲师职位',
...@@ -36,14 +37,13 @@ const rules = reactive<FormRules>({ ...@@ -36,14 +37,13 @@ const rules = reactive<FormRules>({
const submitForm = async (formEl: FormInstance | undefined) => { const submitForm = async (formEl: FormInstance | undefined) => {
if (!formEl) return if (!formEl) return
await formEl.validate((valid, fields) => { await formEl.validate(valid => {
if (valid) { if (valid) {
console.log('submit!') const params = Object.assign({}, ruleForm)
router.push('/admin/teacher') createTeacher(params).then(() => {
} else { ElMessage.success('创建讲师成功')
router.push('/admin/teacher') router.push('/admin/teacher')
})
console.log('error submit!', fields)
} }
}) })
} }
...@@ -66,8 +66,8 @@ const submitForm = async (formEl: FormInstance | undefined) => { ...@@ -66,8 +66,8 @@ const submitForm = async (formEl: FormInstance | undefined) => {
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="10"> <el-col :span="10">
<el-form-item label="讲师职位:" prop="position"> <el-form-item label="讲师职位:" prop="title">
<el-input v-model="ruleForm.position" /> <el-input v-model="ruleForm.title" />
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
...@@ -78,22 +78,22 @@ const submitForm = async (formEl: FormInstance | undefined) => { ...@@ -78,22 +78,22 @@ const submitForm = async (formEl: FormInstance | undefined) => {
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="10"> <el-col :span="10">
<el-form-item label="讲师任职机构:" prop="mechanism"> <el-form-item label="讲师任职机构:" prop="office">
<el-input v-model="ruleForm.mechanism" /> <el-input v-model="ruleForm.office" />
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<el-row> <el-row>
<el-col :span="10"> <el-col :span="10">
<el-form-item label="讲师头像:" prop="imageUrl"> <el-form-item label="讲师头像:" prop="avatar">
<AppUpload v-model="ruleForm.imageUrl" /> <AppUpload v-model="ruleForm.avatar" />
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<el-row> <el-row>
<el-col :span="24"> <el-col :span="24">
<el-form-item label="讲师简介:" prop="desc"> <el-form-item label="讲师简介:" prop="summarize">
<v-editor v-model="ruleForm.desc" class="editor" style="width: 1000px"></v-editor> <v-editor v-model="ruleForm.summarize" class="editor" style="width: 1000px"></v-editor>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
......
<script setup lang="ts"> <script setup lang="ts">
import { getTeacherDetail, updateTeacher } from '../api'
import { ElMessage } from 'element-plus'
import type { FormRules, FormInstance } from 'element-plus'
import VEditor from '@tinymce/tinymce-vue' import VEditor from '@tinymce/tinymce-vue'
import type { FormRules } from 'element-plus' import AppUpload from '@/components/base/AppUpload.vue'
const router = useRouter()
const route = useRoute() const route = useRoute()
const appList = ref()
const id = route.query.id as string
const title = route.query.title as string const title = route.query.title as string
const formSize = ref('default') const isEdit = route.query.isEdit as string
const ruleFormRef = ref<FormInstance>()
const ruleForm = reactive({ const ruleForm = reactive({
id: '',
name: '', name: '',
position: '', title: '', // 职位
education: '', education: '', // 学历
mechanism: '', office: '', // 讲师任职机构
introduce: '', summarize: '', // 讲师简介
picture: '', avatar: '', //讲师图片
desc: '' status: '1'
}) })
const url = JSON.parse(route.query.form + '').imageUrl as string
const appList = ref()
const rules = reactive<FormRules>({ const rules = reactive<FormRules>({
name: [ name: [{ required: true, message: '请输入讲师姓名', trigger: 'blur' }],
{ required: true, message: 'Please input Activity name', trigger: 'blur' }, title: [{ required: true, message: ' 请输入职位', trigger: 'blur' }]
{ min: 3, max: 5, message: 'Length should be 3 to 5', trigger: 'blur' }
],
position: [
{
required: true,
message: 'Please select Activity zone',
trigger: 'change'
}
],
date1: [
{
type: 'date',
required: true,
message: 'Please pick a date',
trigger: 'change'
}
],
date2: [
{
type: 'date',
required: true,
message: 'Please pick a time',
trigger: 'change'
}
],
type: [
{
type: 'array',
required: true,
message: 'Please select at least one activity type',
trigger: 'change'
}
],
resource: [
{
required: true,
message: 'Please select activity resource',
trigger: 'change'
}
]
}) })
const listOptions = { const listOptions = {
remote: { remote: {
// httpRequest: getVideoList,
params: { type: '' } params: { type: '' }
}, },
columns: [ columns: [
{ label: '#', type: 'index', align: 'center' }, { label: '#', type: 'index', align: 'center' },
{ label: '课程图片', slots: 'table-cover', align: 'center' }, { label: '课程图片', slots: 'table-cover', align: 'center' },
...@@ -78,55 +42,71 @@ const listOptions = { ...@@ -78,55 +42,71 @@ const listOptions = {
{ label: '创建时间', prop: 'created_time', align: 'center' }, { label: '创建时间', prop: 'created_time', align: 'center' },
{ label: '编辑', prop: 'created_time', align: 'center' }, { label: '编辑', prop: 'created_time', align: 'center' },
{ label: '操作', slots: 'table-operate', width: 300, align: 'center' } { label: '操作', slots: 'table-operate', width: 300, align: 'center' }
],
data: [
{ id: 1, title: '视频标题', type: '视频分类' },
{ id: 2, title: '视频标题', type: '视频分类' }
] ]
} }
const handleDelete = (row: any) => { const handleDelete = (row: any) => {
console.log('删除', row) console.log('删除', row)
} }
const getUpdateForm = () => { const getTeacherInfo = () => {
const editForm = JSON.parse(route.query.form + '') getTeacherDetail({ id: id }).then(res => {
Object.keys(ruleForm).forEach(key => { console.log(res.data)
ruleForm[key] = editForm[key] Object.keys(ruleForm).forEach(key => {
ruleForm[key] = res.data[key]
})
})
}
// 更新讲师
const handleUpdate = async (formEl: FormInstance | undefined) => {
if (!formEl) return
await formEl.validate(valid => {
if (valid) {
const params = Object.assign({}, ruleForm)
updateTeacher(params).then(() => {
ElMessage.success('创建讲师成功')
router.push('/admin/teacher')
})
}
}) })
} }
onMounted(() => { onMounted(() => {
// 更新获取讲师信息 // 更新获取讲师信息
getUpdateForm() getTeacherInfo()
}) })
</script> </script>
<template> <template>
<AppCard :title="title"> <AppCard :title="title">
<el-form :model="ruleForm" :size="formSize" :rules="rules" label-position="right" label-width="100px"> <el-form ref="ruleFormRef" :model="ruleForm" :rules="rules" label-position="right" label-width="100px">
<el-row> <el-row>
<el-col :span="4"> <el-col :span="8">
<el-form-item label="讲师图片:" prop="picture"> <el-form-item label="讲师图片:" prop="avatar">
<el-image style="width: 300px" :src="url" /> <div v-if="isEdit === '1'">暂无照片</div>
<AppUpload v-model="ruleForm.avatar" v-else />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="8" style="margin-left: 80px"> <el-col :span="8" style="margin-left: 80px">
<el-form-item label="讲师姓名:" prop="name"> <el-form-item label="讲师姓名:" prop="name">
<el-input v-model="ruleForm.name" /> <el-input v-model="ruleForm.name" :disabled="isEdit === '1'" />
</el-form-item> </el-form-item>
<el-form-item label="讲师职位:" prop="position"> <el-form-item label="讲师职位:" prop="title">
<el-input v-model="ruleForm.position" /> <el-input v-model="ruleForm.title" :disabled="isEdit === '1'" />
</el-form-item> </el-form-item>
<el-form-item label="讲师学历:" prop="education"> <el-form-item label="讲师学历:" prop="education">
<el-input v-model="ruleForm.education" /> <el-input v-model="ruleForm.education" :disabled="isEdit === '1'" />
</el-form-item> </el-form-item>
<el-form-item label="讲师任职机构:" prop="mechanism"> <el-form-item label="讲师任职机构:" prop="office">
<el-input v-model="ruleForm.mechanism" /> <el-input v-model="ruleForm.office" :disabled="isEdit === '1'" />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-form-item>
<el-button type="primary" v-if="isEdit !== '1'" @click="handleUpdate(ruleFormRef)">保存</el-button>
</el-form-item>
</el-row> </el-row>
<el-form-item label="讲师简介:" prop="introduce"> <el-form-item label="讲师简介:" prop="summarize">
<v-editor v-model="ruleForm.introduce" style="width: 70%"></v-editor> <v-editor v-model="ruleForm.summarize" style="width: 70%" :disabled="isEdit === '1'"></v-editor>
</el-form-item> </el-form-item>
</el-form> </el-form>
<el-card> <el-card>
......
<script setup lang="ts"> <script setup lang="ts">
// import { getVideoList } from '../api' import { ElMessage,ElMessageBox } from 'element-plus'
import { getTeacherList, deleteTeacher } from '../api'
const router = useRouter() const router = useRouter()
const appList = ref() const appList = ref()
const listOptions = { const listOptions = {
remote: { remote: {
// httpRequest: getVideoList, httpRequest: getTeacherList,
params: { type: '' } params: { type: '' }
}, },
filters: [ filters: [
{ type: 'input', prop: 'type', label: '讲师姓名:' }, { type: 'input', prop: 'name', label: '讲师姓名:' },
{ type: 'input', prop: 'project_id', label: '讲师任职机构:' }, { type: 'input', prop: 'office', label: '讲师任职机构:' },
{ type: 'input', prop: 'category_id', label: '讲师职位:' }, { type: 'input', prop: 'title', label: '讲师职位:' },
{ type: 'input', prop: 'category_id', label: '讲师学历:' } { type: 'input', prop: 'education', label: '讲师学历:' }
], ],
columns: [ columns: [
{ label: '#', type: 'index', align: 'center' }, { label: '#', type: 'index', align: 'center' },
{ label: '讲师头像', slots: 'table-img', align: 'center' }, { label: '讲师头像', slots: 'table-img', align: 'center' },
{ label: '讲师姓名', prop: 'name', align: 'center' }, { label: '讲师姓名', prop: 'name', align: 'center' },
{ label: '讲师任职机构', prop: 'mechanism', align: 'center' }, { label: '讲师任职机构', prop: 'office', align: 'center' },
{ label: '讲师职位', prop: 'position', align: 'center' }, { label: '讲师职位', prop: 'title', align: 'center' },
{ label: '讲师学历', prop: 'education', align: 'center' }, { label: '讲师学历', prop: 'education', align: 'center' },
{ label: '编辑', prop: 'edit', align: 'center' },
{ label: '创建时间', prop: 'created_time', align: 'center' }, { label: '创建时间', prop: 'created_time', align: 'center' },
{ label: '操作', slots: 'table-operate', width: 230, align: 'center' } { label: '操作', slots: 'table-operate', width: 230, align: 'center' }
],
data: [
{
id: 1,
imageUrl: 'https://img0.baidu.com/it/u=1872881124,390027250&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=333',
name: '章三',
mechanism: '紫荆',
position: '讲师',
education: '本科',
edit: '123',
created_time: '2022-05-30'
}
] ]
} }
// 删除讲师
const handleDelete = (row: any) => { const handleDelete = (row: any) => {
console.log('删除', row) ElMessageBox.confirm('确定要删除吗?', '提示').then(() => {
deleteTeacher({ id: row.id }).then(() => {
ElMessage.success('删除成功')
appList.value.refetch()
})
})
} }
// 更新讲师
const handleUpdate = (row: any) => { const handleUpdate = (row: any) => {
console.log(row)
router.push({ router.push({
path: '/admin/teacher/detail', path: '/admin/teacher/detail',
query: { query: {
form: JSON.stringify(row), id: row.id,
isEdit: '0',
title: '更新讲师' title: '更新讲师'
} }
}) })
} }
//讲师详情
const handleDetail = (row: any) => {
console.log(row.id)
router.push({
path: '/admin/teacher/detail',
query: {
id: row.id,
isEdit: '1',
title: '讲师详情'
}
})
}
</script> </script>
<template> <template>
...@@ -60,13 +66,11 @@ const handleUpdate = (row: any) => { ...@@ -60,13 +66,11 @@ const handleUpdate = (row: any) => {
<el-button type="primary" round>添加讲师</el-button> <el-button type="primary" round>添加讲师</el-button>
</router-link> </router-link>
<template #header-aside> </template> <template #header-aside> </template>
<template #table-img="{ row }"> <img :src="row.imageUrl" alt="" style="width: 100%" /></template> <template #table-img="{ row }"> <img :src="row.avatar" alt="" style="width: 100%" /></template>
<template #table-operate="{ row }"> <template #table-operate="{ row }">
<el-space> <el-space>
<router-link :to="{ path: '/admin/teacher/detail', query: { title: '讲师详情', form: JSON.stringify(row) } }"> <el-button type="primary" plain @click="handleDetail(row)">查看</el-button>
<el-button type="primary" plain>查看</el-button>
</router-link>
<el-button type="primary" plain @click="handleUpdate(row)">更新</el-button> <el-button type="primary" plain @click="handleUpdate(row)">更新</el-button>
<el-button type="primary" plain @click="handleDelete(row)">删除</el-button> <el-button type="primary" plain @click="handleDelete(row)">删除</el-button>
</el-space> </el-space>
......
...@@ -2,5 +2,5 @@ import httpRequest from '@/utils/axios' ...@@ -2,5 +2,5 @@ import httpRequest from '@/utils/axios'
// 获取视频列表 // 获取视频列表
export function getVideoList(params?: { type?: string; page?: number; page_size?: number }) { export function getVideoList(params?: { type?: string; page?: number; page_size?: number }) {
return httpRequest.get('/api/psp/backend/video/index', { params }) return httpRequest.get('/api/resource/backend/video/index', { params })
} }
...@@ -2,20 +2,20 @@ import httpRequest from '@/utils/axios' ...@@ -2,20 +2,20 @@ import httpRequest from '@/utils/axios'
// 获取视频列表 // 获取视频列表
export function getVideoList(params?: { type?: string; page?: number; page_size?: number }) { export function getVideoList(params?: { type?: string; page?: number; page_size?: number }) {
return httpRequest.get('/api/psp/backend/video/index', { params }) return httpRequest.get('/api/resource/backend/video/index', { params })
} }
// 创建视频 // 创建视频
export function createVideo(data: { course_name: string; cover_page: string; type: string; weight?: string }) { export function createVideo(data: { course_name: string; cover_page: string; type: string; weight?: string }) {
return httpRequest.post('/api/psp/backend/video/create', data) return httpRequest.post('/api/resource/backend/video/create', data)
} }
// 更新视频 // 更新视频
export function updateVideo(data: { id: string; course_name: string; cover_page: string; type: string; weight?: string }) { export function updateVideo(data: { id: string; course_name: string; cover_page: string; type: string; weight?: string }) {
return httpRequest.post('/api/psp/backend/video/update', data) return httpRequest.post('/api/resource/backend/video/update', data)
} }
// 获取视频详情 // 获取视频详情
export function getVideo(params: { id: string }) { export function getVideo(params: { id: string }) {
return httpRequest.get('/api/psp/backend/video/view', { params }) return httpRequest.get('/api/resource/backend/video/view', { params })
} }
import httpRequest from '@/utils/axios' import httpRequest from '@/utils/axios'
// 获取视频列表 // 获取封面列表
export function getVideoList(params?: { type?: string; page?: number; page_size?: number }) { export function getCoverList(params?: { type?: string; page?: number; page_size?: number }) {
return httpRequest.get('/api/psp/backend/video/index', { params }) return httpRequest.get('/api/resource/v1/backend/cover/list', { params })
}
// 创建封面
export function createCover(data?: { title?: string; status?: number; type?: number; url?: number }) {
return httpRequest.post('/api/resource/v1/backend/cover/create', data)
}
// 更新封面
export function updateCover(data?: { title?: string; status?: number; type?: number; url?: number }) {
return httpRequest.post('/api/resource/v1/backend/cover/update', data)
}
// 删除封面
export function deleteCover(data: { id: any }) {
return httpRequest.post('/api/resource/v1/backend/cover/delete', data)
}
// 获取公共字典列表
export function getMapList() {
return httpRequest.get('/api/resource/v1/util/get-data-dictionary-list')
} }
<script lang="ts" setup> <script lang="ts" setup>
// import { getMapList } from '../api'
import AppUpload from '@/components/base/AppUpload.vue' import AppUpload from '@/components/base/AppUpload.vue'
import type { FormInstance, FormRules } from 'element-plus'
import { useMapStore } from '@/stores/map'
const store = useMapStore()
interface mapList {
label: string
value: string
data_dictionary_id: string
sort: string
remark: string
id: string
}
// 封面类型
let typeList = $ref<mapList[]>([])
// 封面状态
let statusList = $ref<mapList[]>([])
const form = reactive({ const form = reactive({
status: '0', title: '',
imageUrl: '', status: '1',
type: '0' url: '',
type: '1'
}) })
const rules = { const rules = reactive<FormRules>({
status: [{ required: true, message: '请选择状态', trigger: 'blur' }], status: [{ required: true, message: '请选择状态', trigger: 'blur' }],
imageUrl: [{ required: true, message: '请上传图片', trigger: 'change' }], url: [{ required: true, message: '请上传图片', trigger: 'change' }],
type: [{ required: true, message: '请选择封面类型', trigger: 'blur' }] type: [{ required: true, message: '请选择封面类型', trigger: 'blur' }]
} })
const props = defineProps({ const props = defineProps({
isShowDialog: { isShowDialog: {
type: Boolean, type: Boolean,
...@@ -27,10 +44,11 @@ const props = defineProps({ ...@@ -27,10 +44,11 @@ const props = defineProps({
}) })
interface Emits { interface Emits {
(e: 'update:isShowDialog', isShowDialog: boolean): void (e: 'update:isShowDialog', isShowDialog: boolean): void
(e: 'confirm'): void (e: 'createCover', form: any): void
} }
const emit = defineEmits<Emits>() const emit = defineEmits<Emits>()
const ruleFormRef = ref<FormInstance>()
// 普通属性 // 普通属性
...@@ -40,32 +58,47 @@ const handleCancel = () => { ...@@ -40,32 +58,47 @@ const handleCancel = () => {
// 确定 // 确定
const handleConfirm = () => { const handleConfirm = () => {
emit('update:isShowDialog', false) emit('update:isShowDialog', false)
emit('confirm') if (props.isEdit === true) {
emit('createCover', { form, isUpdate: 1, id: props.editData.id })
} else {
form.title = form.url
emit('createCover', { form, isUpdate: 0 })
}
} }
const getMapList = async () => {
await store.getMapList()
typeList = store.mapList.filter((item: any) => item.key === 'system_cover_type')[0].values
statusList = store.mapList.filter((item: any) => item.key === 'system_status')[0].values
}
const change = () => {
console.log(form, statusList)
}
onMounted(() => { onMounted(() => {
if (props.isEdit) { if (props.isEdit) {
form.status = props.editData.status form.status = props.editData.status
form.imageUrl = props.editData.cover_img form.url = props.editData.url
form.type = props.editData.type form.type = props.editData.type
form.title = props.editData.url
} }
getMapList()
}) })
</script> </script>
<template> <template>
<el-dialog :model-value="isShowDialog" draggable :before-close="handleCancel" width="30%"> <el-dialog :model-value="isShowDialog" draggable :before-close="handleCancel" width="30%">
<el-form :model="form" :rules="rules"> <el-form :model="form" :rules="rules" ref="ruleFormRef">
<el-form-item label="封面类型:" prop="type"> <el-form-item label="封面类型:" prop="type">
<el-select v-model="form.type"> <el-select v-model="form.type">
<el-option label="课程" value="0"></el-option> <el-option v-for="(item, id) in typeList" :key="id" :label="item.label" :value="item.value"></el-option>
<el-option label="视频" value="1"></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="图片地址:" prop="imageUrl"> <el-form-item label="图片地址:" prop="url">
<AppUpload v-model="form.imageUrl" /> <AppUpload v-model="form.url" />
</el-form-item> </el-form-item>
<el-form-item label="状态:" prop="status"> <el-form-item label="状态:" prop="status">
<el-radio-group v-model="form.status"> <el-radio-group v-model="form.status" @change="change()">
<el-radio label="0">成功</el-radio> <el-radio v-for="(item, id) in statusList" :key="id" :label="item.value">{{ item.label }}</el-radio>
<el-radio label="1">失败</el-radio>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
</el-form> </el-form>
......
<script setup lang="ts"> <script setup lang="ts">
import { getCoverList, createCover, updateCover, deleteCover } from '../api'
import { ElMessage, ElMessageBox } from 'element-plus'
import AddDialog from '../component/AddDialog.vue' import AddDialog from '../component/AddDialog.vue'
const appList = ref() const appList = ref()
const isShowDialog = ref(false) const isShowDialog = ref(false)
const isEdit = ref(false) const isEdit = ref(false)
const editData = ref({}) const editData = ref({})
const listOptions = { const listOptions = {
remote: { remote: {
// httpRequest: getVideoList, httpRequest: getCoverList,
params: { type: '' } params: { type: '' }
}, },
columns: [ columns: [
{ label: '封面地址', prop: 'cover_url', align: 'center' }, { label: '封面地址', prop: 'url', align: 'center' },
{ label: '封面预览', prop: 'cover_img', slots: 'table-cover', align: 'center' }, { label: '封面预览', prop: 'url', slots: 'table-cover', align: 'center' },
{ label: '封面类型', prop: 'type', align: 'center' }, { label: '封面类型', prop: 'type_name', align: 'center' },
{ {
label: '状态', label: '状态',
prop: 'status', prop: 'status_name',
align: 'center', align: 'center'
computed(row: any) {
console.log(row)
if (row.row.status === '0') {
return '正常'
} else if (row.row.status === '1') {
return '停用'
} else {
return '-'
}
}
}, },
{ label: '创建时间', prop: 'created_time', align: 'center' }, { label: '创建时间', prop: 'created_time', align: 'center' },
{ label: '操作', slots: 'table-operate', width: 230, align: 'center' } { label: '操作', slots: 'table-operate', width: 230, align: 'center' }
],
data: [
{
id: 1,
cover_url: 'https://img0.baidu.com/it/u=1106810636,3829865668&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=505',
cover_img: 'https://img0.baidu.com/it/u=1106810636,3829865668&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=505',
type: '视频',
status: '0',
created_time: '2022-06-01'
}
] ]
} }
// 删除 // 删除
const handleDelete = (row: any) => { const handleDelete = (row: any) => {
console.log('删除', row) ElMessageBox.confirm('确定要删除吗?', '提示').then(() => {
const params: any = { id: row.id }
deleteCover(params).then(() => {
ElMessage.success('删除成功')
appList.value.refetch()
})
})
} }
// 确定 // 确定
const handleConfirm = () => { const handleConfirm = (val: any) => {
console.log('123') if (val.isUpdate === 1) {
// 更新封面
const params = Object.assign({ id: val.id }, val.form)
updateCover(params).then(() => {
appList.value.refetch()
})
} else {
// 添加封面
const params = Object.assign({}, val.form)
createCover(params).then(() => {
appList.value.refetch()
})
}
} }
// 添加 // 添加
const handleAdd = () => { const handleAdd = () => {
...@@ -70,7 +71,7 @@ const handleEdit = (row: any) => { ...@@ -70,7 +71,7 @@ const handleEdit = (row: any) => {
<AppList v-bind="listOptions" ref="appList"> <AppList v-bind="listOptions" ref="appList">
<template #header-aside> </template> <template #header-aside> </template>
<template #table-cover="{ row }"> <template #table-cover="{ row }">
<img :src="row.cover_img" alt="" style="width: 100px" /> <img :src="row.url" alt="" style="width: 100px" />
</template> </template>
<template #table-operate="{ row }"> <template #table-operate="{ row }">
<el-space> <el-space>
...@@ -79,7 +80,12 @@ const handleEdit = (row: any) => { ...@@ -79,7 +80,12 @@ const handleEdit = (row: any) => {
</el-space> </el-space>
</template> </template>
<template v-if="isShowDialog === true"> <template v-if="isShowDialog === true">
<AddDialog v-model:isShowDialog="isShowDialog" @confirm="handleConfirm" :editData="editData" :isEdit="isEdit" /> <AddDialog
v-model:isShowDialog="isShowDialog"
@createCover="handleConfirm"
:editData="editData"
:isEdit="isEdit"
/>
</template> </template>
</AppList> </AppList>
</AppCard> </AppCard>
......
...@@ -2,5 +2,75 @@ import httpRequest from '@/utils/axios' ...@@ -2,5 +2,75 @@ import httpRequest from '@/utils/axios'
// 获取视频列表 // 获取视频列表
export function getVideoList(params?: { type?: string; page?: number; page_size?: number }) { export function getVideoList(params?: { type?: string; page?: number; page_size?: number }) {
return httpRequest.get('/api/psp/backend/video/index', { params }) return httpRequest.get('/api/resource/backend/video/index', { params })
} }
// 获取字典列表
export function getDictionaryList(params?: {
name?: string
key?: number
status?: boolean
created_time_start?: string
created_time_end?: string
page?: number
page_size?: number
}) {
return httpRequest.get('/api/resource/v1/backend/data-dictionary/list', { params })
}
// 新增字典
export function createDictionary(data: {
name: string
key: number
status: boolean
remark: string
can_edit: string
}) {
return httpRequest.post('/api/resource/v1/backend/data-dictionary/create', data)
}
// 更新字典
export function updateDictionary(data: {
id: string
name: string
key: number
status: boolean
remark: string
can_edit: string
}) {
return httpRequest.post('/api/resource/v1/backend/data-dictionary/update', data)
}
// 删除字典
export function delDictionary(data: { id: string }) {
return httpRequest.post('/api/resource/v1/backend/data-dictionary/delete', data)
}
// 获取字典的值的列表
export function getDictionaryItemList(params?: { data_dictionary_id: string; page?: number; page_size?: number }) {
return httpRequest.get('/api/resource/v1/backend/data-dictionary/value-list', { params })
}
// 新增字典的值
export function createDictionaryItem(data: {
data_dictionary_id: string
label: number
value: boolean
sort: string
remark: string
can_edit: string
status: string
}) {
return httpRequest.post('/api/resource/v1/backend/data-dictionary/value-create', data)
}
// 新增字典的值
export function updateDictionaryItem(data: {
id: string
data_dictionary_id: string
label: number
value: boolean
sort: string
remark: string
can_edit: string
status: string
}) {
return httpRequest.post('/api/resource/v1/backend/data-dictionary/value-update', data)
}
// 删除字典的值
export function delDictionaryItem(data: { id: string }) {
return httpRequest.post('/api/resource/v1/backend/data-dictionary/value-delete', data)
}
\ No newline at end of file
<script lang="ts" setup> <script lang="ts" setup>
import type { IMapList } from '../types'
import { useMapStore } from '@/stores/map'
import type { FormInstance, FormRules } from 'element-plus'
const store = useMapStore()
const ruleFormRef = ref<FormInstance>()
const form = reactive({ const form = reactive({
name: '', name: '',
type: '', key: '',
status: '0', status: '1',
remark: '' remark: '',
}) })
const rules = { let statusList = $ref<IMapList[]>([])
const rules = reactive<FormRules>({
name: [{ required: true, message: '请输入字典名称', trigger: 'blur' }], name: [{ required: true, message: '请输入字典名称', trigger: 'blur' }],
type: [{ required: true, message: '请输入字典类型', trigger: 'blur' }] key: [{ required: true, message: '请输入字典类型', trigger: 'blur' }]
} })
const props = defineProps({ const props = defineProps({
isShowDialog: { isShowDialog: {
type: Boolean, type: Boolean,
...@@ -25,7 +34,7 @@ const props = defineProps({ ...@@ -25,7 +34,7 @@ const props = defineProps({
}) })
interface Emits { interface Emits {
(e: 'update:isShowDialog', isShowDialog: boolean): void (e: 'update:isShowDialog', isShowDialog: boolean): void
(e: 'confirm'): void (e: 'confirm', form: object): void
} }
const emit = defineEmits<Emits>() const emit = defineEmits<Emits>()
...@@ -36,19 +45,35 @@ const handleCancel = () => { ...@@ -36,19 +45,35 @@ const handleCancel = () => {
emit('update:isShowDialog', false) emit('update:isShowDialog', false)
} }
// 确定 // 确定
const handleConfirm = () => { const handleConfirm = async (formEl: FormInstance | undefined) => {
emit('update:isShowDialog', false) if (!formEl) return
emit('confirm') await formEl.validate(valid => {
if (valid) {
if (props.isEdit === true) {
emit('update:isShowDialog', false)
emit('confirm', { form, isUpdate: 1, id: props.rowInfo.id })
} else {
emit('update:isShowDialog', false)
emit('confirm', { form, isUpdate: 0 })
}
}
})
}
const getMapList = async () => {
await store.getMapList()
statusList = store.mapList.filter((item: any) => item.key === 'system_status')[0].values
console.log(statusList, 'statusList')
} }
onMounted(() => { onMounted(() => {
getMapList()
console.log(props.rowInfo, 'props.rowInfo') console.log(props.rowInfo, 'props.rowInfo')
if (props.isEdit) { if (props.isEdit) {
form.name = props.rowInfo.name form.name = props.rowInfo.name
form.type = props.rowInfo.type form.key = props.rowInfo.key
if (props.rowInfo.status === '正常') { if (props.rowInfo.status === '有效') {
form.status = '0'
} else {
form.status = '1' form.status = '1'
} else {
form.status = '0'
} }
form.remark = props.rowInfo.remark form.remark = props.rowInfo.remark
} }
...@@ -61,18 +86,17 @@ onMounted(() => { ...@@ -61,18 +86,17 @@ onMounted(() => {
:before-close="handleCancel" :before-close="handleCancel"
:title="isEdit === true ? '编辑字典' : '新增字典'" :title="isEdit === true ? '编辑字典' : '新增字典'"
> >
<el-form :model="form" ref="formRef" :rules="rules" label-width="120px"> <el-form :model="form" ref="ruleFormRef" :rules="rules" label-width="120px">
<el-form-item label="字典名称:" prop="name"> <el-form-item label="字典名称:" prop="name">
<el-input v-model="form.name"></el-input> <el-input v-model="form.name"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="字典类型:" prop="type"> <el-form-item label="字典类型:" prop="key">
<el-input v-model="form.type"></el-input> <el-input v-model="form.key"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="状态:" prop="status"> <el-form-item label="状态:" prop="status">
<el-radio-group v-model="form.status"> <el-radio-group v-model="form.status">
<el-radio label="0">正常</el-radio> <el-radio v-for="(item, index) in statusList" :key="index" :label="item.value">{{ item.label }}</el-radio>
<el-radio label="1">停用</el-radio>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
<el-form-item label="备注:" prop="remark"> <el-form-item label="备注:" prop="remark">
...@@ -81,7 +105,7 @@ onMounted(() => { ...@@ -81,7 +105,7 @@ onMounted(() => {
</el-form> </el-form>
<template #footer> <template #footer>
<span> <span>
<el-button type="primary" @click="handleConfirm">确定</el-button> <el-button type="primary" @click="handleConfirm(ruleFormRef)">确定</el-button>
<el-button @click="handleCancel">关闭</el-button> <el-button @click="handleCancel">关闭</el-button>
</span> </span>
</template> </template>
......
<script lang="ts" setup> <script lang="ts" setup>
import type { IMapList } from '../types'
import { useMapStore } from '@/stores/map'
import type { FormInstance, FormRules } from 'element-plus'
const ruleFormRef = ref<FormInstance>()
const store = useMapStore()
let statusList = $ref<IMapList[]>([])
const form = reactive({ const form = reactive({
tag: '', label: '',
value: '',
key: '', key: '',
type: '', type: '',
status: '0', status: '1',
remark: '' remark: '',
sort: ''
})
const rules = reactive<FormRules>({
label: [{ required: true, message: '请输入字典标签', trigger: 'blur' }],
value: [{ required: true, message: '请输入字典键值', trigger: 'blur' }],
sort: [{ required: true, message: '请输入字典排序', trigger: 'blur' }]
}) })
const rules = {
tag: [{ required: true, message: '请输入字典标签', trigger: 'blur' }],
key: [{ required: true, message: '请输入字典键值', trigger: 'blur' }],
sort: [{ required: true, message: '请输入字典键值', trigger: 'blur' }]
}
const props = defineProps({ const props = defineProps({
isListAddDialog: { isListAddDialog: {
type: Boolean, type: Boolean,
...@@ -27,7 +38,7 @@ const props = defineProps({ ...@@ -27,7 +38,7 @@ const props = defineProps({
}) })
interface Emits { interface Emits {
(e: 'update:isListAddDialog', isListAddDialog: boolean): void (e: 'update:isListAddDialog', isListAddDialog: boolean): void
(e: 'confirm'): void (e: 'confirm', form: object): void
} }
const emit = defineEmits<Emits>() const emit = defineEmits<Emits>()
...@@ -38,37 +49,55 @@ const handleCancel = () => { ...@@ -38,37 +49,55 @@ const handleCancel = () => {
emit('update:isListAddDialog', false) emit('update:isListAddDialog', false)
} }
// 确定 // 确定
const handleConfirm = () => { const handleConfirm = async (formEl: FormInstance | undefined) => {
emit('update:isListAddDialog', false) if (!formEl) return
emit('confirm') await formEl.validate(valid => {
if (valid) {
if (props.isEdit === true) {
emit('update:isListAddDialog', false)
emit('confirm', { form, isUpdate: 1, id: props.editData.id })
} else {
emit('update:isListAddDialog', false)
emit('confirm', { form, isUpdate: 0 })
}
}
})
}
const getMapList = async () => {
await store.getMapList()
statusList = store.mapList.filter((item: any) => item.key === 'system_status')[0].values
console.log(statusList, 'statusList')
} }
onMounted(() => { onMounted(() => {
console.log('props.editData.status', props.editData.status) getMapList()
if (props.isEdit) { if (props.isEdit) {
form.tag = props.editData.tag form.label = props.editData.label
form.key = props.editData.key form.value = props.editData.value
form.type = props.editData.type form.type = props.editData.type
form.remark = props.editData.remark form.remark = props.editData.remark
form.status = props.editData.status form.status = props.editData.status
form.sort = props.editData.sort
} }
}) })
</script> </script>
<template> <template>
<el-dialog :model-value="isListAddDialog" draggable :before-close="handleCancel"> <el-dialog :model-value="isListAddDialog" draggable :before-close="handleCancel">
<el-form :model="form" :rules="rules" label-width="120px"> <el-form :model="form" ref="ruleFormRef" :rules="rules" label-width="120px">
<el-form-item label="字典标签:" prop="tag"> <el-form-item label="字典标签:" prop="label">
<el-input v-model="form.tag"></el-input> <el-input v-model="form.label"></el-input>
</el-form-item>
<el-form-item label="字典键值:" prop="value">
<el-input v-model="form.value"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="字典键值:" prop="key"> <el-form-item label="字典排序:" prop="sort">
<el-input v-model="form.key"></el-input> <el-input v-model="form.sort"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="字典类型:" prop="type"> <el-form-item label="字典类型:" prop="type">
<el-input v-model="form.type"></el-input> <el-input v-model="form.type"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="状态:" prop="status"> <el-form-item label="状态:" prop="status">
<el-radio-group v-model="form.status"> <el-radio-group v-model="form.status">
<el-radio label="0">正常</el-radio> <el-radio v-for="(item, index) in statusList" :key="index" :label="item.value">{{ item.label }}</el-radio>
<el-radio label="1">停用</el-radio>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
<el-form-item label="备注:" prop="remark"> <el-form-item label="备注:" prop="remark">
...@@ -77,7 +106,7 @@ onMounted(() => { ...@@ -77,7 +106,7 @@ onMounted(() => {
</el-form> </el-form>
<template #footer> <template #footer>
<span> <span>
<el-button type="primary" @click="handleConfirm">确定</el-button> <el-button type="primary" @click="handleConfirm(ruleFormRef)">确定</el-button>
<el-button @click="handleCancel">关闭</el-button> <el-button @click="handleCancel">关闭</el-button>
</span> </span>
</template> </template>
......
export interface IMapList {
label: string
value: string
data_dictionary_id: string
sort: string
remark: string
id: string
}
<script setup lang="ts"> <script setup lang="ts">
import type { IMapList } from '../types'
import { ElMessage, ElMessageBox } from 'element-plus'
import { useMapStore } from '@/stores/map'
import { getDictionaryList, createDictionary, updateDictionary, delDictionary } from '../api'
import AddDialog from '../component/AddDialog.vue' import AddDialog from '../component/AddDialog.vue'
const store = useMapStore()
const router = useRouter() const router = useRouter()
const appList = ref() const appList = ref()
const isShowDialog = ref(false) // 新增字典弹框状态 const isShowDialog = ref(false) // 新增字典弹框状态
const isEdit = ref(false) //是否可编辑 const isEdit = ref(false) //是否可编辑
const rowInfo = ref({}) const rowInfo = ref({})
// 状态
let statusList = $ref<IMapList[]>([])
//表单每行数据 //表单每行数据
const listOptions = { const listOptions = {
remote: { remote: {
// httpRequest: getVideoList, httpRequest: getDictionaryList,
params: { type: '', created_time: '' } params: {
type: '',
created_time_start: '',
created_time_end: ''
}
}, },
filters: [ filters: [
{ type: 'input', prop: 'name', label: '字典名称:' }, { type: 'input', prop: 'name', label: '字典名称:' },
{ type: 'input', prop: 'type', label: '字典类型:' }, { type: 'input', prop: 'key', label: '字典类型:' },
{ {
type: 'select', type: 'select',
prop: 'status', prop: 'status',
label: '字典状态:', label: '字典状态:',
options: [ options: [
{ label: '正常', value: '0' }, { label: '有效', value: '1' },
{ label: '停用', value: '1' } { label: '失效', value: '0' }
] ]
}, },
{ type: 'input', prop: 'created_time', slots: 'created_time', label: '创建时间:' } {
type: 'input',
label: '创建时间:',
slots: 'created_time_start',
prop: 'created_time_start'
},
{ slots: 'created_time_end', prop: 'created_time_end' }
], ],
columns: [ columns: [
{ label: '字典主键', slots: 'key', width: 224, align: 'center' }, { label: '字典主键', prop: 'id', width: 224, align: 'center' },
{ label: '字典名称', prop: 'name', align: 'center' }, { label: '字典名称', prop: 'name', align: 'center' },
{ label: '字典类型', prop: 'type', align: 'center' }, { label: '字典类型', prop: 'key', align: 'center' },
{ {
label: '状态', label: '状态',
prop: 'status', prop: 'status_name',
align: 'center', align: 'center'
computed(row: any) {
if (row.status === '0') {
return '正常'
} else {
return '停用'
}
}
}, },
{ label: '备注 ', prop: 'remark', align: 'center' }, { label: '备注 ', prop: 'remark', align: 'center' },
{ label: '创建时间', prop: 'created_time', align: 'center' }, { label: '创建时间', prop: 'created_time', align: 'center' },
...@@ -61,31 +71,63 @@ const listOptions = { ...@@ -61,31 +71,63 @@ const listOptions = {
} }
] ]
} }
// 新增弹窗
const handleAdd = () => { const handleAdd = () => {
console.log('新增字典')
isShowDialog.value = true isShowDialog.value = true
isEdit.value = false isEdit.value = false
} }
// 编辑弹窗
const handleEdit = (row: any) => { const handleEdit = (row: any) => {
console.log('编辑字典', row)
rowInfo.value = row rowInfo.value = row
isShowDialog.value = true isShowDialog.value = true
isEdit.value = true isEdit.value = true
console.log(rowInfo)
} }
//删除
const handleDelete = (row: any) => { const handleDelete = (row: any) => {
console.log('删除字典', row) ElMessageBox.confirm('确定要删除吗?', '提示').then(() => {
const params = { id: row.id }
delDictionary(params).then(() => {
ElMessage.success('删除成功')
appList.value.refetch()
})
})
} }
// 跳转列表
const handleList = (row: any) => { const handleList = (row: any) => {
console.log('列表', row.rowList) console.log('列表', row.rowList)
router.push({ router.push({
path: '/system/dictionary/rowList', path: '/system/dictionary/rowList',
query: { query: {
rowList: JSON.stringify(row.rowList) id: row.id
} }
}) })
// listShowDialog.value = true
} }
const getMapList = async () => {
await store.getMapList()
statusList = store.mapList.filter((item: any) => item.key === 'system_status')[0].values
console.log(statusList, 'statusList')
}
// 确定
const handleConfirm = (val: any) => {
if (val.isUpdate === 1) {
// 更新字典
const params = Object.assign({ id: val.id }, val.form)
updateDictionary(params).then(() => {
ElMessage.success('更新成功')
appList.value.refetch()
})
} else {
// 新增字典
const params = Object.assign({}, val.form)
createDictionary(params).then(() => {
ElMessage.success('新增成功')
appList.value.refetch()
})
}
}
onMounted(() => {
getMapList()
})
</script> </script>
<template> <template>
...@@ -94,17 +136,12 @@ const handleList = (row: any) => { ...@@ -94,17 +136,12 @@ const handleList = (row: any) => {
<el-row> <el-row>
<el-button type="primary" @click="handleAdd">新增字典</el-button> <el-button type="primary" @click="handleAdd">新增字典</el-button>
</el-row> </el-row>
<template v-slot:created_time="{ params }"> <template v-slot:created_time_start="{ params }">
<el-date-picker <el-date-picker v-model="params.created_time_start" type="date" placeholder="开始时间"> </el-date-picker>
v-model="params.created_time" <p class="separator">&nbsp;&nbsp;&nbsp;&nbsp;-</p>
type="daterange" </template>
range-separator="至" <template v-slot:created_time_end="{ params }">
start-placeholder="开始日期" <el-date-picker v-model="params.created_time_end" type="date" placeholder="结束时间"> </el-date-picker>
end-placeholder="结束日期"
value-format="yyyy-MM-dd"
size="small"
>
</el-date-picker>
</template> </template>
<template #table-operate="{ row }"> <template #table-operate="{ row }">
<el-space> <el-space>
...@@ -114,8 +151,15 @@ const handleList = (row: any) => { ...@@ -114,8 +151,15 @@ const handleList = (row: any) => {
</el-space> </el-space>
</template> </template>
<template v-if="isShowDialog === true"> <template v-if="isShowDialog === true">
<AddDialog v-model:isShowDialog="isShowDialog" :isEdit="isEdit" :rowInfo="rowInfo" /> <AddDialog
v-model:isShowDialog="isShowDialog"
:isEdit="isEdit"
:rowInfo="rowInfo"
:statusList="statusList"
@confirm="handleConfirm"
/>
</template> </template>
</AppList> </AppList>
</AppCard> </AppCard>
</template> </template>
<style lang="scss" scoped></style>
<script setup lang="ts"> <script setup lang="ts">
import { getDictionaryItemList, createDictionaryItem, updateDictionaryItem, delDictionaryItem } from '../api'
import { ElMessage, ElMessageBox } from 'element-plus'
import ListAddDialog from '../component/ListAddDialog.vue' import ListAddDialog from '../component/ListAddDialog.vue'
const route = useRoute() const route = useRoute()
const appList = ref() const appList = ref()
...@@ -7,38 +10,27 @@ const isEdit = ref(false) ...@@ -7,38 +10,27 @@ const isEdit = ref(false)
const isListAddDialog = ref(false) const isListAddDialog = ref(false)
const listOptions = { const listOptions = {
remote: { remote: {
// httpRequest: getVideoList, httpRequest: getDictionaryItemList,
params: { type: '' } params: { data_dictionary_id: route.query.id }
}, },
columns: [ columns: [
{ label: '字典编码', prop: 'code', align: 'center' }, { label: '字典编码', prop: 'data_dictionary_id', align: 'center' },
{ label: '字典标签', prop: 'tag', align: 'center' }, { label: '字典标签', prop: 'label', align: 'center' },
{ label: '字典键值', prop: 'key', align: 'center' }, { label: '字典键值', prop: 'value', align: 'center' },
{ {
label: '状态', label: '状态',
prop: 'status', prop: 'status_name',
align: 'center', align: 'center'
computed(row: any) {
console.log(row.row)
if (row.row.status === '0') {
return '正常'
} else if (row.row.status === '1') {
return '停用'
} else {
return '-'
}
}
}, },
{ label: '备注 ', prop: 'remark', align: 'center' }, { label: '备注 ', prop: 'remark', align: 'center' },
{ label: '创建时间', prop: 'created_time', align: 'center' }, { label: '创建时间', prop: 'created_time', align: 'center' },
{ label: '操作', slots: 'table-operate', align: 'center', minWidth: 180 } { label: '操作', slots: 'table-operate', align: 'center', minWidth: 180 }
], ]
data: JSON.parse(route.query.rowList + '')
} }
const handleAdd = () => { const handleAdd = () => {
isListAddDialog.value = true isListAddDialog.value = true
isEdit.value = true isEdit.value = false
editData.value = {} editData.value = {}
console.log('新增字典') console.log('新增字典')
} }
...@@ -49,10 +41,32 @@ const handleEdit = (row: any) => { ...@@ -49,10 +41,32 @@ const handleEdit = (row: any) => {
console.log('编辑字典', row) console.log('编辑字典', row)
} }
const handleDelete = (row: any) => { const handleDelete = (row: any) => {
console.log('删除字典', row) ElMessageBox.confirm('确定要删除吗?', '提示').then(() => {
const params = { id: row.id }
delDictionaryItem(params).then(() => {
ElMessage.success('删除成功')
appList.value.refetch()
})
})
} }
const confirm = () => { // 确定
console.log('0001111') const handleConfirm = (val: any) => {
console.log(val.id, '9999')
if (val.isUpdate === 1) {
// 更新字典的值
const params = Object.assign({ id: val.id, data_dictionary_id: route.query.id }, val.form)
updateDictionaryItem(params).then(() => {
ElMessage.success('更新成功')
appList.value.refetch()
})
} else {
// 新增字典的值
const params = Object.assign({ data_dictionary_id: route.query.id }, val.form)
createDictionaryItem(params).then(() => {
ElMessage.success('新增成功')
appList.value.refetch()
})
}
} }
</script> </script>
...@@ -71,6 +85,11 @@ const confirm = () => { ...@@ -71,6 +85,11 @@ const confirm = () => {
</AppList> </AppList>
</AppCard> </AppCard>
<template v-if="isListAddDialog === true"> <template v-if="isListAddDialog === true">
<ListAddDialog v-model:isListAddDialog="isListAddDialog" @confirm="confirm" :editData="editData" :isEdit="isEdit" /> <ListAddDialog
v-model:isListAddDialog="isListAddDialog"
@confirm="handleConfirm"
:editData="editData"
:isEdit="isEdit"
/>
</template> </template>
</template> </template>
import { defineStore } from 'pinia'
import { getMapList } from '@/api/base'
interface IMapState {
id: string
key: string
name: string
remark: string
values: IValuesList[]
}
interface IValuesList {
data_dictionary_id: string
id: string
label: string
remark: string
sort: string
value: string
}
export const useMapStore = defineStore({
id: 'map',
state: () => {
return {
mapList: [] as IMapState | any
}
},
getters: {},
actions: {
async getMapList() {
const res = await getMapList()
this.mapList = res.data
}
}
})
...@@ -29,6 +29,7 @@ export const useUserStore = defineStore({ ...@@ -29,6 +29,7 @@ export const useUserStore = defineStore({
async getUser() { async getUser() {
const res = await getUser() const res = await getUser()
this.user = res.data this.user = res.data
console.log(res.data, 'res.data')
}, },
async logout() { async logout() {
await logout() await logout()
......
...@@ -26,6 +26,12 @@ export default defineConfig(({ mode }) => ({ ...@@ -26,6 +26,12 @@ export default defineConfig(({ mode }) => ({
cert: fs.readFileSync(path.join(__dirname, './https/dev.ezijing.com.pem')) cert: fs.readFileSync(path.join(__dirname, './https/dev.ezijing.com.pem'))
}, },
proxy: { proxy: {
'/api/resource': {
// target: 'http://localhost-activity-frontend.ezijing.com',
target: 'http://localhost-resource-backend.ezijing.com',
changeOrigin: true,
rewrite: path => path.replace(/^\/api\/resource/, '')
},
'/api': 'https://learn-api.ezijing.com' '/api': 'https://learn-api.ezijing.com'
} }
}, },
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论