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