<link rel="icon" type="image/svg+xml" href="/logo_1.jpg" /> | <link rel="icon" type="image/svg+xml" href="/logo_1.jpg" /> | ||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||||
<title>菊城人才市场后台管理</title> | <title>菊城人才市场后台管理</title> | ||||
<script type="module" crossorigin src="/assets/index-AHTnyh3r.js"></script> | |||||
<link rel="stylesheet" crossorigin href="/assets/index-7KXeZgtg.css"> | |||||
<script type="module" crossorigin src="/assets/index-zplygJt9.js"></script> | |||||
<link rel="stylesheet" crossorigin href="/assets/index-EE_SYqet.css"> | |||||
</head> | </head> | ||||
<body> | <body> | ||||
<div id="app"></div> | <div id="app"></div> |
:expanded-row-keys="state.expandRowKeys" | :expanded-row-keys="state.expandRowKeys" | ||||
:rowClassName="(record, index) => (index % 2 === 1 ? 'table-striped' : null)" :loading="loading" | :rowClassName="(record, index) => (index % 2 === 1 ? 'table-striped' : null)" :loading="loading" | ||||
:scroll="{ y: 600 }"> | :scroll="{ y: 600 }"> | ||||
<template #stick_top="{ record }"> | |||||
<slot name="stick_top" :record='record'></slot> | |||||
</template> | |||||
<template #hot="{ record }"> | |||||
<slot name="hot" :record='record'></slot> | |||||
</template> | |||||
<template #photo_image="{ record }"> | <template #photo_image="{ record }"> | ||||
<slot name="photo_image" :record='record'></slot> | <slot name="photo_image" :record='record'></slot> | ||||
</template> | </template> |
<template> | |||||
<div style="display: flex;"> | |||||
<a-upload-dragger v-model:file-list="fileList" class="avatar-uploader" :show-upload-list="false" | |||||
:before-upload="beforeUpload" :data="uploadData" :customRequest="uploadCustom" @drop="handleDrop"> | |||||
<p class="ant-upload-drag-icon"> | |||||
<inbox-outlined></inbox-outlined> | |||||
</p> | |||||
<p class="ant-upload-text">拖拽文件上传</p> | |||||
</a-upload-dragger> | |||||
</div> | |||||
</template> | |||||
<script setup lang="ts"> | |||||
import { ref, onMounted, computed, defineProps, watch, defineEmits } from 'vue'; | |||||
import axios from 'axios'; | |||||
import { UploadOutlined, InboxOutlined } from '@ant-design/icons-vue'; | |||||
import { useCommon } from '@/hooks/useCommon'; | |||||
let { message, imageprefix } = useCommon(); | |||||
const props = defineProps({ | |||||
upload_txt: String, | |||||
doc_type: { | |||||
type: Number, | |||||
default: 1 | |||||
} | |||||
}); | |||||
const emit = defineEmits(); | |||||
const headers = ref<Object>({ | |||||
Authorization: sessionStorage.getItem('token'), | |||||
'X-Requested-With': null | |||||
}) | |||||
const uploadData = ref<Object>({ | |||||
doc: '' | |||||
}) | |||||
const docType = ref<Number>(props.doc_type) | |||||
let fileList = ref<Object[]>([]) | |||||
watch(() => [props.doc_type], (newVal, oldVal) => { | |||||
docType.value = newVal[0]; | |||||
}, { | |||||
immediate: true | |||||
}) | |||||
const handleDrop = (e) => { | |||||
} | |||||
const beforeUpload = (file) => { | |||||
uploadData.value.doc = file | |||||
} | |||||
const uploadCustom = (e) => { | |||||
let formdata = new FormData() | |||||
formdata.append('doc', e.file) | |||||
axios({ | |||||
url: 'https://rcsc-test.jcjob.cn/api/common/doc/upload?doctype=' + docType.value, | |||||
method: 'post', | |||||
data: formdata, | |||||
headers: headers.value | |||||
}).then((res) => { | |||||
console.log(res.data.data.filename) | |||||
message.success(`上传文件成功`); | |||||
emit('uploadSuccess', res.data.data.filename) | |||||
}).catch(err => { | |||||
message.danger('上传失败,请联系管理员'); | |||||
}) | |||||
} | |||||
</script> | |||||
<style scoped lang="less"> | |||||
.avatar-uploader { | |||||
width: 300px; | |||||
} | |||||
.avatar-uploader i { | |||||
font-size: 32px; | |||||
color: #999; | |||||
} | |||||
.avatar-uploader .ant-upload-text { | |||||
margin-top: 8px; | |||||
color: #666; | |||||
padding: 20px; | |||||
} | |||||
.avatar-uploader .ant-upload-list-item { | |||||
width: 128px; | |||||
height: 128px; | |||||
margin-right: 8px; | |||||
} | |||||
</style> |
</template> | </template> | ||||
</template> | </template> | ||||
<template v-if="imagesList.length < imagesLength || imagesList.length == 1"> | <template v-if="imagesList.length < imagesLength || imagesList.length == 1"> | ||||
<a-upload a-upload v-model:file-list="fileList" list-type="picture-card" class="avatar-uploader" | |||||
<a-upload v-model:file-list="fileList" list-type="picture-card" class="avatar-uploader" | |||||
:show-upload-list="false" :before-upload="beforeUpload" :data="uploadData" | :show-upload-list="false" :before-upload="beforeUpload" :data="uploadData" | ||||
:customRequest="uploadCustom"> | :customRequest="uploadCustom"> | ||||
<plus-outlined /> | <plus-outlined /> | ||||
uid: '-1', // 文件唯一标识,建议设置为负数,防止和内部产生的 id 冲突 | uid: '-1', // 文件唯一标识,建议设置为负数,防止和内部产生的 id 冲突 | ||||
name: e.file.name, // 文件名 | name: e.file.name, // 文件名 | ||||
status: 'done', // 状态有:uploading done error removed | status: 'done', // 状态有:uploading done error removed | ||||
url: "https://rcsc-test.jcjob.cn/img" + res.data.data.filename | |||||
url: imageprefix + res.data.data.filename | |||||
}] | }] | ||||
} else { | } else { | ||||
if (imagesList.value.length < imagesLength.value) { | if (imagesList.value.length < imagesLength.value) { | ||||
uid: '-' + (imagesList.value.length + 1), // 文件唯一标识,建议设置为负数,防止和内部产生的 id 冲突 | uid: '-' + (imagesList.value.length + 1), // 文件唯一标识,建议设置为负数,防止和内部产生的 id 冲突 | ||||
name: e.file.name, // 文件名 | name: e.file.name, // 文件名 | ||||
status: 'done', // 状态有:uploading done error removed | status: 'done', // 状态有:uploading done error removed | ||||
url: "https://rcsc-test.jcjob.cn/img" + res.data.data.filename | |||||
url: imageprefix + res.data.data.filename | |||||
}) | }) | ||||
} else { | } else { | ||||
message.danger('最多上传5张'); | message.danger('最多上传5张'); | ||||
console.log(res.data.data.filename) | console.log(res.data.data.filename) | ||||
message.success(`${props.upload_txt}成功`); | message.success(`${props.upload_txt}成功`); | ||||
emit('uploadSuccess', res.data.data.filename) | emit('uploadSuccess', res.data.data.filename) | ||||
}).catch(err => { | |||||
message.danger('上传失败,请联系管理员'); | |||||
}) | }) | ||||
} | } | ||||
import ACSelect from '@/components/cSelect/select.vue'; | import ACSelect from '@/components/cSelect/select.vue'; | ||||
import ACSelectCommon from '@/components/cSelect/common.vue'; | import ACSelectCommon from '@/components/cSelect/common.vue'; | ||||
import UploadOne from '@/components/upload/one.vue'; | import UploadOne from '@/components/upload/one.vue'; | ||||
import UploadFile from '@/components/upload/file.vue'; | |||||
import { Model } from 'node_modules/echarts/index'; | import { Model } from 'node_modules/echarts/index'; | ||||
// router.beforeEach(async (to, from, next) => { | // router.beforeEach(async (to, from, next) => { | ||||
app.component('a-c-select-common', ACSelectCommon); | app.component('a-c-select-common', ACSelectCommon); | ||||
app.component('QuillEditor', QuillEditor) | app.component('QuillEditor', QuillEditor) | ||||
app.component('upload-one', UploadOne) | app.component('upload-one', UploadOne) | ||||
app.component('upload-file', UploadFile) | |||||
app.use(router); | app.use(router); | ||||
app.use(store); | app.use(store); | ||||
app.use(Antd); | app.use(Antd); |
</a-form-item> | </a-form-item> | ||||
</a-col> | </a-col> | ||||
<a-col span="24"> | <a-col span="24"> | ||||
<a-form-item required label="封面图" name="name"> | |||||
<a-form-item required label="封面图"> | |||||
<upload-one upload_txt="上传封面图" @uploadSuccess="uploadSuccess" :success_image="success_img" | <upload-one upload_txt="上传封面图" @uploadSuccess="uploadSuccess" :success_image="success_img" | ||||
images_length="1"></upload-one> | images_length="1"></upload-one> | ||||
</a-form-item> | </a-form-item> | ||||
</a-col> | </a-col> | ||||
<a-col span="24"> | |||||
<a-form-item label="上传文件,可将链接放入文章内容"> | |||||
<upload-file @uploadSuccess="uploadDocSuccess"></upload-file> | |||||
<a-typography-paragraph v-if="createForm.doc" :copyable="{ text: imageprefix+createForm.doc}"> | |||||
{{imageprefix+createForm.doc}} | |||||
</a-typography-paragraph> | |||||
</a-form-item> | |||||
</a-col> | |||||
<a-col span="24"> | <a-col span="24"> | ||||
<a-form-item required label="上级栏目" name="parent_id"> | <a-form-item required label="上级栏目" name="parent_id"> | ||||
<search-select placeholder="请选择上级栏目" :list="section_list" :select_value="addOtherForm.name" | <search-select placeholder="请选择上级栏目" :list="section_list" :select_value="addOtherForm.name" | ||||
<script setup lang="ts"> | <script setup lang="ts"> | ||||
import { ref, onMounted, computed, defineProps, watch, defineEmits } from 'vue'; | import { ref, onMounted, computed, defineProps, watch, defineEmits } from 'vue'; | ||||
import { addArticle, updateArticle, listSection } from '@/apis/models'; | import { addArticle, updateArticle, listSection } from '@/apis/models'; | ||||
import he from 'he'; | |||||
import { dataForm, otherDataForm, reset } from '@/views/information/section/add/data.ts'; | import { dataForm, otherDataForm, reset } from '@/views/information/section/add/data.ts'; | ||||
import { useCommon } from '@/hooks/useCommon'; | import { useCommon } from '@/hooks/useCommon'; | ||||
let { store, openAddModel, hideModal, message, richOption } = useCommon(); | |||||
let { store, openAddModel, hideModal, message, richOption, imageprefix } = useCommon(); | |||||
const emit = defineEmits(); | const emit = defineEmits(); | ||||
let props = defineProps(['edit_record']); | let props = defineProps(['edit_record']); | ||||
let title = ref<String>('新增文章'); | let title = ref<String>('新增文章'); | ||||
// 上传图片 | // 上传图片 | ||||
const uploadSuccess = (data : Object) => { | const uploadSuccess = (data : Object) => { | ||||
success_img.value = "http://114.132.85.7:8894" + data | |||||
success_img.value = imageprefix + data | |||||
createForm.value.cover_img = data | createForm.value.cover_img = data | ||||
} | |||||
// 上传文件 | |||||
const uploadDocSuccess = (data : Object) => { | |||||
createForm.value.doc = data | |||||
} | } | ||||
// 选择栏目/频道 | // 选择栏目/频道 | ||||
if (newVal) { | if (newVal) { | ||||
title.value = '编辑文章'; | title.value = '编辑文章'; | ||||
addOtherForm.value = { | addOtherForm.value = { | ||||
name: '', | |||||
content:newVal.content | |||||
name: newVal.section_id, | |||||
content: he.decode(newVal.content) | |||||
} | } | ||||
success_img.value = "https://rcsc-test.jcjob.cn/img" + newVal.cover_img; | |||||
success_img.value = imageprefix + newVal.cover_img; | |||||
createForm.value = { | createForm.value = { | ||||
id: newVal.id, | id: newVal.id, |
export let dataForm = { | export let dataForm = { | ||||
title: '', | title: '', | ||||
cover_img: '', | cover_img: '', | ||||
doc: '', | |||||
section_id: 0, | section_id: 0, | ||||
content: '', | content: '', | ||||
stick_top: 0, | stick_top: 0, | ||||
dataForm = { | dataForm = { | ||||
title: '', | title: '', | ||||
cover_img: '', | cover_img: '', | ||||
doc: '', | |||||
section_id: 0, | section_id: 0, | ||||
content: '', | content: '', | ||||
stick_top: 0, | stick_top: 0, |
}, | }, | ||||
{ | { | ||||
title: '置顶', | title: '置顶', | ||||
dataIndex: 'stick_top' | |||||
dataIndex: 'stick_top', | |||||
slots: { customRender: 'stick_top' }, | |||||
}, | }, | ||||
{ | |||||
{ | |||||
title: '热门', | title: '热门', | ||||
dataIndex: 'hot' | |||||
dataIndex: 'hot', | |||||
slots: { customRender: 'hot' }, | |||||
}, | }, | ||||
{ | { | ||||
title: '作者', | title: '作者', |
<a-c-operation @refresh="clearData"></a-c-operation> | <a-c-operation @refresh="clearData"></a-c-operation> | ||||
<a-c-table :data="commomParams.table.data" :columns="commomParams.table.columns" :pagination="commomParams.page" | <a-c-table :data="commomParams.table.data" :columns="commomParams.table.columns" :pagination="commomParams.page" | ||||
@page="getPage" :loading="loading"> | @page="getPage" :loading="loading"> | ||||
<template #stick_top="{ record }"> | |||||
<a-tag color="success" v-if="record.stick_top == 1">置顶</a-tag> | |||||
</template> | |||||
<template #hot="{ record }"> | |||||
<a-tag color="red" v-if="record.hot == 2">热门</a-tag> | |||||
<a-tag v-else>普通</a-tag> | |||||
</template> | |||||
<template #default="{ record }"> | <template #default="{ record }"> | ||||
<a-row :gutter="10"> | <a-row :gutter="10"> | ||||
<a-col><a-button type="primary" size="small" primary @click="edit(record)">编辑</a-button></a-col> | <a-col><a-button type="primary" size="small" primary @click="edit(record)">编辑</a-button></a-col> |
watch(() => props.search_params, (newVal) => { | watch(() => props.search_params, (newVal) => { | ||||
emit('searchData', commomParams.value.search) | emit('searchData', commomParams.value.search) | ||||
}, { | |||||
immediate: true | |||||
}) | }) | ||||
const getData = () => { | const getData = () => { |
<template> | <template> | ||||
<a-typography-paragraph v-if="editMode == false">{{text}} | |||||
<HighlightOutlined @click="() => {editMode = true}" color="rgb(25, 190, 107" /> | |||||
</a-typography-paragraph> | |||||
<div v-else style="width: 100%;"> | |||||
<div style="width: 100%;"> | |||||
<a-space direction="vertical" style="width: 100%;"> | <a-space direction="vertical" style="width: 100%;"> | ||||
<a-textarea v-model:value="text" /> | <a-textarea v-model:value="text" /> | ||||
<a-flex justify="flex-end"> | <a-flex justify="flex-end"> | ||||
<a-space> | <a-space> | ||||
<a-button @click="() => {editMode = false}">取消</a-button> | |||||
<a-button type="primary" @click="saveTxt">保存</a-button> | <a-button type="primary" @click="saveTxt">保存</a-button> | ||||
</a-space> | </a-space> | ||||
</a-flex> | </a-flex> | ||||
</a-space> | </a-space> | ||||
</div> | </div> | ||||
</template> | </template> | ||||
<script lang="ts" setup> | <script lang="ts" setup> | ||||
import { ref, onMounted, watch, computed } from 'vue'; | import { ref, onMounted, watch, computed } from 'vue'; | ||||
import { GetTokenizerGet, PostTokenizerModify } from '@/apis/models'; | import { GetTokenizerGet, PostTokenizerModify } from '@/apis/models'; | ||||
import { useCommon } from '@/hooks/useCommon'; | import { useCommon } from '@/hooks/useCommon'; | ||||
import { | |||||
HighlightOutlined | |||||
} from '@ant-design/icons-vue'; | |||||
let { store, commomParams, showModal, showOtherModal1, message } = useCommon(); | let { store, commomParams, showModal, showOtherModal1, message } = useCommon(); | ||||
let text = ref<String>('') | let text = ref<String>('') | ||||
let editMode = ref<Boolean>(false) | |||||
onMounted(() => { | onMounted(() => { | ||||
getData(); | getData(); | ||||
const saveTxt = () => { | const saveTxt = () => { | ||||
PostTokenizerModify({ text: text.value }).then(res => { | PostTokenizerModify({ text: text.value }).then(res => { | ||||
message.success('分词器更新成功'); | message.success('分词器更新成功'); | ||||
editMode.value = false; | |||||
}) | }) | ||||
} | } | ||||
</script> | </script> |
name?: String, | name?: String, | ||||
value?: String, | value?: String, | ||||
remark?: String, | remark?: String, | ||||
txt_mode ?: Number | |||||
} | } | ||||
type addOtherFormType = { | type addOtherFormType = { |
</a-col> | </a-col> | ||||
<a-col span="24"> | <a-col span="24"> | ||||
<a-form-item required label="请选择文本格式"> | <a-form-item required label="请选择文本格式"> | ||||
<a-radio-group v-model:value="txt_mode" button-style="solid" @change="txtModeChange"> | |||||
<a-radio-group v-model:value="createForm.txt_mode" button-style="solid" @change="txtModeChange"> | |||||
<a-radio-button :value="1">普通文本</a-radio-button> | <a-radio-button :value="1">普通文本</a-radio-button> | ||||
<a-radio-button :value="2">带有格式的文本</a-radio-button> | <a-radio-button :value="2">带有格式的文本</a-radio-button> | ||||
</a-radio-group> | </a-radio-group> | ||||
</a-form-item> | </a-form-item> | ||||
</a-col> | </a-col> | ||||
<a-col span="24" v-if="txt_mode == 1"> | |||||
<a-col span="24" v-if="createForm.txt_mode == 1"> | |||||
<a-form-item required label="配置内容" name="value"> | <a-form-item required label="配置内容" name="value"> | ||||
<a-input v-model:value="createForm.value" placeholder="请输入配置内容" /> | |||||
<a-textarea v-model:value="createForm.value" placeholder="请输入配置内容" /> | |||||
</a-form-item> | </a-form-item> | ||||
</a-col> | </a-col> | ||||
<a-col span="24" v-if="txt_mode == 2"> | |||||
<a-col span="24" v-if="createForm.txt_mode == 2"> | |||||
<a-form-item required label="配置内容" name="value"> | <a-form-item required label="配置内容" name="value"> | ||||
<QuillEditor theme="snow" :options="options" toolbar="full" | <QuillEditor theme="snow" :options="options" toolbar="full" | ||||
v-model:content="addOtherForm.value" @update:content="onEditorUpdate($event)" | v-model:content="addOtherForm.value" @update:content="onEditorUpdate($event)" | ||||
let props = defineProps(['edit_record']); | let props = defineProps(['edit_record']); | ||||
let title = ref<String>('新增配置项'); | let title = ref<String>('新增配置项'); | ||||
let showMap = ref<Boolean>(false); | let showMap = ref<Boolean>(false); | ||||
let txt_mode = ref<Number>(1); | |||||
const options = ref(richOption) | const options = ref(richOption) | ||||
let createForm = ref<SettingListType.addFormType>(dataForm) | let createForm = ref<SettingListType.addFormType>(dataForm) | ||||
let addOtherForm = ref<SettingListType.addOtherFormType>(otherDataForm) | let addOtherForm = ref<SettingListType.addOtherFormType>(otherDataForm) | ||||
const txtModeChange = (data) => { | |||||
createForm.value.value = '' | |||||
addOtherForm.value.value = '' | |||||
} | |||||
// const txtModeChange = (data) => { | |||||
// createForm.value.value = '' | |||||
// addOtherForm.value.value = '' | |||||
// } | |||||
// 富文本 | // 富文本 | ||||
const onEditorUpdate = (data) => { | const onEditorUpdate = (data) => { | ||||
watch(() => props.edit_record, (newVal) => { | watch(() => props.edit_record, (newVal) => { | ||||
if (newVal) { | if (newVal) { | ||||
title.value = '编辑配置项'; | title.value = '编辑配置项'; | ||||
if(newVal.value.length > 100) { | |||||
txt_mode.value = 2 | |||||
if(newVal.txt_mode == 1) { | |||||
createForm.value.value = newVal.value | |||||
} else { | |||||
addOtherForm.value = { | addOtherForm.value = { | ||||
value: he.decode(newVal.value), | value: he.decode(newVal.value), | ||||
} | } | ||||
id: newVal.id, | id: newVal.id, | ||||
name: newVal.name, | name: newVal.name, | ||||
value: newVal.value, | value: newVal.value, | ||||
remark: newVal.remark | |||||
remark: newVal.remark, | |||||
txt_mode: newVal.txt_mode | |||||
} | } | ||||
} else { | } else { | ||||
title.value = '新增配置项'; | title.value = '新增配置项'; |
name: '', | name: '', | ||||
value: '', | value: '', | ||||
remark: '', | remark: '', | ||||
txt_mode: 1 | |||||
} | } | ||||
export let otherDataForm = { | export let otherDataForm = { | ||||
cate: '', | |||||
value: '', | |||||
} | } | ||||
export const reset = () => { | export const reset = () => { | ||||
name: '', | name: '', | ||||
value: '', | value: '', | ||||
remark: '', | remark: '', | ||||
txt_mode: 1 | |||||
}; | }; | ||||
otherDataForm = { | otherDataForm = { | ||||
value: '', | value: '', |