提交 0b3132a2 authored 作者: 王鹏飞's avatar 王鹏飞

chore: update

上级 db23da4b
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
"axios": "^0.27.2", "axios": "^0.27.2",
"blueimp-md5": "^2.19.0", "blueimp-md5": "^2.19.0",
"countup.js": "^2.2.0", "countup.js": "^2.2.0",
"dayjs": "^1.11.3",
"element-plus": "^2.2.5", "element-plus": "^2.2.5",
"pinia": "^2.0.14", "pinia": "^2.0.14",
"qs": "^6.10.5", "qs": "^6.10.5",
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
"axios": "^0.27.2", "axios": "^0.27.2",
"blueimp-md5": "^2.19.0", "blueimp-md5": "^2.19.0",
"countup.js": "^2.2.0", "countup.js": "^2.2.0",
"dayjs": "^1.11.3",
"element-plus": "^2.2.5", "element-plus": "^2.2.5",
"pinia": "^2.0.14", "pinia": "^2.0.14",
"qs": "^6.10.5", "qs": "^6.10.5",
......
...@@ -5,9 +5,15 @@ import type { UploadProps, UploadUserFile } from 'element-plus' ...@@ -5,9 +5,15 @@ import type { UploadProps, UploadUserFile } from 'element-plus'
import md5 from 'blueimp-md5' import md5 from 'blueimp-md5'
import { getSignature } from '@/api/base' import { getSignature } from '@/api/base'
const props = withDefaults(defineProps<{ modelValue: string | []; prefix?: string }>(), { interface Props {
modelValue: string | { name: string; url: string }[]
prefix?: string
}
const props = withDefaults(defineProps<Props>(), {
prefix: 'upload/admin/' prefix: 'upload/admin/'
}) })
const emit = defineEmits(['update:modelValue', 'success']) const emit = defineEmits(['update:modelValue', 'success'])
const uploadData = ref() const uploadData = ref()
...@@ -17,7 +23,7 @@ const fileList = ref<UploadUserFile[]>([]) ...@@ -17,7 +23,7 @@ const fileList = ref<UploadUserFile[]>([])
watch( watch(
() => props.modelValue, () => props.modelValue,
value => { value => {
fileList.value = Array.isArray(value) ? [...value] : [] fileList.value = Array.isArray(value) ? value.map(item => ({ ...item })) : []
} }
) )
...@@ -97,7 +103,7 @@ const handlePreview: UploadProps['onPreview'] = uploadFile => { ...@@ -97,7 +103,7 @@ const handlePreview: UploadProps['onPreview'] = uploadFile => {
<el-icon><Plus /></el-icon> <el-icon><Plus /></el-icon>
</template> </template>
<template v-else> <template v-else>
<el-button type="primary">点击上传</el-button> <el-button size="default" round>点击上传</el-button>
</template> </template>
</template> </template>
<div class="avatar-uploader" v-else> <div class="avatar-uploader" v-else>
......
...@@ -218,17 +218,22 @@ const rows: Record<string, any>[] = [ ...@@ -218,17 +218,22 @@ const rows: Record<string, any>[] = [
title: '发布项目', title: '发布项目',
// href: '/project/create' // href: '/project/create'
onClick() { onClick() {
ElMessage({ message: '暂未开放' }) if (!user.isLogin) {
location.href = `${import.meta.env.VITE_LOGIN_URL}?rd=${encodeURIComponent(location.href)}`
return
}
if (!user.hasCompany) {
ElMessage({ message: '请先注册您的企业' })
} else {
window.open('/project/create')
}
} }
}, },
{ {
icon: 'https://webapp-pub.ezijing.com/project/saas/icon_7_6.png', icon: 'https://webapp-pub.ezijing.com/project/saas/icon_7_6.png',
hoverIcon: 'https://webapp-pub.ezijing.com/project/saas/icon_7_6_hover.png', hoverIcon: 'https://webapp-pub.ezijing.com/project/saas/icon_7_6_hover.png',
title: '寻找项目', title: '寻找项目',
// href: '/project' href: '/project'
onClick() {
ElMessage({ message: '暂未开放' })
}
} }
] ]
} }
......
...@@ -10,5 +10,6 @@ export interface CompanyType { ...@@ -10,5 +10,6 @@ export interface CompanyType {
province: string province: string
city: string city: string
industry: string industry: string
status?: 1 | 2 | 3 | 4 status?: 1 | 2
audit_status?: 1 | 2 | 3
} }
...@@ -7,8 +7,6 @@ import type { CompanyType } from '../types' ...@@ -7,8 +7,6 @@ import type { CompanyType } from '../types'
import { companyTypeList, industryCategoryList } from '@/utils/dictionary' import { companyTypeList, industryCategoryList } from '@/utils/dictionary'
import { useArea } from '@/composables/useArea' import { useArea } from '@/composables/useArea'
const props = defineProps<{ id?: string }>()
const router = useRouter() const router = useRouter()
const formRef = ref<FormInstance>() const formRef = ref<FormInstance>()
...@@ -45,9 +43,9 @@ const { provinceList, cityList, provinceValue } = useArea() ...@@ -45,9 +43,9 @@ const { provinceList, cityList, provinceValue } = useArea()
function onProvinceChange() { function onProvinceChange() {
provinceValue.value = form.province provinceValue.value = form.province
} }
// 待审核可以修改 // 审核不通过可以修改
const disabled = computed(() => { const disabled = computed(() => {
return !(!form.status || form.status === 4) return form.audit_status === 1 || form.audit_status === 3
}) })
// 提交 // 提交
...@@ -65,11 +63,14 @@ const onCancel = () => { ...@@ -65,11 +63,14 @@ const onCancel = () => {
// 修改 // 修改
const update = () => { const update = () => {
const params = { ...form, id: props.id as string } updateCompany(form)
updateCompany(params).then(() => { .then(() => {
ElMessage({ message: '提交成功', type: 'success' }) ElMessage({ message: '提交成功', type: 'success' })
router.push('/') router.push('/')
}) })
.catch(res => {
ElMessage.error(res.message)
})
} }
onMounted(() => { onMounted(() => {
...@@ -85,9 +86,9 @@ onMounted(() => { ...@@ -85,9 +86,9 @@ onMounted(() => {
<p class="company-register__tips">请完成企业信息认证,完成后即可发布职位</p> <p class="company-register__tips">请完成企业信息认证,完成后即可发布职位</p>
<AppCard> <AppCard>
<div class="company-register__status"> <div class="company-register__status">
<p style="color: #60b0ea" v-if="form.status === 3">待审核</p> <p style="color: #1dc388" v-if="form.audit_status === 1">审核通过</p>
<p style="color: #1dc388" v-if="form.status === 1">审核通过</p> <p style="color: #898989" v-if="form.audit_status === 2">审核不通过</p>
<p style="color: #898989" v-if="form.status === 4">审核不通过</p> <p style="color: #60b0ea" v-if="form.audit_status === 3">待审核</p>
<p style="color: #f8524b" v-if="form.status === 2">已禁用</p> <p style="color: #f8524b" v-if="form.status === 2">已禁用</p>
</div> </div>
<el-form <el-form
......
import httpRequest from '@/utils/axios' import httpRequest from '@/utils/axios'
import type { CompanyType } from './types' import type { ProjectType } from './types'
// 创建公司 // 获取我的项目列表
export function createCompany(data: CompanyType) { export function getMyProjectList(params: { page: number; limit: number }) {
return httpRequest.post('/api/psp/backend/banner/create', data) return httpRequest.get('/api/hr/api/v1/projects/my-list', { params })
} }
// 更新公司 // 获取项目列表
export function updateCompany(data: CompanyType) { export function getProjectList(params: { page?: number; limit?: number; name?: string }) {
return httpRequest.post('/api/psp/backend/banner/update', data) return httpRequest.get('/api/hr/api/v1/projects', { params })
} }
// 获取公司详情 // 创建项目
export function getCompany(params: { id: string }) { export function createProject(data: ProjectType) {
return httpRequest.get('/api/psp/backend/banner/view', { params }) return httpRequest.post('/api/hr/api/v1/project/publish', data)
}
// 更新项目
export function updateProject(data: ProjectType) {
return httpRequest.put(`/api/hr/api/v1/project/${data.id}/update`, data)
}
// 获取项目详情
export function getProject(params: { id: string }) {
return httpRequest.get(`/api/hr/api/v1/project/${params.id}/detail`, { params })
}
// 项目审核
export function auditProject(data: { id: string; status: 1 | 2 }) {
return httpRequest.post(`/api/hr/api/v1/project/${data.id}/audit`, data)
} }
<script setup lang="ts">
import { Plus } from '@element-plus/icons-vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import type { ProjectType } from '../types'
import ProjectListItem from './ProjectListItem.vue'
import { getMyProjectList, auditProject } from '../api'
const dataset = reactive<{ total: number; list: ProjectType[] }>({ total: 0, list: [] })
const params = reactive({ page: 1, limit: 3 })
let loading = $ref(false)
function fetchList() {
loading = true
getMyProjectList(params)
.then(res => {
const { total, data: list } = res.data
dataset.total = total
dataset.list = list
})
.finally(() => {
loading = false
})
}
watch(
() => params.page,
() => {
fetchList()
}
)
onMounted(() => {
fetchList()
})
// 启用/禁用
function onAudit(status: 1 | 2, data: ProjectType) {
const statusText = status === 1 ? '启用' : '禁用'
ElMessageBox.confirm(`确定要${statusText}该项目吗?`).then(() => {
auditProject({ status, id: data.id as string })
.then(() => {
ElMessage.success(`${statusText}成功`)
fetchList()
})
.catch(res => {
ElMessage.error(res.message)
})
})
}
</script>
<template>
<div class="project-header">
<h2 class="subtitle">我的项目</h2>
<el-pagination
background
layout="prev, next"
v-model:current-page="params.page"
:page-size="params.limit"
:total="dataset.total"
/>
</div>
<div class="project-list" v-loading="loading">
<ProjectListItem v-for="item in dataset.list" :key="item.id" :data="item" isMine @audit="onAudit"></ProjectListItem>
<div class="project-item">
<router-link to="/project/create" class="project-item__add"><Plus />发布新项目</router-link>
</div>
</div>
</template>
<style lang="scss" scoped>
.project-header {
display: flex;
align-items: center;
justify-content: space-between;
}
.project-list {
display: grid;
grid-template-columns: repeat(4, 1fr);
column-gap: 20px;
row-gap: 20px;
}
.project-item__add {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: 20px;
font-weight: 400;
line-height: 34px;
color: #666666;
cursor: pointer;
svg {
width: 30px;
}
}
</style>
<script setup lang="ts">
import type { ProjectType } from '../types'
defineProps<{ data: ProjectType }>()
</script>
<template>
<div class="project-item">
<router-link :to="`/project/view/${data.id}`" target="_blank">
<img :src="data.logo" class="project-item__pic" />
<div class="project-item__content">
<h2>{{ data.name }}</h2>
<p>{{ data.desc }}</p>
</div>
</router-link>
</div>
</template>
<style lang="scss">
.project-item {
margin-bottom: 20px;
width: 275px;
height: 305px;
background: #fafafa;
border-radius: 6px;
}
.project-item__pic {
width: 100%;
height: 142px;
object-fit: cover;
}
.project-item__content {
padding: 16px;
h2 {
margin-bottom: 18px;
font-size: 18px;
font-weight: 500;
line-height: 1;
color: #333333;
}
p {
font-size: 14px;
font-weight: 300;
line-height: 24px;
color: #666666;
}
}
</style>
<script setup lang="ts">
import type { ProjectType } from '../types'
import ProjectListItem from './ProjectListItem.vue'
import { getProjectList } from '../api'
const dataset = reactive<{ total: number; list: ProjectType[] }>({ total: 0, list: [] })
const params = reactive({ page: 1, limit: 4 })
let loading = $ref(false)
function fetchList() {
loading = true
getProjectList(params)
.then(res => {
const { total, data: list } = res.data
dataset.total = total
dataset.list = list
})
.finally(() => {
loading = false
})
}
watch(
() => params.page,
() => {
fetchList()
}
)
onMounted(() => {
fetchList()
})
</script>
<template>
<div class="project-header">
<h2 class="subtitle">项目列表</h2>
<el-pagination
background
layout="prev, next"
v-model:current-page="params.page"
:page-size="params.limit"
:total="dataset.total"
/>
</div>
<div class="project-list" v-loading="loading">
<ProjectListItem v-for="item in dataset.list" :key="item.id" :data="item"></ProjectListItem>
</div>
</template>
<style lang="scss" scoped>
.project-header {
display: flex;
align-items: center;
justify-content: space-between;
}
.project-list {
display: grid;
grid-template-columns: repeat(4, 1fr);
column-gap: 20px;
row-gap: 20px;
}
</style>
<script setup lang="ts">
import type { ProjectType } from '../types'
const props = defineProps<{ data: ProjectType; isMine?: boolean }>()
const emit = defineEmits<{
(e: 'audit', status: 1 | 2, data: ProjectType): void
}>()
const descHtml = computed(() => {
return props.data.desc.replace(/\n/g, '<br />')
})
</script>
<template>
<div class="project-item">
<router-link :to="`/project/view/${data.id}`" target="_blank">
<img :src="data.logo" class="project-item__pic" lazy />
<div class="project-item-main">
<div class="project-item__header">
<h2>{{ data.name }}</h2>
<template v-if="isMine">
<p style="color: #1dc388" v-if="data.audit_status === 1">审核通过</p>
<p style="color: #898989" v-if="data.audit_status === 2">审核不通过</p>
<p style="color: #60b0ea" v-if="data.audit_status === 3">待审核</p>
</template>
</div>
<p v-html="descHtml" class="project-item__content"></p>
</div>
</router-link>
<ul class="project-actions" v-if="isMine && data.audit_status === 1">
<li style="color: #60b0ea" v-if="data.status === 2" @click="emit('audit', 1, data)">启用</li>
<li style="color: #f84e46" v-if="data.status === 1" @click="emit('audit', 2, data)">禁用</li>
</ul>
</div>
</template>
<style lang="scss">
.project-item {
position: relative;
margin-bottom: 20px;
background: #fafafa;
border-radius: 6px;
overflow: hidden;
&:hover {
box-shadow: 0px 0px 12px rgba(0, 0, 0, 0.12);
}
}
.project-item__pic {
width: 100%;
height: 142px;
object-fit: cover;
}
.project-item-main {
height: 130px;
margin: 16px;
overflow: hidden;
}
.project-item__header {
display: flex;
h2 {
flex: 1;
margin-bottom: 18px;
font-size: 18px;
font-weight: 500;
line-height: 1;
color: #333333;
overflow: hidden;
}
p {
padding-left: 10px;
}
}
.project-item__content {
font-size: 14px;
font-weight: 300;
line-height: 24px;
color: #666666;
}
.project-actions {
position: absolute;
top: 0;
right: 0;
z-index: 1;
display: flex;
background: rgba(255, 255, 255, 0.86);
opacity: 1;
border-radius: 0px 6px 0px 6px;
li {
line-height: 25px;
padding: 0 7px;
cursor: pointer;
}
}
</style>
...@@ -8,7 +8,7 @@ export const routes: Array<RouteRecordRaw> = [ ...@@ -8,7 +8,7 @@ export const routes: Array<RouteRecordRaw> = [
children: [ children: [
{ path: '', component: () => import('./views/Index.vue') }, { path: '', component: () => import('./views/Index.vue') },
{ path: 'create', component: () => import('./views/Update.vue') }, { path: 'create', component: () => import('./views/Update.vue') },
{ path: 'update/:id', component: () => import('./views/Update.vue') }, { path: 'update/:id', component: () => import('./views/Update.vue'), props: true },
{ path: 'view/:id', component: () => import('./views/View.vue'), props: true } { path: 'view/:id', component: () => import('./views/View.vue'), props: true }
] ]
} }
......
export interface ProjectType { export interface ProjectType {
id: string id?: string
name: string name: string
logo: string logo: string
type: 1 | 2 | 3 type: 1 | 2 | 3
start_time: string
end_time: string
desc: string desc: string
contact: string contact: string
contact_mobile: string contact_mobile: string
status: 1 | 2 | 3 | 4 documents: { name: string; url: string }[]
documents: string[] status?: 1 | 2
audit_status?: 1 | 2 | 3
is_mine?: boolean
} }
export interface CompanyType { export interface ResponseType {
id?: string code: number
name: string message: string
logo: string }
desc: string
email: string export interface ProjectListResponseType extends ResponseType {
nature: string data: { total: number; data: ProjectType[] }
code: string
business_licence: string
} }
<script setup lang="ts"> <script setup lang="ts">
import { Plus } from '@element-plus/icons-vue' import MyProjectList from '../components/MyProjectList.vue'
import type { ProjectType } from '../types' import ProjectList from '../components/ProjectList.vue'
import ProjectItem from '../components/ProjectItem.vue'
const projectList = ref<ProjectType[]>([
{
id: '1',
name: 'SEAL学习中心',
logo: 'https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png',
type: 1,
desc: '中加本硕直通车项目是针对大专及本科生提升学历、移居海外的定制通道。采用国内2.5+1.5(专升本)/3.5+2(本硕连读)年的…',
contact: '123',
contact_mobile: '123',
status: 1,
documents: []
},
{
id: '2',
name: '项目1',
logo: 'https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png',
type: 1,
desc: '中加本硕直通车项目是针对大专及本科生提升学历、移居海外的定制通道。采用国内2.5+1.5(专升本)/3.5+2(本硕连读)年的…',
contact: '123',
contact_mobile: '123',
status: 2,
documents: []
}
])
</script> </script>
<template> <template>
<AppContainer background="#fff"> <AppContainer background="#fff">
<section> <MyProjectList></MyProjectList>
<h2 class="subtitle">我的项目</h2> <ProjectList></ProjectList>
<div class="project-list">
<ProjectItem v-for="item in projectList" :key="item.id" :data="item"></ProjectItem>
<div class="project-item">
<router-link to="/project/create" class="project-item__add"><Plus />发布新项目</router-link>
</div>
</div>
</section>
<section>
<h2 class="subtitle">项目列表</h2>
<div class="project-list">
<ProjectItem v-for="item in projectList" :key="item.id" :data="item"></ProjectItem>
</div>
</section>
</AppContainer> </AppContainer>
</template> </template>
<style lang="scss">
.project-list {
display: flex;
flex-wrap: wrap;
.project-item {
margin-right: 20px;
}
}
.project-item__add {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: 20px;
font-weight: 400;
line-height: 34px;
color: #666666;
cursor: pointer;
svg {
width: 30px;
}
}
</style>
<script setup lang="ts"> <script setup lang="ts">
import dayjs from 'dayjs'
import { ElMessage } from 'element-plus' import { ElMessage } from 'element-plus'
import type { FormInstance } from 'element-plus' import type { FormInstance, FormRules } from 'element-plus'
import AppEditor from '@/components/tinymce/Index.vue' import { createProject, updateProject, getProject } from '../api'
import { createCompany, updateCompany, getCompany } from '../api' import type { ProjectType } from '../types'
import type { CompanyType } from '../types' import { projectTypeList } from '@/utils/dictionary'
const props = defineProps<{ id?: string }>() const props = defineProps<{ id?: string }>()
const router = useRouter() const router = useRouter()
const formRef = ref<FormInstance>() const formRef = ref<FormInstance>()
const form = reactive<CompanyType>({ const form = reactive<ProjectType>({
logo: '', logo: '',
name: '', name: '',
type: 1,
start_time: '',
end_time: '',
desc: '', desc: '',
email: '', contact: '',
nature: '', contact_mobile: '',
code: '', documents: []
business_licence: ''
}) })
const rules = { const rules = reactive<FormRules>({
logo: [{ required: true, message: '请上传项目图片', trigger: 'change' }], logo: [{ required: true, message: '请上传项目图片', trigger: 'change' }],
name: [{ required: true, message: '请输入项目名称', trigger: 'blur' }], name: [{ required: true, message: '请输入项目名称', trigger: 'blur' }],
type: [{ required: true, message: '请选择项目类型', trigger: 'change' }],
start_time: [{ required: true, message: '请选择项目开始时间', trigger: 'change' }],
end_time: [{ required: true, message: '请选择项目结束时间', trigger: 'change' }],
desc: [{ required: true, message: '请输入项目介绍', trigger: 'blur' }], desc: [{ required: true, message: '请输入项目介绍', trigger: 'blur' }],
email: [{ required: true, message: '请输入企业邮箱', trigger: 'blur' }], contact: [{ required: true, message: '请输入联系人', trigger: 'blur' }],
nature: [{ required: true, message: '请选择项目类型', trigger: 'blur' }], contact_mobile: [{ required: true, message: '请输入联系人电话', trigger: 'blur' }],
code: [{ required: true, message: '请输入社会统一信用代码', trigger: 'blur' }], documents: [{ required: true, message: '请上传项目文件', trigger: 'change' }]
business_licence: [{ required: true, message: '请上传营业执照附件', trigger: 'change' }] })
}
// 提交 // 提交
const onSubmit = () => { const onSubmit = () => {
if (!formRef.value) return if (!formRef.value) return
...@@ -42,24 +47,36 @@ const onCancel = () => { ...@@ -42,24 +47,36 @@ const onCancel = () => {
} }
// 创建 // 创建
const create = () => { const create = () => {
createCompany(form).then(() => { createProject(form)
.then(() => {
ElMessage({ message: '创建成功', type: 'success' }) ElMessage({ message: '创建成功', type: 'success' })
router.push('/project') router.push('/project')
}) })
.catch(res => {
ElMessage.error(res.message)
})
} }
// 修改 // 修改
const update = () => { const update = () => {
const params = { ...form, id: props.id as string } const params = { ...form, id: props.id as string }
updateCompany(params).then(() => { updateProject(params)
.then(() => {
ElMessage({ message: '修改成功', type: 'success' }) ElMessage({ message: '修改成功', type: 'success' })
router.push('/project') router.push('/project/view/' + props.id)
})
.catch(res => {
ElMessage.error(res.message)
}) })
} }
onMounted(() => { onMounted(() => {
props.id && props.id &&
getCompany({ id: props.id }).then(res => { getProject({ id: props.id }).then(res => {
Object.assign(form, res.data) const { detail } = res.data
Object.assign(form, detail, {
start_time: dayjs(detail.start_time).format('YYYY-MM-DD'),
end_time: dayjs(detail.end_time).format('YYYY-MM-DD')
})
}) })
}) })
</script> </script>
...@@ -82,25 +99,38 @@ onMounted(() => { ...@@ -82,25 +99,38 @@ onMounted(() => {
<el-form-item label="项目名称" prop="name"> <el-form-item label="项目名称" prop="name">
<el-input v-model="form.name" placeholder="请输入" /> <el-input v-model="form.name" placeholder="请输入" />
</el-form-item> </el-form-item>
<el-form-item label="项目类型" prop="nature"> <el-form-item label="项目类型" prop="type">
<el-input v-model="form.nature" placeholder="请选择" /> <el-select v-model="form.type" placeholder="请选择" style="width: 100%">
<el-option v-for="item in projectTypeList" v-bind="item" :key="item.value"></el-option>
</el-select>
</el-form-item> </el-form-item>
<el-form-item label="开始时间" prop="nature"> <el-form-item label="开始时间" prop="start_time">
<el-input v-model="form.nature" placeholder="请选择" /> <el-date-picker v-model="form.start_time" value-format="YYYY-MM-DD" placeholder="请选择" style="width: 100%" />
</el-form-item> </el-form-item>
<el-form-item label="结束时间" prop="nature"> <el-form-item label="结束时间" prop="end_time">
<el-input v-model="form.nature" placeholder="请选择" /> <el-date-picker v-model="form.end_time" value-format="YYYY-MM-DD" placeholder="请选择" style="width: 100%" />
</el-form-item> </el-form-item>
<el-form-item label="项目介绍" prop="desc"> <el-form-item label="项目介绍" prop="desc">
<AppEditor v-model="form.desc" placeholder="请输入"></AppEditor> <el-input
type="textarea"
v-model="form.desc"
placeholder="请输入"
:autosize="{ minRows: 10, maxRows: 20 }"
></el-input>
</el-form-item>
<el-form-item label="联系人" prop="contact">
<el-input v-model="form.contact" placeholder="请输入" />
</el-form-item> </el-form-item>
<el-form-item label="项目文件" prop="business_licence"> <el-form-item label="联系电话" prop="contact_mobile">
<AppUpload v-model="form.business_licence" accept="image/*"></AppUpload> <el-input v-model="form.contact_mobile" placeholder="请输入" />
</el-form-item> </el-form-item>
<el-form-item> <el-form-item label="项目文件" prop="documents">
<el-button type="primary" auto-insert-space @click="onSubmit">发布项目</el-button> <AppUpload v-model="form.documents"></AppUpload>
<el-button auto-insert-space @click="onCancel">取消</el-button>
</el-form-item> </el-form-item>
<el-row justify="center" style="margin: 60px 0 20px">
<el-button type="primary" auto-insert-space @click="onSubmit" style="border-radius: 10px">发布项目</el-button>
<el-button auto-insert-space @click="onCancel" v-if="false">取消</el-button>
</el-row>
</el-form> </el-form>
</AppContainer> </AppContainer>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
const files = [ import dayjs from 'dayjs'
{ import { getProject } from '../api'
name: 'index.ts', import type { ProjectType } from '../types'
url: 'https://raw.githubusercontent.com/vuejs/vue/dev/examples/todo/src/index.ts' import { projectType } from '@/utils/dictionary'
},
{ const props = defineProps<{ id: string }>()
name: 'index.ts', let loading = $ref(false)
url: 'https://raw.githubusercontent.com/vuejs/vue/dev/examples/todo/src/index.ts' const data = reactive<ProjectType>({
} name: '',
] logo: '',
type: 1,
start_time: '',
end_time: '',
desc: '',
contact: '',
contact_mobile: '',
documents: []
})
const files = computed(() => {
return data.documents || []
})
const typeName = computed(() => {
return projectType[data.type] || data.type
})
const descHtml = computed(() => {
return data.desc.replace(/\n/g, '<br />')
})
const canEdit = computed(() => data.is_mine && data.audit_status !== 3)
function fetchDetail() {
loading = true
getProject({ id: props.id })
.then(res => {
Object.assign(data, res.data.detail)
})
.finally(() => {
loading = false
})
}
onMounted(() => {
fetchDetail()
})
function formatDate(timeStr: string) {
return dayjs(timeStr).format('YYYY-MM-DD')
}
</script> </script>
<template> <template>
<AppCard> <AppCard v-loading="loading">
<section class="project-info"> <section class="project-info">
<img src="https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png" class="project-info__pic" /> <div class="buttons" v-if="canEdit">
<router-link :to="`/project/update/${id}`">
<el-button size="default">编辑</el-button>
</router-link>
</div>
<a :href="data.logo" target="_blank"><img :src="data.logo" class="project-info__pic" lazy /></a>
<div class="project-info__forms"> <div class="project-info__forms">
<dl> <dl>
<dt>项目名称</dt> <dt>项目名称</dt>
<dd>abc</dd> <dd>{{ data.name }}</dd>
</dl> </dl>
<dl> <dl>
<dt>开始时间</dt> <dt>开始时间</dt>
<dd>abc</dd> <dd>{{ formatDate(data.start_time) }}</dd>
</dl> </dl>
<dl> <dl>
<dt>联系人</dt> <dt>联系人</dt>
<dd>abc</dd> <dd>{{ data.contact }}</dd>
</dl> </dl>
<dl> <dl>
<dt>项目类型</dt> <dt>项目类型</dt>
<dd>abc</dd> <dd>{{ typeName }}</dd>
</dl> </dl>
<dl> <dl>
<dt>结束时间</dt> <dt>结束时间</dt>
<dd>abc</dd> <dd>{{ formatDate(data.end_time) }}</dd>
</dl> </dl>
<dl> <dl>
<dt>联系电话</dt> <dt>联系电话</dt>
<dd>abc</dd> <dd>{{ data.contact_mobile }}</dd>
</dl> </dl>
</div> </div>
</section> </section>
<section class="project-desc"> <section class="project-desc">
<h2 class="subtitle">项目介绍</h2> <h2 class="subtitle">项目介绍</h2>
<div class="box"> <div class="box" v-html="descHtml"></div>
中加本硕直通车项目是针对大专及本科生提升学历、移居海外的定制通道。
采用国内2.5+1.5(专升本)/3.5+2(本硕连读)年的合作模式即可分别获得加拿大卡普顿大学的本科与硕士学位,符合条件的国内院校的大专及本科生分别在国内完成2.5年及3.5年的专科和本科的学习,可直接进入加拿大卡普顿大学进行本科和硕士阶段的学习。本项目对接经教育部认证的国外名校,旨在帮助学生缩短留学周期,让学生顺利完成国外规定的学业课程,获得国外学位及移民海外的需求。
</div>
</section> </section>
<section class="project-files"> <section class="project-files">
<h2 class="subtitle">项目文件</h2> <h2 class="subtitle">项目文件</h2>
...@@ -63,14 +101,21 @@ const files = [ ...@@ -63,14 +101,21 @@ const files = [
</AppCard> </AppCard>
</template> </template>
<style lang="scss"> <style lang="scss" scoped>
.buttons {
position: absolute;
right: 0;
top: 0;
}
.project-info { .project-info {
position: relative;
display: flex; display: flex;
align-items: center; align-items: center;
} }
.project-info__pic { .project-info__pic {
width: 242px; width: 242px;
height: 155px; height: 155px;
object-fit: cover;
border-radius: 10px; border-radius: 10px;
overflow: hidden; overflow: hidden;
} }
......
...@@ -28,7 +28,7 @@ export const useUserStore = defineStore({ ...@@ -28,7 +28,7 @@ export const useUserStore = defineStore({
this.user = res.data this.user = res.data
if (this.isLogin) { if (this.isLogin) {
const { data: alumniUser } = await getAlumniUserInfo() const { data: alumniUser } = await getAlumniUserInfo()
this.hasCompany = alumniUser.is_registered_company this.hasCompany = alumniUser.is_registered_company && alumniUser.company_audit_status === 1
this.projects = alumniUser.projects this.projects = alumniUser.projects
} }
}, },
......
...@@ -21,13 +21,20 @@ export const companyTypeList = json2Array(companyType) ...@@ -21,13 +21,20 @@ export const companyTypeList = json2Array(companyType)
// 状态 // 状态
export const status = { export const status = {
1: '启用', 1: '启用',
2: '禁用', 2: '禁用'
3: '待审核',
4: '审核不通过'
} }
// 状态列表 // 状态列表
export const statusList = json2Array(status) export const statusList = json2Array(status)
// 审核状态
export const auditStatus = {
1: '审核通过',
2: '审核不通过',
3: '待审核'
}
// 审核状态列表
export const auditStatusList = json2Array(status)
// 学历 // 学历
export const education = { export const education = {
1: '高中或以下', 1: '高中或以下',
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论