| <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: '', |