| <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-AKeHTq0B.js"></script> | |||||
| <link rel="stylesheet" crossorigin href="/assets/index-EE_SYqet.css"> | |||||
| <script type="module" crossorigin src="/assets/index-AZrlCp8c.js"></script> | |||||
| <link rel="stylesheet" crossorigin href="/assets/index-CfxQrvHe.css"> | |||||
| </head> | </head> | ||||
| <body> | <body> | ||||
| <div id="app"></div> | <div id="app"></div> |
| }).then((res:object) => { | }).then((res:object) => { | ||||
| listOptions.value = res.data.dicts | listOptions.value = res.data.dicts | ||||
| }) | }) | ||||
| selectValue.value = newVal[1] == 0 ? props.placeholder : newVal[1]; | |||||
| selectValue.value = newVal[1] ? newVal[1] : null; | |||||
| }, { immediate: true }) | }, { immediate: true }) | ||||
| onMounted(() => { | onMounted(() => { |
| <template> | |||||
| <a-select v-model:value="selectValue" @change="handleChange" :placeholder="placeholder" label-in-value size="large"> | |||||
| <a-select-option v-for="item in listOptions" :key="item.id" :value="item.id" :label="item.name">{{item.name}}</a-select-option> | |||||
| </a-select> | |||||
| </template> | |||||
| <script lang="ts" setup> | |||||
| import { ref, onMounted, defineProps, watch, defineEmits } from 'vue'; | |||||
| import { GetDictTree } from '@/apis/models'; | |||||
| const props = defineProps(['dict', 'placeholder', 'select_content']); | |||||
| let listOptions = ref([]); | |||||
| let selectValue = ref<String>(null); | |||||
| let placeholder = ref<String>(props.placeholder); | |||||
| watch(() => [props.dict, props.select_content], | |||||
| (newVal:string, oldVal:string) => { | |||||
| GetDictTree({ | |||||
| code: newVal[0] | |||||
| }).then((res:object) => { | |||||
| listOptions.value = res.data.dicts | |||||
| }) | |||||
| selectValue.value = newVal[1] ? newVal[1] : null; | |||||
| }, { immediate: true }) | |||||
| onMounted(() => { | |||||
| GetDictTree({ | |||||
| code: props.dict | |||||
| }).then((res:object) => { | |||||
| listOptions.value = res.data.dicts | |||||
| }) | |||||
| }) | |||||
| const emit = defineEmits(); | |||||
| const handleChange = (val) => { | |||||
| emit('saveSelect', { val: val }); | |||||
| } | |||||
| </script> | |||||
| <style> | |||||
| </style> |
| <p class="ant-upload-drag-icon"> | <p class="ant-upload-drag-icon"> | ||||
| <inbox-outlined></inbox-outlined> | <inbox-outlined></inbox-outlined> | ||||
| </p> | </p> | ||||
| <p class="ant-upload-text">拖拽文件上传</p> | |||||
| <p class="ant-upload-text">拖拽或点击文件上传</p> | |||||
| </a-upload-dragger> | </a-upload-dragger> | ||||
| </div> | </div> | ||||
| </template> | </template> |
| import UploadFile from '@/components/upload/file.vue'; | import UploadFile from '@/components/upload/file.vue'; | ||||
| import ImageContainer from '@/components/form/image-container.vue'; | import ImageContainer from '@/components/form/image-container.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) => { | ||||
| // document.title = `${to.meta.title} - 菊城人才市场后台管理`; | // document.title = `${to.meta.title} - 菊城人才市场后台管理`; | ||||
| // // 动态路由可能还没加载完成,先检查是否已加载 | // // 动态路由可能还没加载完成,先检查是否已加载 |
| ], | ], | ||||
| }; | }; | ||||
| // 求职企业账号管理 | |||||
| // const CustomerRoute : AppRouteRecordRaw = { | |||||
| // path: '/customer', | |||||
| // name: 'customer', | |||||
| // component: routerList.Customer, | |||||
| // meta: { | |||||
| // title: '求职企业账号管理', | |||||
| // icon: HomeOutlined | |||||
| // }, | |||||
| // children: [ | |||||
| // // { | |||||
| // // path: '/activity/list', | |||||
| // // name: 'activityList', | |||||
| // // component: routerList.ActivityList, | |||||
| // // meta: { | |||||
| // // title: '活动列表', | |||||
| // // icon: HomeOutlined | |||||
| // // }, | |||||
| // // }, | |||||
| // { | |||||
| // path: '/customer/list', | |||||
| // name: 'customerList', | |||||
| // component: routerList.CustomerList, | |||||
| // meta: { | |||||
| // title: '账号列表', | |||||
| // icon: HomeOutlined | |||||
| // }, | |||||
| // } | |||||
| // ], | |||||
| // }; | |||||
| export const routesModuleList : AppRouteModule[] = [CompanyRoute,HomemakeRoute, JokSeekerRoute, JokFairRoute, InformationRoute, AdvertisementRoute, ActivityRoute, StatisticsRoute,PermissionRoute, SettingRoute, OtherRoute, FeedbackRoute]; | export const routesModuleList : AppRouteModule[] = [CompanyRoute,HomemakeRoute, JokSeekerRoute, JokFairRoute, InformationRoute, AdvertisementRoute, ActivityRoute, StatisticsRoute,PermissionRoute, SettingRoute, OtherRoute, FeedbackRoute]; |
| import Feedback from '@/views/feedback/index.vue'; | import Feedback from '@/views/feedback/index.vue'; | ||||
| import FeedbackList from '@/views/feedback/list/index.vue'; | import FeedbackList from '@/views/feedback/list/index.vue'; | ||||
| import Customer from '@/views/customer/index.vue'; | |||||
| import CustomerList from '@/views/customer/list/index.vue'; | |||||
| export const routerList = { | export const routerList = { | ||||
| Permission, | Permission, | ||||
| ROLE, | ROLE, | ||||
| Other, | Other, | ||||
| Tokenizer, | Tokenizer, | ||||
| Feedback, | Feedback, | ||||
| FeedbackList | |||||
| FeedbackList, | |||||
| Customer, | |||||
| CustomerList | |||||
| } | } |
| <template> | |||||
| <router-view></router-view> | |||||
| </template> | |||||
| <script> | |||||
| </script> | |||||
| <style> | |||||
| </style> |
| declare namespace CustomerListType { | |||||
| type addrFormType = { | |||||
| role?: Number, | |||||
| mobile?: String, | |||||
| username?: String, | |||||
| password?: String, | |||||
| email?: String, | |||||
| } | |||||
| type addOtherFormType = { | |||||
| } | |||||
| } | |||||
| <template> | |||||
| <a-modal v-model:visible="openAddModel" :title="title" ok-text="提交" cancel-text="取消" @ok="sumbitForm" | |||||
| @cancel="cancelModal" width="50%"> | |||||
| <a-form :model="createForm" :label-col="{span: 4}" labelAlign="right"> | |||||
| <a-row gutter="20"> | |||||
| <a-col span="24"> | |||||
| <a-form-item required label="角色" name="role"> | |||||
| <a-select v-model:value="createForm.role" placeholder="请选择角色"> | |||||
| <a-select-option v-for="(item,index) in role_list" :key="id" | |||||
| :value="item.id">{{item.name}}</a-select-option> | |||||
| </a-select> | |||||
| </a-form-item> | |||||
| </a-col> | |||||
| <a-col span="24"> | |||||
| <a-form-item required label="手机号" name="mobile"> | |||||
| <a-input v-model:value="createForm.mobile" placeholder="请输入手机号" /> | |||||
| </a-form-item> | |||||
| </a-col> | |||||
| <a-col span="24"> | |||||
| <a-form-item required label="密码" name="password"> | |||||
| <a-input-password placeholder="密码" | |||||
| v-model:value="createForm.password"></a-input-password> | |||||
| </a-form-item> | |||||
| </a-col> | |||||
| <a-col span="24"> | |||||
| <a-form-item required label="邮箱" name="email"> | |||||
| <a-input v-model:value="createForm.email" placeholder="请输入邮箱" /> | |||||
| </a-form-item> | |||||
| </a-col> | |||||
| </a-row> | |||||
| </a-form> | |||||
| </a-modal> | |||||
| </template> | |||||
| <script setup lang="ts"> | |||||
| import { ref, onMounted, computed, defineProps, watch, defineEmits } from 'vue'; | |||||
| import { PostCustomerAdd, GetCustomerUpdate,GetCustomerDetail, GetRoleList } from '@/apis/models'; | |||||
| import { dataForm, otherDataForm, reset } from '@/views/customer/list/add/data.ts'; | |||||
| import { useCommon } from '@/hooks/useCommon'; | |||||
| let { store, openAddModel, hideModal, message, richOption } = useCommon(); | |||||
| const emit = defineEmits(); | |||||
| let props = defineProps(['edit_record']); | |||||
| let title = ref<String>('新增账号'); | |||||
| let role_list = ref([]) | |||||
| onMounted(() => { | |||||
| getRole() | |||||
| }) | |||||
| const getRole = () => { | |||||
| GetRoleList({page: 1, pagesize: 100}).then(res => { | |||||
| role_list.value = res.data.roles | |||||
| }) | |||||
| } | |||||
| let createForm = ref<CustomerListType.addFormType>(dataForm) | |||||
| const sumbitForm = () => { | |||||
| if (!createForm.value.id) { | |||||
| PostCustomerAdd(createForm.value).then(res => { | |||||
| message.success('创建账号成功'); | |||||
| hideModal(); | |||||
| resetForm(); | |||||
| emit('successAdd'); | |||||
| }).catch(err => { | |||||
| }) | |||||
| } else { | |||||
| GetCustomerUpdate(createForm.value).then(res => { | |||||
| message.success('修改账号成功'); | |||||
| hideModal(); | |||||
| resetForm(); | |||||
| emit('successAdd'); | |||||
| }).catch(err => { | |||||
| }) | |||||
| } | |||||
| } | |||||
| const resetForm = () => { | |||||
| createForm.value = reset().dataForm; | |||||
| } | |||||
| const cancelModal = () => { | |||||
| emit('closeAdd'); | |||||
| resetForm(); | |||||
| hideModal(); | |||||
| } | |||||
| openAddModel = computed(() => { | |||||
| return store.state.openAddModel; | |||||
| }) | |||||
| watch(() => props.edit_record, (newVal) => { | |||||
| GetRoleList() | |||||
| if (newVal) { | |||||
| title.value = '编辑账号'; | |||||
| createForm.value = { | |||||
| id: newVal.id, | |||||
| name: newVal.name, | |||||
| address: newVal.address, | |||||
| telephone:newVal.telephone, | |||||
| fax: newVal.fax, | |||||
| postal: newVal.postal, | |||||
| email: newVal.email, | |||||
| content: newVal.content, | |||||
| } | |||||
| } else { | |||||
| title.value = '新增账号'; | |||||
| } | |||||
| }) | |||||
| </script> | |||||
| <style> | |||||
| </style> |
| export let dataForm = { | |||||
| role: null, | |||||
| mobile: '', | |||||
| username: '', | |||||
| password: '', | |||||
| email: '', | |||||
| } | |||||
| export let otherDataForm = { | |||||
| } | |||||
| export const reset = () => { | |||||
| dataForm = { | |||||
| role: null, | |||||
| mobile: '', | |||||
| username: '', | |||||
| password: '', | |||||
| email: '', | |||||
| }; | |||||
| otherDataForm = { | |||||
| } | |||||
| return { dataForm, otherDataForm } | |||||
| } |
| export const cols = <ColType.type[]>[ | |||||
| { | |||||
| title: '用户', | |||||
| dataIndex: 'name' | |||||
| }, | |||||
| { | |||||
| title: '邮箱', | |||||
| dataIndex: 'email' | |||||
| }, | |||||
| { | |||||
| title: '消息内容', | |||||
| dataIndex: 'content' | |||||
| }, | |||||
| { | |||||
| title: '操作', | |||||
| dataIndex: 'operation', | |||||
| slots: { | |||||
| customRender: 'operation' | |||||
| } | |||||
| } | |||||
| ]; |
| <template> | |||||
| <list-search @searchData="searchData" @clearData="clearData" :search_params="commomParams.search"></list-search> | |||||
| <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 #default="{ record }"> | |||||
| <a-row :gutter="10"> | |||||
| <a-col><a-button type="primary" size="small" primary @click="edit(record)">编辑</a-button></a-col> | |||||
| <a-popconfirm title="是否删除该反馈消息?" @confirm="del(record.id)"> | |||||
| <a-col><a-button type="primary" size="small" danger>删除</a-button></a-col> | |||||
| </a-popconfirm> | |||||
| </a-row> | |||||
| </template> | |||||
| </a-c-table> | |||||
| <list-add :edit_record="edit_record" @successAdd="successAdd" @closeAdd="closeAdd"></list-add> | |||||
| </template> | |||||
| <script lang="ts" setup> | |||||
| import { ref, onMounted, watch, computed } from 'vue'; | |||||
| import ListSearch from '@/views/customer/list/search/index.vue'; | |||||
| import ListAdd from '@/views/customer/list/add/add.vue'; | |||||
| import { GetCustomerList, GetCustomerDetail, PostCustomerDel } from '@/apis/models'; | |||||
| import { useCommon } from '@/hooks/useCommon'; | |||||
| import { cols } from '@/views/customer/list/columns'; | |||||
| let { store, commomParams, showModal, showOtherModal1, message } = useCommon(); | |||||
| let loading = ref<Boolean>(true); | |||||
| onMounted(() => { | |||||
| getData(commomParams.value.search); | |||||
| }) | |||||
| const searchData = (data : object) => { | |||||
| commomParams.value.search = data | |||||
| getData(); | |||||
| } | |||||
| const clearData = (data : object) => { | |||||
| if (data) { | |||||
| commomParams.value.search = data | |||||
| } else { | |||||
| commomParams.value.search = { | |||||
| page: 1, | |||||
| pagesize: 10, | |||||
| sort: 'id', | |||||
| sortby: 'asc', | |||||
| keyword: '' | |||||
| } | |||||
| } | |||||
| getData(); | |||||
| } | |||||
| const getPage = (data : object) => { | |||||
| commomParams.value.search.page = data.current; | |||||
| commomParams.value.search.pagesize = data.pageSize; | |||||
| getData(); | |||||
| } | |||||
| const getData = async () => { | |||||
| try { | |||||
| loading.value = true; | |||||
| let res = await GetCustomerList(commomParams.value.search); | |||||
| loading.value = false; | |||||
| commomParams.value.table.data = res.data.feedbacks; | |||||
| commomParams.value.table.columns = cols; | |||||
| commomParams.value.page = { | |||||
| current: commomParams.value.search.page, | |||||
| pageSize: commomParams.value.search.pagesize, | |||||
| total: res.data.total, | |||||
| pageSizeOptions: ['10', '20', '30', '40'], | |||||
| hideOnSinglePage: false, | |||||
| showSizeChanger: true | |||||
| }; | |||||
| } catch { | |||||
| loading.value = false; | |||||
| } | |||||
| } | |||||
| // 编辑 | |||||
| let edit_record = ref<Object>(null) | |||||
| const edit = (record : object) => { | |||||
| edit_record.value = record; | |||||
| showModal() | |||||
| } | |||||
| const successAdd = () => { | |||||
| getData(); | |||||
| } | |||||
| const closeAdd = () => { | |||||
| edit_record.value = null; | |||||
| } | |||||
| // 删除 | |||||
| const del = (id : number) => { | |||||
| commomParams.value.delRecord = { id: id }; | |||||
| PostCustomerDel(commomParams.value.delRecord).then(res => { | |||||
| message.success('删除成功'); | |||||
| getData(); | |||||
| }) | |||||
| } | |||||
| </script> | |||||
| <style lang="less" scoped> | |||||
| </style> |
| <template> | |||||
| <a-drawer :width="500" title="搜索" placement="right" :open="openSearchModel" @close="onClose"> | |||||
| <template #extra> | |||||
| <a-button style="margin-right: 8px" @click="clearSearch">清空搜索</a-button> | |||||
| <a-button type="primary" @click="getData">搜索</a-button> | |||||
| </template> | |||||
| <a-form :model="commomParams.search"> | |||||
| <a-row :gutter="[10]"> | |||||
| <a-col span="24"> | |||||
| <a-form-item> | |||||
| <a-input addon-before="配置项名称" v-model:value="commomParams.search.keyword" | |||||
| placeholder="请输入配置项名称" /> | |||||
| </a-form-item> | |||||
| </a-col> | |||||
| </a-row> | |||||
| </a-form> | |||||
| </a-drawer> | |||||
| </template> | |||||
| <script lang="ts" setup> | |||||
| import { ref, onMounted, watch, computed } from 'vue'; | |||||
| import { useCommon } from '@/hooks/useCommon'; | |||||
| let { store, commomParams, openSearchModel, hideSearch } = useCommon(); | |||||
| let props = defineProps(['search_params']); | |||||
| const emit = defineEmits(); | |||||
| openSearchModel = computed(() => { | |||||
| return store.state.openSearchModel; | |||||
| }) | |||||
| watch(() => props.search_params, (newVal) => { | |||||
| emit('searchData', commomParams.value.search) | |||||
| }) | |||||
| const getData = () => { | |||||
| emit('searchData', commomParams.value.search); | |||||
| hideSearch() | |||||
| } | |||||
| // 清空搜索 | |||||
| const clearSearch = () => { | |||||
| commomParams.value.search = { | |||||
| page: 1, | |||||
| pagesize: 10, | |||||
| sort: 'id', | |||||
| sortby: 'asc', | |||||
| keyword: '' | |||||
| } | |||||
| } | |||||
| const onClose = () => { | |||||
| clearSearch() | |||||
| hideSearch() | |||||
| } | |||||
| </script> | |||||
| <style> | |||||
| </style> |
| <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 { PostFeedbackAdd, PostFeedbackUpdate } from '@/apis/models'; | import { PostFeedbackAdd, PostFeedbackUpdate } from '@/apis/models'; | ||||
| import he from 'he'; | |||||
| import { dataForm, otherDataForm, reset } from '@/views/feedback/list/add/data.js'; | import { dataForm, otherDataForm, reset } from '@/views/feedback/list/add/data.js'; | ||||
| import { useCommon } from '@/hooks/useCommon'; | import { useCommon } from '@/hooks/useCommon'; | ||||
| let { store, openAddModel, hideModal, message, richOption } = useCommon(); | let { store, openAddModel, hideModal, message, richOption } = 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>('新增消息'); | ||||
| let showMap = ref<Boolean>(false); | |||||
| let createForm = ref<FeedbackListType.addFormType>(dataForm) | let createForm = ref<FeedbackListType.addFormType>(dataForm) | ||||
| emit('closeAdd'); | emit('closeAdd'); | ||||
| resetForm(); | resetForm(); | ||||
| hideModal(); | hideModal(); | ||||
| showMap.value = false; | |||||
| } | } | ||||
| </a-form-item> | </a-form-item> | ||||
| </a-col> | </a-col> | ||||
| <a-col span="24"> | <a-col span="24"> | ||||
| <a-form-item label="上传文件,可将链接放入文章内容"> | |||||
| <upload-file @uploadSuccess="uploadDocSuccess"></upload-file> | |||||
| <a-typography-paragraph v-if="createForm.doc_url" :copyable="{ text: imageprefix+createForm.doc_url}"> | |||||
| {{imageprefix+createForm.doc_url}} | |||||
| </a-typography-paragraph> | |||||
| <a-form-item label="上传文件"> | |||||
| <a-switch v-model:checked="showUplaod"> </a-switch> | |||||
| <div v-if="showUplaod" style="margin-top: 10px;"> | |||||
| <upload-file @uploadSuccess="uploadDocSuccess"></upload-file> | |||||
| <a-typography-paragraph v-if="createForm.doc_url" :copyable="{ text: imageprefix+createForm.doc_url}"> | |||||
| {{imageprefix+createForm.doc_url}} | |||||
| </a-typography-paragraph> | |||||
| </div> | |||||
| </a-form-item> | </a-form-item> | ||||
| </a-col> | </a-col> | ||||
| <a-col span="24"> | <a-col span="24"> | ||||
| let selectDisabled = ref<Boolean>(false) | let selectDisabled = ref<Boolean>(false) | ||||
| let success_img = ref<String>('') | let success_img = ref<String>('') | ||||
| const options = ref(richOption) | const options = ref(richOption) | ||||
| let showUplaod = ref<Boolean>(false) | |||||
| let createForm = ref<companyDepartmentType.addFormType>(dataForm) | let createForm = ref<companyDepartmentType.addFormType>(dataForm) | ||||
| let addOtherForm = ref<companyDepartmentType.addOtherFormType>(otherDataForm) | let addOtherForm = ref<companyDepartmentType.addOtherFormType>(otherDataForm) | ||||
| onMounted(() => { | onMounted(() => { | ||||
| sectionSearch({ page: 1, pagesize: 10 }) | |||||
| sectionSearch({ page: 1, pagesize: 100 }) | |||||
| }) | }) | ||||
| // 上传图片 | // 上传图片 |
| <a-row :gutter="10"> | <a-row :gutter="10"> | ||||
| <a-col :span="24"> | <a-col :span="24"> | ||||
| <a-form-item> | <a-form-item> | ||||
| <a-input size="large" type="password" placeholder="密码" | |||||
| v-model:value="createForm.password"> | |||||
| <template #prefix> | |||||
| <LockOutlined /> | |||||
| </template> | |||||
| <template #suffix> | |||||
| <a-tooltip title="Extra information"> | |||||
| <EyeInvisibleOutlined style="color: rgba(0, 0, 0, 0.25)" /> | |||||
| </a-tooltip> | |||||
| </template> | |||||
| </a-input> | |||||
| <a-input-password placeholder="密码" | |||||
| v-model:value="createForm.password"></a-input-password> | |||||
| </a-form-item> | </a-form-item> | ||||
| </a-col> | </a-col> | ||||
| </a-row> | </a-row> |