|
@@ -1,23 +1,69 @@
|
|
<template>
|
|
<template>
|
|
<div class="main animate__animated animate__backInRight">
|
|
<div class="main animate__animated animate__backInRight">
|
|
- <custom-search-bar v-model="searchForm" :fields="fields.filter((f) => f.filter)" @search="search" @reset="toReset"></custom-search-bar>
|
|
|
|
- <custom-table :data="data" :fields="fields" @search="search" :total="total" :opera="opera" @exam="toExam" @view="toView" @delete="toDelete"> </custom-table>
|
|
|
|
- <el-dialog v-model="dialog.show" :title="dialog.title" :destroy-on-close="false" @close="toClose">
|
|
|
|
|
|
+ <custom-search-bar
|
|
|
|
+ v-model="searchForm"
|
|
|
|
+ :fields="fields.filter((f) => f.filter)"
|
|
|
|
+ @search="search"
|
|
|
|
+ @reset="toReset"
|
|
|
|
+ ></custom-search-bar>
|
|
|
|
+ <custom-table
|
|
|
|
+ :data="data"
|
|
|
|
+ :fields="fields"
|
|
|
|
+ @search="search"
|
|
|
|
+ :total="total"
|
|
|
|
+ :opera="opera"
|
|
|
|
+ @view="toView"
|
|
|
|
+ @exam="toExam"
|
|
|
|
+ @delete="toDelete"
|
|
|
|
+ >
|
|
|
|
+ <template #role="{ row }">
|
|
|
|
+ <div class="tags">
|
|
|
|
+ <el-tag v-for="(item, index) in row.role" :key="index" type="primary">{{
|
|
|
|
+ getRole(item)
|
|
|
|
+ }}</el-tag>
|
|
|
|
+ </div>
|
|
|
|
+ </template>
|
|
|
|
+ </custom-table>
|
|
|
|
+ <el-dialog
|
|
|
|
+ v-model="dialog.show"
|
|
|
|
+ :title="dialog.title"
|
|
|
|
+ :destroy-on-close="false"
|
|
|
|
+ @close="toClose"
|
|
|
|
+ >
|
|
<el-row>
|
|
<el-row>
|
|
<el-col :span="24" v-if="dialog.type == '1'">
|
|
<el-col :span="24" v-if="dialog.type == '1'">
|
|
- <custom-form v-model="form" :fields="formFields" :useSave="false">
|
|
|
|
- <template #gender>
|
|
|
|
- <el-option v-for="i in genderList" :key="i._id" :label="i.label" :value="i.value"></el-option>
|
|
|
|
- </template>
|
|
|
|
- <template #role>
|
|
|
|
- {{ getRole(form.role) }}
|
|
|
|
- </template>
|
|
|
|
- </custom-form>
|
|
|
|
|
|
+ <el-tabs v-model="type" type="card" @tab-change="toChang">
|
|
|
|
+ <el-tab-pane
|
|
|
|
+ v-for="(item, index) in role"
|
|
|
|
+ :key="index"
|
|
|
|
+ :label="getRole(item)"
|
|
|
|
+ :name="item"
|
|
|
|
+ ></el-tab-pane>
|
|
|
|
+ </el-tabs>
|
|
|
|
+ <user v-if="type == 'User'"></user>
|
|
|
|
+ <expert v-if="type == 'Expert'"></expert>
|
|
|
|
+ <company v-if="type == 'Company'"></company>
|
|
|
|
+ <incubator v-if="type == 'Incubator'"></incubator>
|
|
|
|
+ <competition v-if="type == 'Competition'"></competition>
|
|
|
|
+ <investment v-if="type == 'Investment'"></investment>
|
|
|
|
+ <association v-if="type == 'Association'"></association>
|
|
|
|
+ <state v-if="type == 'State'"></state>
|
|
|
|
+ <unit v-if="type == 'Unit'"></unit>
|
|
</el-col>
|
|
</el-col>
|
|
<el-col :span="24" v-if="dialog.type == '2'">
|
|
<el-col :span="24" v-if="dialog.type == '2'">
|
|
- <custom-form v-model="examForm" :fields="examFormFields" :rules="examRules" @save="toExamSave">
|
|
|
|
|
|
+ <custom-form
|
|
|
|
+ v-model="examForm"
|
|
|
|
+ :fields="examFormFields"
|
|
|
|
+ :rules="examRules"
|
|
|
|
+ @save="toExamSave"
|
|
|
|
+ >
|
|
<template #status>
|
|
<template #status>
|
|
- <el-option v-for="i in statusList" :key="i._id" :label="i.label" :value="i.value"></el-option>
|
|
|
|
|
|
+ <el-option
|
|
|
|
+ v-for="i in statusList"
|
|
|
|
+ :key="i._id"
|
|
|
|
+ :label="i.label"
|
|
|
|
+ :value="i.value"
|
|
|
|
+ ></el-option>
|
|
</template>
|
|
</template>
|
|
</custom-form>
|
|
</custom-form>
|
|
</el-col>
|
|
</el-col>
|
|
@@ -27,6 +73,18 @@
|
|
</template>
|
|
</template>
|
|
|
|
|
|
<script setup>
|
|
<script setup>
|
|
|
|
+// 组件
|
|
|
|
+import user from './parts/user.vue'
|
|
|
|
+import association from './parts/association.vue'
|
|
|
|
+import company from './parts/company.vue'
|
|
|
|
+import competition from './parts/competition.vue'
|
|
|
|
+import expert from './parts/expert.vue'
|
|
|
|
+import incubator from './parts/incubator.vue'
|
|
|
|
+import state from './parts/state.vue'
|
|
|
|
+import unit from './parts/unit.vue'
|
|
|
|
+import investment from './parts/investment.vue'
|
|
|
|
+// API 引用
|
|
|
|
+import { getCity } from '@/utils/city'
|
|
import { UserStore } from '@/store/api/user/user'
|
|
import { UserStore } from '@/store/api/user/user'
|
|
import { RoleStore } from '@/store/api/system/role'
|
|
import { RoleStore } from '@/store/api/system/role'
|
|
import { DictDataStore } from '@/store/api/system/dictData'
|
|
import { DictDataStore } from '@/store/api/system/dictData'
|
|
@@ -35,12 +93,31 @@ const $checkRes = inject('$checkRes')
|
|
const store = UserStore()
|
|
const store = UserStore()
|
|
const dictDataStore = DictDataStore()
|
|
const dictDataStore = DictDataStore()
|
|
const roleStore = RoleStore()
|
|
const roleStore = RoleStore()
|
|
|
|
+// 接口
|
|
|
|
+import { UnitStore } from '@/store/api/user/unit'
|
|
|
|
+const unitStore = UnitStore()
|
|
|
|
+import { ExpertStore } from '@/store/api/user/expert'
|
|
|
|
+const expertStore = ExpertStore()
|
|
|
|
+import { AssociationStore } from '@/store/api/user/association'
|
|
|
|
+const associationStore = AssociationStore()
|
|
|
|
+import { CompanyStore } from '@/store/api/user/company'
|
|
|
|
+const companyStore = CompanyStore()
|
|
|
|
+import { CompetitionStore } from '@/store/api/user/competition'
|
|
|
|
+const competitionStore = CompetitionStore()
|
|
|
|
+import { IncubatorStore } from '@/store/api/user/incubator'
|
|
|
|
+const incubatorStore = IncubatorStore()
|
|
|
|
+import { InvestmentStore } from '@/store/api/user/investment'
|
|
|
|
+const investmentStore = InvestmentStore()
|
|
|
|
+import { StateStore } from '@/store/api/user/state'
|
|
|
|
+const stateStore = StateStore()
|
|
const { t } = useI18n()
|
|
const { t } = useI18n()
|
|
const loading = ref(false)
|
|
const loading = ref(false)
|
|
let skip = 0
|
|
let skip = 0
|
|
let limit = inject('limit')
|
|
let limit = inject('limit')
|
|
const data = ref([])
|
|
const data = ref([])
|
|
const total = ref(0)
|
|
const total = ref(0)
|
|
|
|
+const type = ref('User')
|
|
|
|
+const role = ref([])
|
|
onMounted(async () => {
|
|
onMounted(async () => {
|
|
loading.value = true
|
|
loading.value = true
|
|
await searchOther()
|
|
await searchOther()
|
|
@@ -51,20 +128,23 @@ const fields = [
|
|
{ label: t('pages.user.account'), model: 'account', filter: true },
|
|
{ label: t('pages.user.account'), model: 'account', filter: true },
|
|
{ label: t('pages.user.nick_name'), model: 'nick_name' },
|
|
{ label: t('pages.user.nick_name'), model: 'nick_name' },
|
|
{ label: t('pages.user.phone'), model: 'phone' },
|
|
{ label: t('pages.user.phone'), model: 'phone' },
|
|
- { label: t('pages.user.role'), model: 'role', format: (i) => getRole(i) },
|
|
|
|
|
|
+ { label: t('pages.user.role'), model: 'role', custom: true },
|
|
{ label: t('pages.user.status'), model: 'status', format: (i) => getDict(i) }
|
|
{ label: t('pages.user.status'), model: 'status', format: (i) => getDict(i) }
|
|
]
|
|
]
|
|
const opera = [
|
|
const opera = [
|
|
{ label: t('common.view'), method: 'view' },
|
|
{ label: t('common.view'), method: 'view' },
|
|
- { label: t('common.exam'), method: 'exam', type: 'warning', display: (i) => i.status === '0' },
|
|
|
|
- { label: t('common.delete'), method: 'delete', confirm: true, type: 'danger', display: (i) => i.status === '-1' }
|
|
|
|
|
|
+ { label: t('common.exam'), method: 'exam', type: 'warning' },
|
|
|
|
+ {
|
|
|
|
+ label: t('common.delete'),
|
|
|
|
+ method: 'delete',
|
|
|
|
+ confirm: true,
|
|
|
|
+ type: 'danger',
|
|
|
|
+ display: (i) => i.status === '-1'
|
|
|
|
+ }
|
|
]
|
|
]
|
|
const searchForm = ref({})
|
|
const searchForm = ref({})
|
|
const dialog = ref({ type: '1', show: false, title: t('pages.user.dialogTitle') })
|
|
const dialog = ref({ type: '1', show: false, title: t('pages.user.dialogTitle') })
|
|
-// 审核
|
|
|
|
-const examFormFields = [{ label: t('pages.user.status'), model: 'status', type: 'select' }]
|
|
|
|
-const examRules = reactive({ status: [{ required: true, message: t('common.statusMessage'), trigger: 'blur' }] })
|
|
|
|
-const examForm = ref({})
|
|
|
|
|
|
+// 查询
|
|
const search = async (query = { skip: 0, limit }) => {
|
|
const search = async (query = { skip: 0, limit }) => {
|
|
const info = { skip: query.skip, limit: query.limit, ...searchForm.value }
|
|
const info = { skip: query.skip, limit: query.limit, ...searchForm.value }
|
|
const res = await store.query(info)
|
|
const res = await store.query(info)
|
|
@@ -73,9 +153,28 @@ const search = async (query = { skip: 0, limit }) => {
|
|
total.value = res.total
|
|
total.value = res.total
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+// 表单验证
|
|
|
|
+const ruleFormRef = ref()
|
|
|
|
+const form = ref({})
|
|
|
|
+// 审核
|
|
|
|
+const examFormFields = [{ label: t('pages.user.status'), model: 'status', type: 'select' }]
|
|
|
|
+const examRules = reactive({
|
|
|
|
+ status: [{ required: true, message: t('common.statusMessage'), trigger: 'blur' }]
|
|
|
|
+})
|
|
|
|
+const examForm = ref({})
|
|
|
|
+// 字典表
|
|
const statusList = ref([])
|
|
const statusList = ref([])
|
|
const roleList = ref([])
|
|
const roleList = ref([])
|
|
const genderList = ref([])
|
|
const genderList = ref([])
|
|
|
|
+const fieldList = ref([])
|
|
|
|
+const educationList = ref([])
|
|
|
|
+const cityList = ref([])
|
|
|
|
+const isUseList = ref([])
|
|
|
|
+const patternList = ref([])
|
|
|
|
+const scaleList = ref([])
|
|
|
|
+const IndustryList = ref([])
|
|
|
|
+const cardTypeList = ref([])
|
|
|
|
+const contributionList = ref([])
|
|
const searchOther = async () => {
|
|
const searchOther = async () => {
|
|
let result
|
|
let result
|
|
// 状态
|
|
// 状态
|
|
@@ -87,6 +186,35 @@ const searchOther = async () => {
|
|
// 角色
|
|
// 角色
|
|
result = await roleStore.query({ is_use: '0' })
|
|
result = await roleStore.query({ is_use: '0' })
|
|
if ($checkRes(result)) roleList.value = result.data
|
|
if ($checkRes(result)) roleList.value = result.data
|
|
|
|
+ // 专家领域
|
|
|
|
+ result = await dictDataStore.query({ code: 'field', is_use: '0' })
|
|
|
|
+ if ($checkRes(result)) fieldList.value = result.data
|
|
|
|
+ // 企业类型
|
|
|
|
+ result = await dictDataStore.query({ code: 'companyType', is_use: '0' })
|
|
|
|
+ if ($checkRes(result)) patternList.value = result.data
|
|
|
|
+ // 企业规模
|
|
|
|
+ result = await dictDataStore.query({ code: 'companyScale', is_use: '0' })
|
|
|
|
+ if ($checkRes(result)) scaleList.value = result.data
|
|
|
|
+ // 企业所属行业
|
|
|
|
+ result = await dictDataStore.query({ code: 'companyIndustry', is_use: '0' })
|
|
|
|
+ if ($checkRes(result)) IndustryList.value = result.data
|
|
|
|
+ // 学历
|
|
|
|
+ result = await dictDataStore.query({ code: 'education', is_use: '0' })
|
|
|
|
+ if ($checkRes(result)) educationList.value = result.data
|
|
|
|
+ // 证件类型
|
|
|
|
+ result = await dictDataStore.query({ code: 'cardType', is_use: '0' })
|
|
|
|
+ if ($checkRes(result)) cardTypeList.value = result.data
|
|
|
|
+ // 出资方式
|
|
|
|
+ result = await dictDataStore.query({ code: 'contribution', is_use: '0' })
|
|
|
|
+ if ($checkRes(result)) contributionList.value = result.data
|
|
|
|
+ // 是否使用
|
|
|
|
+ result = await dictDataStore.query({ code: 'isUse', is_use: '0' })
|
|
|
|
+ if ($checkRes(result)) isUseList.value = result.data
|
|
|
|
+ // 城市
|
|
|
|
+ getCity().then((response) => (cityList.value = response.address))
|
|
|
|
+ // 角色
|
|
|
|
+ result = await roleStore.query({ is_use: '0' })
|
|
|
|
+ if ($checkRes(result)) roleList.value = result.data
|
|
}
|
|
}
|
|
|
|
|
|
const toDelete = async (data) => {
|
|
const toDelete = async (data) => {
|
|
@@ -95,20 +223,48 @@ const toDelete = async (data) => {
|
|
search({ skip: 0, limit })
|
|
search({ skip: 0, limit })
|
|
}
|
|
}
|
|
}
|
|
}
|
|
-const form = ref({})
|
|
|
|
-const formFields = ref([])
|
|
|
|
-const formFieldsForUpdate = [
|
|
|
|
- { label: t('pages.user.account'), model: 'account' },
|
|
|
|
- { label: t('pages.user.nick_name'), model: 'nick_name' },
|
|
|
|
- { label: t('pages.user.gender'), model: 'gender', type: 'select' },
|
|
|
|
- { label: t('pages.user.phone'), model: 'phone' },
|
|
|
|
- { label: t('pages.user.role'), model: 'role', custom: true }
|
|
|
|
-]
|
|
|
|
-const toView = (data) => {
|
|
|
|
- formFields.value = cloneDeep(formFieldsForUpdate)
|
|
|
|
|
|
+const getRole = (data) => {
|
|
|
|
+ const res = roleList.value.find((f) => f.code === data)
|
|
|
|
+ return get(res, 'name')
|
|
|
|
+}
|
|
|
|
+const getDict = (data) => {
|
|
|
|
+ const res = statusList.value.find((f) => f.value == data)
|
|
|
|
+ return get(res, 'label')
|
|
|
|
+}
|
|
|
|
+// 查看
|
|
|
|
+const toView = async (data) => {
|
|
form.value = data
|
|
form.value = data
|
|
|
|
+ role.value = get(data, 'role')
|
|
dialog.value = { type: '1', show: true, title: t('pages.user.dialogTitle') }
|
|
dialog.value = { type: '1', show: true, title: t('pages.user.dialogTitle') }
|
|
}
|
|
}
|
|
|
|
+// 标签改变
|
|
|
|
+const toChang = async (name) => {
|
|
|
|
+ let result
|
|
|
|
+ if (name == 'User') {
|
|
|
|
+ result = await store.fetch(form.value.user)
|
|
|
|
+ if ($checkRes(result)) form.value = result.data
|
|
|
|
+ } else {
|
|
|
|
+ if (name == 'Expert') {
|
|
|
|
+ result = await expertStore.query({ user: form.value._id })
|
|
|
|
+ } else if (name == 'Company') {
|
|
|
|
+ result = await companyStore.query({ user: form.value._id })
|
|
|
|
+ } else if (name == 'Unit') {
|
|
|
|
+ result = await unitStore.query({ user: form.value._id })
|
|
|
|
+ } else if (name == 'Association') {
|
|
|
|
+ result = await associationStore.query({ user: form.value._id })
|
|
|
|
+ } else if (name == 'Competition') {
|
|
|
|
+ result = await competitionStore.query({ user: form.value._id })
|
|
|
|
+ } else if (name == 'Incubator') {
|
|
|
|
+ result = await incubatorStore.query({ user: form.value._id })
|
|
|
|
+ } else if (name == 'Investment') {
|
|
|
|
+ result = await investmentStore.query({ user: form.value._id })
|
|
|
|
+ } else if (name == 'State') {
|
|
|
|
+ result = await stateStore.query({ user: form.value._id })
|
|
|
|
+ }
|
|
|
|
+ if ($checkRes(result)) form.value = result.data[0] || {}
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
// 审核
|
|
// 审核
|
|
const toExam = (data) => {
|
|
const toExam = (data) => {
|
|
examForm.value = data
|
|
examForm.value = data
|
|
@@ -123,21 +279,10 @@ const toExamSave = async () => {
|
|
toClose()
|
|
toClose()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
-const getRole = (data) => {
|
|
|
|
- const list = []
|
|
|
|
- for (const val of data) {
|
|
|
|
- const res = roleList.value.find((f) => f.code === val)
|
|
|
|
- list.push(get(res, 'name'))
|
|
|
|
- }
|
|
|
|
- return list.join(',')
|
|
|
|
-}
|
|
|
|
-const getDict = (data) => {
|
|
|
|
- const res = statusList.value.find((f) => f.value == data)
|
|
|
|
- return get(res, 'label')
|
|
|
|
-}
|
|
|
|
const toClose = () => {
|
|
const toClose = () => {
|
|
- examForm.value = {}
|
|
|
|
form.value = {}
|
|
form.value = {}
|
|
|
|
+ type.value = 'User'
|
|
|
|
+ role.value = []
|
|
dialog.value = { show: false }
|
|
dialog.value = { show: false }
|
|
}
|
|
}
|
|
// 重置
|
|
// 重置
|
|
@@ -145,5 +290,30 @@ const toReset = async () => {
|
|
searchForm.value = {}
|
|
searchForm.value = {}
|
|
await search({ skip, limit })
|
|
await search({ skip, limit })
|
|
}
|
|
}
|
|
|
|
+// provide
|
|
|
|
+provide('cloneDeep', cloneDeep)
|
|
|
|
+provide('ruleFormRef ', ruleFormRef)
|
|
|
|
+provide('form', form)
|
|
|
|
+// 字典
|
|
|
|
+provide('statusList', statusList)
|
|
|
|
+provide('genderList', genderList)
|
|
|
|
+provide('fieldList', fieldList)
|
|
|
|
+provide('educationList', educationList)
|
|
|
|
+provide('cityList', cityList)
|
|
|
|
+provide('isUseList', isUseList)
|
|
|
|
+provide('patternList', patternList)
|
|
|
|
+provide('scaleList', scaleList)
|
|
|
|
+provide('IndustryList', IndustryList)
|
|
|
|
+provide('cardTypeList', cardTypeList)
|
|
|
|
+provide('contributionList', contributionList)
|
|
|
|
+// 方法
|
|
|
|
+provide('getRole', getRole)
|
|
</script>
|
|
</script>
|
|
-<style scoped></style>
|
|
|
|
|
|
+<style scoped lang="scss">
|
|
|
|
+.tags {
|
|
|
|
+ display: flex;
|
|
|
|
+ justify-content: center;
|
|
|
|
+ grid-gap: 0.5rem;
|
|
|
|
+ gap: 0.5rem;
|
|
|
|
+}
|
|
|
|
+</style>
|