| @@ -5,8 +5,8 @@ | |||
| <link rel="icon" type="image/svg+xml" href="/logo_1.jpg" /> | |||
| <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | |||
| <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> | |||
| <body> | |||
| <div id="app"></div> | |||
| @@ -4,6 +4,12 @@ | |||
| :expanded-row-keys="state.expandRowKeys" | |||
| :rowClassName="(record, index) => (index % 2 === 1 ? 'table-striped' : null)" :loading="loading" | |||
| :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 }"> | |||
| <slot name="photo_image" :record='record'></slot> | |||
| </template> | |||
| @@ -0,0 +1,89 @@ | |||
| <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> | |||
| @@ -13,7 +13,7 @@ | |||
| </template> | |||
| </template> | |||
| <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" | |||
| :customRequest="uploadCustom"> | |||
| <plus-outlined /> | |||
| @@ -94,7 +94,7 @@ | |||
| uid: '-1', // 文件唯一标识,建议设置为负数,防止和内部产生的 id 冲突 | |||
| name: e.file.name, // 文件名 | |||
| status: 'done', // 状态有:uploading done error removed | |||
| url: "https://rcsc-test.jcjob.cn/img" + res.data.data.filename | |||
| url: imageprefix + res.data.data.filename | |||
| }] | |||
| } else { | |||
| if (imagesList.value.length < imagesLength.value) { | |||
| @@ -103,7 +103,7 @@ | |||
| uid: '-' + (imagesList.value.length + 1), // 文件唯一标识,建议设置为负数,防止和内部产生的 id 冲突 | |||
| name: e.file.name, // 文件名 | |||
| status: 'done', // 状态有:uploading done error removed | |||
| url: "https://rcsc-test.jcjob.cn/img" + res.data.data.filename | |||
| url: imageprefix + res.data.data.filename | |||
| }) | |||
| } else { | |||
| message.danger('最多上传5张'); | |||
| @@ -112,6 +112,8 @@ | |||
| console.log(res.data.data.filename) | |||
| message.success(`${props.upload_txt}成功`); | |||
| emit('uploadSuccess', res.data.data.filename) | |||
| }).catch(err => { | |||
| message.danger('上传失败,请联系管理员'); | |||
| }) | |||
| } | |||
| @@ -20,6 +20,7 @@ import AXuanze from '@/components/cSelect/xuanze.vue'; | |||
| import ACSelect from '@/components/cSelect/select.vue'; | |||
| import ACSelectCommon from '@/components/cSelect/common.vue'; | |||
| import UploadOne from '@/components/upload/one.vue'; | |||
| import UploadFile from '@/components/upload/file.vue'; | |||
| import { Model } from 'node_modules/echarts/index'; | |||
| // router.beforeEach(async (to, from, next) => { | |||
| @@ -79,6 +80,7 @@ app.component('search-select', SearchSelect); | |||
| app.component('a-c-select-common', ACSelectCommon); | |||
| app.component('QuillEditor', QuillEditor) | |||
| app.component('upload-one', UploadOne) | |||
| app.component('upload-file', UploadFile) | |||
| app.use(router); | |||
| app.use(store); | |||
| app.use(Antd); | |||
| @@ -9,11 +9,19 @@ | |||
| </a-form-item> | |||
| </a-col> | |||
| <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" | |||
| images_length="1"></upload-one> | |||
| </a-form-item> | |||
| </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-form-item required label="上级栏目" name="parent_id"> | |||
| <search-select placeholder="请选择上级栏目" :list="section_list" :select_value="addOtherForm.name" | |||
| @@ -57,9 +65,10 @@ | |||
| <script setup lang="ts"> | |||
| import { ref, onMounted, computed, defineProps, watch, defineEmits } from 'vue'; | |||
| import { addArticle, updateArticle, listSection } from '@/apis/models'; | |||
| import he from 'he'; | |||
| import { dataForm, otherDataForm, reset } from '@/views/information/section/add/data.ts'; | |||
| import { useCommon } from '@/hooks/useCommon'; | |||
| let { store, openAddModel, hideModal, message, richOption } = useCommon(); | |||
| let { store, openAddModel, hideModal, message, richOption, imageprefix } = useCommon(); | |||
| const emit = defineEmits(); | |||
| let props = defineProps(['edit_record']); | |||
| let title = ref<String>('新增文章'); | |||
| @@ -77,9 +86,13 @@ | |||
| // 上传图片 | |||
| const uploadSuccess = (data : Object) => { | |||
| success_img.value = "http://114.132.85.7:8894" + data | |||
| success_img.value = imageprefix + data | |||
| createForm.value.cover_img = data | |||
| } | |||
| // 上传文件 | |||
| const uploadDocSuccess = (data : Object) => { | |||
| createForm.value.doc = data | |||
| } | |||
| // 选择栏目/频道 | |||
| @@ -147,10 +160,10 @@ | |||
| if (newVal) { | |||
| title.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 = { | |||
| id: newVal.id, | |||
| @@ -1,6 +1,7 @@ | |||
| export let dataForm = { | |||
| title: '', | |||
| cover_img: '', | |||
| doc: '', | |||
| section_id: 0, | |||
| content: '', | |||
| stick_top: 0, | |||
| @@ -17,6 +18,7 @@ export const reset = () => { | |||
| dataForm = { | |||
| title: '', | |||
| cover_img: '', | |||
| doc: '', | |||
| section_id: 0, | |||
| content: '', | |||
| stick_top: 0, | |||
| @@ -5,11 +5,13 @@ export const cols = <ColType.type[]>[ | |||
| }, | |||
| { | |||
| title: '置顶', | |||
| dataIndex: 'stick_top' | |||
| dataIndex: 'stick_top', | |||
| slots: { customRender: 'stick_top' }, | |||
| }, | |||
| { | |||
| { | |||
| title: '热门', | |||
| dataIndex: 'hot' | |||
| dataIndex: 'hot', | |||
| slots: { customRender: 'hot' }, | |||
| }, | |||
| { | |||
| title: '作者', | |||
| @@ -4,6 +4,13 @@ | |||
| <a-c-operation @refresh="clearData"></a-c-operation> | |||
| <a-c-table :data="commomParams.table.data" :columns="commomParams.table.columns" :pagination="commomParams.page" | |||
| @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 }"> | |||
| <a-row :gutter="10"> | |||
| <a-col><a-button type="primary" size="small" primary @click="edit(record)">编辑</a-button></a-col> | |||
| @@ -30,8 +30,6 @@ | |||
| watch(() => props.search_params, (newVal) => { | |||
| emit('searchData', commomParams.value.search) | |||
| }, { | |||
| immediate: true | |||
| }) | |||
| const getData = () => { | |||
| @@ -1,31 +1,22 @@ | |||
| <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-textarea v-model:value="text" /> | |||
| <a-flex justify="flex-end"> | |||
| <a-space> | |||
| <a-button @click="() => {editMode = false}">取消</a-button> | |||
| <a-button type="primary" @click="saveTxt">保存</a-button> | |||
| </a-space> | |||
| </a-flex> | |||
| </a-space> | |||
| </div> | |||
| </template> | |||
| <script lang="ts" setup> | |||
| import { ref, onMounted, watch, computed } from 'vue'; | |||
| import { GetTokenizerGet, PostTokenizerModify } from '@/apis/models'; | |||
| import { useCommon } from '@/hooks/useCommon'; | |||
| import { | |||
| HighlightOutlined | |||
| } from '@ant-design/icons-vue'; | |||
| let { store, commomParams, showModal, showOtherModal1, message } = useCommon(); | |||
| let text = ref<String>('') | |||
| let editMode = ref<Boolean>(false) | |||
| onMounted(() => { | |||
| getData(); | |||
| @@ -42,7 +33,6 @@ | |||
| const saveTxt = () => { | |||
| PostTokenizerModify({ text: text.value }).then(res => { | |||
| message.success('分词器更新成功'); | |||
| editMode.value = false; | |||
| }) | |||
| } | |||
| </script> | |||
| @@ -3,6 +3,7 @@ declare namespace SettingListType { | |||
| name?: String, | |||
| value?: String, | |||
| remark?: String, | |||
| txt_mode ?: Number | |||
| } | |||
| type addOtherFormType = { | |||
| @@ -10,18 +10,18 @@ | |||
| </a-col> | |||
| <a-col span="24"> | |||
| <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="2">带有格式的文本</a-radio-button> | |||
| </a-radio-group> | |||
| </a-form-item> | |||
| </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-input v-model:value="createForm.value" placeholder="请输入配置内容" /> | |||
| <a-textarea v-model:value="createForm.value" placeholder="请输入配置内容" /> | |||
| </a-form-item> | |||
| </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"> | |||
| <QuillEditor theme="snow" :options="options" toolbar="full" | |||
| v-model:content="addOtherForm.value" @update:content="onEditorUpdate($event)" | |||
| @@ -49,16 +49,15 @@ | |||
| let props = defineProps(['edit_record']); | |||
| let title = ref<String>('新增配置项'); | |||
| let showMap = ref<Boolean>(false); | |||
| let txt_mode = ref<Number>(1); | |||
| const options = ref(richOption) | |||
| let createForm = ref<SettingListType.addFormType>(dataForm) | |||
| 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) => { | |||
| @@ -110,8 +109,9 @@ | |||
| watch(() => props.edit_record, (newVal) => { | |||
| if (newVal) { | |||
| title.value = '编辑配置项'; | |||
| if(newVal.value.length > 100) { | |||
| txt_mode.value = 2 | |||
| if(newVal.txt_mode == 1) { | |||
| createForm.value.value = newVal.value | |||
| } else { | |||
| addOtherForm.value = { | |||
| value: he.decode(newVal.value), | |||
| } | |||
| @@ -120,7 +120,8 @@ | |||
| id: newVal.id, | |||
| name: newVal.name, | |||
| value: newVal.value, | |||
| remark: newVal.remark | |||
| remark: newVal.remark, | |||
| txt_mode: newVal.txt_mode | |||
| } | |||
| } else { | |||
| title.value = '新增配置项'; | |||
| @@ -3,10 +3,11 @@ export let dataForm = { | |||
| name: '', | |||
| value: '', | |||
| remark: '', | |||
| txt_mode: 1 | |||
| } | |||
| export let otherDataForm = { | |||
| cate: '', | |||
| value: '', | |||
| } | |||
| export const reset = () => { | |||
| @@ -14,6 +15,7 @@ export const reset = () => { | |||
| name: '', | |||
| value: '', | |||
| remark: '', | |||
| txt_mode: 1 | |||
| }; | |||
| otherDataForm = { | |||
| value: '', | |||