Ver Fonte

修改信息发布

zs há 7 meses atrás
pai
commit
ff86f6b694

+ 52 - 2
src/components/custom/custom-layout.vue

@@ -57,7 +57,6 @@
     </div>
     <div class="footer" v-if="is_foot">
       <div class="foot">
-        <div class="foot_1">友情连接</div>
         <div class="foot_2">
           <div class="footer_left">
             <div class="left">
@@ -73,6 +72,17 @@
               <div class="title" @click="toHelp">关于我们</div>
             </div>
           </div>
+          <div class="foot_1">
+            <span>友情连接:</span>
+            <el-col :span="7" class="list" v-for="(item, index) in typeList" :key="index">
+              <div class="list_1">
+                <div class="title">{{ item.title }}</div>
+              </div>
+              <div class="list_2">
+                <span v-for="(tag, indexx) in item.list" :key="indexx" @click="toLink(tag)"> {{ tag.name }}</span>
+              </div>
+            </el-col>
+          </div>
           <div class="footer_right">
             {{ footInfo.Copyright }}
           </div>
@@ -115,6 +125,12 @@ const isIncubator = ref(false)
 const hasbrain = ref(false)
 const notReadNum = ref(0)
 const mqClient = ref()
+// 分类
+const typeList = ref([
+  { title: '热门高校', list: [] },
+  { title: '政府部门', list: [] },
+  { title: '科研机构', list: [] }
+])
 // 请求
 onMounted(async () => {
   search()
@@ -167,6 +183,14 @@ const search = async () => {
   if ($checkRes(result)) {
     configInfo.value = result.data[0] || {}
     footInfo.value = result.data[0].footInfo || {}
+    const friendship = result.data[0].friendship || []
+    for (const val of friendship) {
+      for (const tag of typeList.value) {
+        if (val.type == tag.title) {
+          tag.list.push(val)
+        }
+      }
+    }
   }
 }
 // 登录|注册
@@ -222,6 +246,9 @@ const handleMousOut = (index) => {
 const getUrl = (item) => {
   if (item && item.length > 0) return `${import.meta.env.VITE_APP_HOST}${item[0].uri}`
 }
+const toLink = (item) => {
+  window.open(item.href, '_blank') // 在新标签页中打开URL
+}
 // 退出登录
 const toOut = () => {
   userStore.logOut()
@@ -351,6 +378,28 @@ const toOut = () => {
       .foot_1 {
         color: $global-color-fff;
         font-size: $global-font-size-16;
+        display: flex;
+        margin: 10px 0;
+        padding: 0 0 10px 0;
+
+        span {
+          width: 80px;
+        }
+        .list {
+          text-align: center;
+          .list_1 {
+            margin: 0 0 10px 0;
+          }
+          .list_2 {
+            span {
+              margin: 0 5px 5px 0;
+              cursor: default;
+            }
+            span:hover {
+              font-size: $global-font-size-18;
+            }
+          }
+        }
       }
       .foot_2 {
         color: $global-color-fff;
@@ -360,7 +409,7 @@ const toOut = () => {
           display: flex;
           justify-content: space-between;
           align-items: center;
-          border-bottom: 1px solid rgba(229, 241, 255, 0.7);
+          // border-bottom: 1px solid rgba(229, 241, 255, 0.7);
           .left {
             .image {
               width: 334px;
@@ -385,6 +434,7 @@ const toOut = () => {
         }
         .footer_right {
           padding: 10px 0 0 0;
+          border-top: 1px solid rgba(229, 241, 255, 0.7);
         }
       }
     }

+ 41 - 2
src/views/detail/baseDetail.vue

@@ -42,6 +42,14 @@
               </el-col>
             </div>
           </div>
+          <div class="center">
+            <div class="title">联系方式</div>
+            <div class="content">
+              <div class="infoButton">
+                <div class="button" @click="toChat">获取联系方式</div>
+              </div>
+            </div>
+          </div>
           <div class="center">
             <div class="title">简介</div>
             <div class="content">
@@ -55,7 +63,7 @@
                 <el-table-column prop="company_name" label="企业名称" />
                 <el-table-column prop="time" label="申请时间" />
                 <el-table-column prop="time" label="查看详情">
-                  <template #default="scope">
+                  <template #default="scope" v-if="user && user.id">
                     <el-button type="primary" @click="toCompany(scope.row)">查看详情</el-button>
                   </template>
                 </el-table-column>
@@ -103,10 +111,12 @@ import { get } from 'lodash-es'
 // 接口
 import { IncubatorStore } from '@/store/api/user/incubator'
 import { CirelationStore } from '@/store/api/user/cirelation'
+import { ContactApplyStore } from '@/store/api/user/contactApply'
 import { DictDataStore } from '@/store/api/system/dictData'
 const store = IncubatorStore()
 const cirelationStore = CirelationStore()
 const dictDataStore = DictDataStore()
+const contactApplyStore = ContactApplyStore()
 import { UserStore } from '@/store/user'
 const userStore = UserStore()
 const user = computed(() => userStore.user)
@@ -191,6 +201,20 @@ const getArea = (data) => {
   if (data) return data.join('-')
   else return '暂无地区'
 }
+const toChat = () => {
+  if (user.value.id) {
+    ElMessageBox.confirm(`您确认要获取联系方式?`, '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' })
+      .then(async () => {
+        let source_id = route.query.id
+        let source = 'incubator'
+        let apply_user = user.value.id
+        const obj = { source_id, source, apply_user }
+        await contactApplyStore.create(obj)
+        ElMessage({ message: `获取联系方式成功等待消息通知`, type: 'success' })
+      })
+      .catch(() => {})
+  } else ElMessage({ message: '未登录!', type: 'error' })
+}
 const toCollect = async () => {
   if (user.value.id) {
     info.value.is_collection = !info.value.is_collection
@@ -302,13 +326,28 @@ const sizeChange = (limits) => {
           cursor: pointer;
         }
         .content {
-          padding: 20px;
+          padding: 20px 0;
           font-size: $global-font-size-16;
           .thr {
             display: flex;
             justify-content: center;
             margin: 20px 0 0 0;
           }
+          .infoButton {
+            margin: 10px 0 0 0;
+            .button {
+              width: 152px;
+              height: 36px;
+              background: #3278f4;
+              border-radius: 18px;
+              font-size: $global-font-size-14;
+              font-weight: 500;
+              color: #ffffff;
+              text-align: center;
+              line-height: 36px;
+              cursor: pointer;
+            }
+          }
         }
       }
       .bottom {

+ 15 - 2
src/views/four/index.vue

@@ -3,7 +3,7 @@
     <el-col :span="24" class="one">
       <!-- <el-image class="image" :src="news" fit="fill" /> -->
       <div class="input">
-        <a-tabs v-model:activeKey="activeKey" centered>
+        <a-tabs v-model:activeKey="activeKey" centered @tab-click="handleClick">
           <a-tab-pane :key="item.key" :tab="item.tab" v-for="item in menuList"> </a-tab-pane>
         </a-tabs>
         <div class="input_1">
@@ -43,7 +43,7 @@ const menuList = ref([
   { key: '3', tab: '找项目' },
   { key: '4', tab: '找需求' },
   { key: '6', tab: '找成果' },
-  { key: '5', tab: '更多+' }
+  { key: '-1', tab: '更多+' }
 ])
 // 路由
 const router = useRouter()
@@ -85,6 +85,19 @@ const remoteMethod = (query) => {
     tagsList.value = []
   }
 }
+// 选择
+const handleClick = (tab) => {
+  if (tab == -1) {
+    menuList.value = [
+      { key: '-1', tab: '全部' },
+      { key: '3', tab: '找项目' },
+      { key: '4', tab: '找需求' },
+      { key: '5', tab: '找供给' },
+      { key: '6', tab: '找成果' },
+      { key: '1', tab: '找企业' }
+    ]
+  }
+}
 </script>
 <style scoped lang="scss">
 .main {

+ 6 - 6
src/views/four/parts/index.vue

@@ -306,12 +306,12 @@ const searchOther = async () => {
   // 企业状态
   result = await dictDataStore.query({ code: 'companyStatus', is_use: '0' })
   if ($checkRes(result)) statusList.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: '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: 'field', is_use: '0' })
   if ($checkRes(result)) fieldList.value = result.data

+ 9 - 50
src/views/nine/index.vue

@@ -4,56 +4,6 @@
       <el-image class="image" :src="chengguo" fit="fill" />
     </el-col>
     <div class="w_1300">
-      <!-- <div class="active">
-        <div class="active_1" v-show="industry && industry.length > 0">
-          <div class="active_left">行业:</div>
-          <div class="active_right">
-            <div class="active_label" v-for="(item, index) in industry" :key="index">
-              {{ item.title }}<el-icon @click="toDel(item, '1')"><Close /></el-icon>
-            </div>
-          </div>
-        </div>
-        <div class="active_1" v-show="field && field.length > 0">
-          <div class="active_left">技术领域:</div>
-          <div class="active_right">
-            <div class="active_label" v-for="(item, index) in field" :key="index">
-              {{ item.label }}<el-icon @click="toDel(item, '2')"><Close /></el-icon>
-            </div>
-          </div>
-        </div>
-        <div class="active_1" v-show="mature && mature.length > 0">
-          <div class="active_left">成熟度:</div>
-          <div class="active_right">
-            <div class="active_label" v-for="(item, index) in mature" :key="index">
-              {{ item.label }}<el-icon @click="toDel(item, '3')"><Close /></el-icon>
-            </div>
-          </div>
-        </div>
-        <div class="active_1" v-show="sell && sell.length > 0">
-          <div class="active_left">出让方式:</div>
-          <div class="active_right">
-            <div class="active_label" v-for="(item, index) in sell" :key="index">
-              {{ item.label }}<el-icon @click="toDel(item, '4')"><Close /></el-icon>
-            </div>
-          </div>
-        </div>
-        <div class="active_1" v-show="money && money.length > 0">
-          <div class="active_left">价格:</div>
-          <div class="active_right">
-            <div class="active_label" v-for="(item, index) in money" :key="index">
-              {{ item.label }}<el-icon @click="toDel(item, '5')"><Close /></el-icon>
-            </div>
-          </div>
-        </div>
-        <div class="active_1" v-show="city && city.length > 0">
-          <div class="active_left">所在地:</div>
-          <div class="active_right">
-            <div class="active_label" v-for="(item, index) in city" :key="index">
-              {{ item.name }}<el-icon @click="toDel(item, '6')"><Close /></el-icon>
-            </div>
-          </div>
-        </div>
-      </div> -->
       <div class="two">
         <div class="twoSeacher">
           <div class="twoLeft">
@@ -209,6 +159,7 @@ const regionStore = RegionStore()
 const sectorStore = SectorStore()
 // 路由
 const router = useRouter()
+const route = useRoute()
 
 // 加载中
 const loading = ref(false)
@@ -242,6 +193,7 @@ onMounted(async () => {
   loading.value = true
   await searchOther()
   await search()
+  router.replace({ name: 'nine' })
   loading.value = false
 })
 const search = async (query = { skip, limit }) => {
@@ -254,6 +206,13 @@ const search = async (query = { skip, limit }) => {
     is_use: '0',
     ...searchForm.value
   }
+  if (route.query.type) {
+    info.field = route.query.type
+    for (const val of typeList.value) {
+      if (route.query.type == val.value) val.is_active = true
+      if (val.id == '-1') val.is_active = false
+    }
+  }
   const res = await store.list(info)
   if (res.errcode == '0') {
     list.value = res.data

+ 1 - 5
src/views/search/parts/project.vue

@@ -9,7 +9,7 @@
                 <span>行业</span>
               </div>
               <div v-if="!twoShow" class="OneRight">
-                <el-checkbox class="label" @change="oneChange" v-for="(item, index) in plateList.slice(0, 5)" :key="index" v-model="checked1" :label="item.title" size="large" />
+                <el-checkbox class="label" @change="oneChange" v-for="(item, index) in plateList.slice(0, 4)" :key="index" v-model="checked1" :label="item.title" size="large" />
               </div>
               <div v-else class="OneRight">
                 <el-checkbox class="label" @change="oneChange" v-for="(item, index) in plateList" :key="index" v-model="checked1" :label="item.title" size="large" />
@@ -144,22 +144,18 @@ const searchOther = async () => {
   // 成熟度
   result = await dictDataStore.query({ code: 'projectMaturity', is_use: '0' })
   if ($checkRes(result)) maturityList.value = result.data
-  maturityList.value.unshift({ value: '-1', label: '不限' })
   // // 行业分类
   // result = await dictDataStore.query({ code: 'industry', is_use: '0' })
   // if ($checkRes(result)) industryList.value = result.data
   // 技术领域
   result = await dictDataStore.query({ code: 'field', is_use: '0' })
   if ($checkRes(result)) typeList.value = result.data
-  typeList.value.unshift({ value: '-1', label: '不限' })
   // 地区
   result = await regionStore.list({ level: 'city', parent_code: 22 })
   if ($checkRes(result)) cityList.value = result.data
-  cityList.value.unshift({ code: '-1', name: '不限' })
   // 行业
   result = await sectorStore.query({ is_use: '0' })
   if ($checkRes(result)) plateList.value = result.data
-  plateList.value.unshift({ id: '-1', title: '不限' })
 }
 const search = async (query = { skip, limit }) => {
   skip = query.skip

+ 161 - 0
src/views/two/add/achievement.vue

@@ -0,0 +1,161 @@
+<template>
+  <div class="index">
+    <el-row>
+      <el-col :span="24" class="main animate__animated animate__backInRight" v-loading="loading">
+        <custom-form v-model="form" :fields="formFields" :rules="rules" @save="toSave" @draftSave="toDraftSave">
+          <template #is_use>
+            <el-radio v-for="i in isUseList" :key="i.id" :label="i.value">{{ i.label }}</el-radio>
+          </template>
+          <template #field>
+            <el-option v-for="i in fieldList" :key="i.id" :label="i.label" :value="i.label"></el-option>
+          </template>
+          <template #attribute>
+            <el-option v-for="i in attributeList" :key="i.id" :label="i.label" :value="i.value"></el-option>
+          </template>
+          <template #mature>
+            <el-option v-for="i in matureList" :key="i.id" :label="i.label" :value="i.value"></el-option>
+          </template>
+          <template #sell>
+            <el-option v-for="i in sellList" :key="i.id" :label="i.label" :value="i.value"></el-option>
+          </template>
+          <template #technology>
+            <el-option v-for="i in technologyList" :key="i.id" :label="i.label" :value="i.value"></el-option>
+          </template>
+          <template #area>
+            <el-cascader v-model="form.area" :props="{ value: 'name', label: 'name' }" :options="cityList" style="width: 100%" />
+          </template>
+          <template #file>
+            <custom-upload model="file" :list="form.file" :limit="1" url="/files/web/cxyy_achievement/upload" @change="onUpload"></custom-upload>
+          </template>
+          <template #industry>
+            <el-option v-for="i in sectorList" :key="i.id" :label="i.title" :value="i.title"></el-option>
+          </template>
+          <template #tags>
+            <el-select v-model="form.tags" multiple filterable allow-create default-first-option :reserve-keyword="false" placeholder="请选择标签" style="width: 100%">
+              <el-option v-for="item in tagsList" :key="item.id" :label="item.title" :value="item.title" />
+            </el-select>
+          </template>
+        </custom-form>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script setup>
+import { cloneDeep, get } from 'lodash-es'
+const $checkRes = inject('$checkRes')
+import { UserStore } from '@/store/user'
+const userStore = UserStore()
+const user = computed(() => userStore.user)
+// 接口
+import { AchievementStore } from '@/store/api/platform/achievement'
+import { DictDataStore } from '@/store/api/system/dictData'
+import { TagsStore } from '@/store/api/system/tags'
+import { SectorStore } from '@/store/api/platform/sector'
+import { RegionStore } from '@/store/api/system/region'
+const regionStore = RegionStore()
+const store = AchievementStore()
+const dictDataStore = DictDataStore()
+const tagsStore = TagsStore()
+const sectorStore = SectorStore()
+// 加载中
+const loading = ref(false)
+// 字典表
+const isUseList = ref([])
+const statusList = ref([])
+const fieldList = ref([])
+const attributeList = ref([])
+const matureList = ref([])
+const sellList = ref([])
+const technologyList = ref([])
+const cityList = ref([])
+const achievementList = ref([])
+const tagsList = ref([])
+const sectorList = ref([])
+const formFields = ref([
+  { label: '成果名称', model: 'name' },
+  { label: '标签', model: 'tags', custom: true, mark: 'tags' },
+  { label: '所属产业', model: 'industry', type: 'select' },
+  { label: '专利号', model: 'patent' },
+  { label: '行业领域', model: 'field' },
+  { label: '属性', model: 'attribute', type: 'select', mark: 'dict', code: 'attribute' },
+  { label: '成熟度', model: 'mature', type: 'select', mark: 'dict', code: 'mature' },
+  { label: '出让方式', model: 'sell', type: 'select', mark: 'dict', code: 'sell' },
+  { label: '技术分类', model: 'technology', type: 'select', mark: 'dict', code: 'technology' },
+  { label: '成果地区', model: 'area', custom: true, mark: 'area' },
+  { label: '发布时间', model: 'time', type: 'date' },
+  { label: '价格(万元)', model: 'money' },
+  { label: '项目来源', model: 'source' },
+  { label: '联系人', model: 'person' },
+  { label: '联系电话', model: 'tel' },
+  { label: '是否公开', model: 'is_use', type: 'radio', mark: 'dict', code: 'isUse' },
+  { label: '简介', model: 'brief', type: 'textarea' },
+  { label: '附件', model: 'file', custom: true, mark: 'file' }
+])
+const form = ref({ file: [] })
+const rules = reactive({ name: [{ required: true, message: '请输入成果名称', trigger: 'blur' }] })
+// 请求
+onMounted(async () => {
+  loading.value = true
+  await searchOther()
+  loading.value = false
+})
+const searchOther = async () => {
+  let result
+  // 是否使用
+  result = await dictDataStore.query({ code: 'isUse', is_use: '0' })
+  if ($checkRes(result)) isUseList.value = result.data
+  // 状态
+  result = await dictDataStore.query({ code: 'examStatus', is_use: '0' })
+  if ($checkRes(result)) statusList.value = result.data
+  // 成熟度
+  result = await dictDataStore.query({ code: 'mature', is_use: '0' })
+  if ($checkRes(result)) matureList.value = result.data
+  // 出让方式
+  result = await dictDataStore.query({ code: 'sell', is_use: '0' })
+  if ($checkRes(result)) sellList.value = result.data
+  // 技术领域
+  result = await dictDataStore.query({ code: 'field', is_use: '0' })
+  if ($checkRes(result)) fieldList.value = result.data
+  // 属性
+  result = await dictDataStore.query({ code: 'attribute', is_use: '0' })
+  if ($checkRes(result)) attributeList.value = result.data
+  // 技术分类
+  result = await dictDataStore.query({ code: 'technology', is_use: '0' })
+  if ($checkRes(result)) technologyList.value = result.data
+  // 成果状态
+  result = await dictDataStore.query({ code: 'demandStatus', is_use: '0' })
+  if ($checkRes(result)) achievementList.value = result.data
+  // 标签
+  result = await tagsStore.query({ is_use: '0' })
+  if ($checkRes(result)) tagsList.value = result.data
+  // 行业
+  result = await sectorStore.query({ is_use: '0' })
+  if ($checkRes(result)) sectorList.value = result.data
+  // 城市
+  result = await regionStore.area({ level: 'province', code: 22 })
+  if ($checkRes(result)) cityList.value = result.data
+}
+// 上传图片
+const onUpload = (e) => {
+  const { model, value } = e
+  form.value[model] = value
+}
+const toSave = async () => {
+  const data = cloneDeep(form.value)
+  const other = { status: '0', user: user.value.id }
+  let res
+  if (get(data, 'id')) res = await store.update({ ...data, ...other })
+  else res = await store.create({ ...data, ...other })
+  if ($checkRes(res, true)) ElMessage({ message: `发布成功可以长历史发布查看`, type: 'success' })
+}
+const toDraftSave = async () => {
+  const data = cloneDeep(form.value)
+  const other = { status: '-2', user: user.value.id }
+  let res
+  if (get(data, 'id')) res = await store.update({ ...data, ...other })
+  else res = await store.create({ ...data, ...other })
+  if ($checkRes(res, true)) ElMessage({ message: `发布成功可以长历史发布查看`, type: 'success' })
+}
+</script>
+<style scoped lang="scss"></style>

+ 151 - 0
src/views/two/add/demand.vue

@@ -0,0 +1,151 @@
+<template>
+  <div class="index">
+    <el-row>
+      <el-col :span="24" class="main animate__animated animate__backInRight" v-loading="loading">
+        <custom-form v-model="form" :fields="formFields" :rules="rules" @save="toSave" @draftSave="toDraftSave">
+          <template #is_use>
+            <el-radio v-for="i in isUseList" :key="i.id" :label="i.value">{{ i.label }}</el-radio>
+          </template>
+          <template #field>
+            <el-option v-for="i in fieldList" :key="i.id" :label="i.label" :value="i.label"></el-option>
+          </template>
+          <template #industry>
+            <el-option v-for="i in sectorList" :key="i.id" :label="i.title" :value="i.title"></el-option>
+          </template>
+          <template #urgent>
+            <el-option v-for="i in urgentList" :key="i.id" :label="i.label" :value="i.value"></el-option>
+          </template>
+          <template #method>
+            <el-option v-for="i in methodList" :key="i.id" :label="i.label" :value="i.value"></el-option>
+          </template>
+          <template #area>
+            <el-cascader v-model="form.area" :props="{ value: 'name', label: 'name' }" :options="cityList" style="width: 100%" />
+          </template>
+          <template #tags>
+            <el-select v-model="form.tags" multiple filterable allow-create default-first-option :reserve-keyword="false" placeholder="请选择标签" style="width: 100%">
+              <el-option v-for="item in tagsList" :key="item.id" :label="item.title" :value="item.title" />
+            </el-select>
+          </template>
+        </custom-form>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script setup>
+import { cloneDeep, get } from 'lodash-es'
+const $checkRes = inject('$checkRes')
+import { UserStore } from '@/store/user'
+const userStore = UserStore()
+const user = computed(() => userStore.user)
+// 接口
+import { DemandStore } from '@/store/api/platform/demand'
+import { DictDataStore } from '@/store/api/system/dictData'
+import { TagsStore } from '@/store/api/system/tags'
+import { SectorStore } from '@/store/api/platform/sector'
+import { RegionStore } from '@/store/api/system/region'
+const regionStore = RegionStore()
+const store = DemandStore()
+const dictDataStore = DictDataStore()
+const tagsStore = TagsStore()
+const sectorStore = SectorStore()
+// 加载中
+const loading = ref(false)
+// 字典表
+const isUseList = ref([])
+const statusList = ref([])
+const methodList = ref([])
+const urgentList = ref([])
+const fieldList = ref([])
+const cityList = ref([])
+const demandList = ref([])
+const tagsList = ref([])
+const sectorList = ref([])
+
+const form = ref({ time: [] })
+const formFields = ref([
+  { label: '需求名称', model: 'name' },
+  { label: '标签', model: 'tags', custom: true, mark: 'tags' },
+  { label: '所属产业', model: 'industry', type: 'select' },
+  { label: '行业领域', model: 'field' },
+  { label: '需求紧急度', model: 'urgent', type: 'select', mark: 'dict', code: 'urgent' },
+  { label: '合作方式', model: 'method', type: 'select', mark: 'dict', code: 'method' },
+  { label: '价格(万元)', model: 'money' },
+  { label: '所属企业', model: 'company' },
+  { label: '企业简况', model: 'company_brief', type: 'textarea' },
+  { label: '联系人', model: 'contacts' },
+  { label: '联系电话', model: 'tel' },
+  { label: '年份', model: 'year', type: 'year' },
+  { label: '月份', model: 'month', type: 'month' },
+  { label: '技术需求名称', model: 'tec_name' },
+  { label: '待解决问题', model: 'question', type: 'textarea' },
+  { label: '需求地区', model: 'area', custom: true, mark: 'area' },
+  { label: '发布时间', model: 'time', type: 'daterange', mark: 'time' },
+  { label: '是否公开', model: 'is_use', type: 'radio', mark: 'dict', code: 'isUse' },
+  { label: '简介', model: 'brief', type: 'textarea' }
+])
+const rules = reactive({ name: [{ required: true, message: '请输入需求名称', trigger: 'blur' }] })
+// 请求
+onMounted(async () => {
+  loading.value = true
+  await searchOther()
+  loading.value = false
+})
+const searchOther = async () => {
+  let result
+  // 是否使用
+  result = await dictDataStore.query({ code: 'isUse', is_use: '0' })
+  if ($checkRes(result)) isUseList.value = result.data
+  // 状态
+  result = await dictDataStore.query({ code: 'examStatus', is_use: '0' })
+  if ($checkRes(result)) statusList.value = result.data
+  // 合作方式
+  result = await dictDataStore.query({ code: 'method', is_use: '0' })
+  if ($checkRes(result)) methodList.value = result.data
+  // 需求紧急度
+  result = await dictDataStore.query({ code: 'urgent', is_use: '0' })
+  if ($checkRes(result)) urgentList.value = result.data
+  // 技术领域
+  result = await dictDataStore.query({ code: 'field', is_use: '0' })
+  if ($checkRes(result)) fieldList.value = result.data
+  // 需求状态
+  result = await dictDataStore.query({ code: 'demandStatus', is_use: '0' })
+  if ($checkRes(result)) demandList.value = result.data
+  // 标签
+  result = await tagsStore.query({ is_use: '0' })
+  if ($checkRes(result)) tagsList.value = result.data
+  // 行业
+  result = await sectorStore.query({ is_use: '0' })
+  if ($checkRes(result)) sectorList.value = result.data
+  // 城市
+  result = await regionStore.area({ level: 'province', code: 22 })
+  if ($checkRes(result)) cityList.value = result.data
+}
+const toSave = async () => {
+  const data = cloneDeep(form.value)
+  const other = { status: '0', user: user.value.id }
+  if (data.time && data.time.length > 1) {
+    data.start_time = data.time[0]
+    data.end_time = data.time[1]
+  }
+  delete data.time
+  let res
+  if (get(data, 'id')) res = await store.update({ ...data, ...other })
+  else res = await store.create({ ...data, ...other })
+  if ($checkRes(res, true)) ElMessage({ message: `发布成功可以长历史发布查看`, type: 'success' })
+}
+const toDraftSave = async () => {
+  const data = cloneDeep(form.value)
+  const other = { status: '-2', user: user.value.id }
+  if (data.time && data.time.length > 1) {
+    data.start_time = data.time[0]
+    data.end_time = data.time[1]
+  }
+  delete data.time
+  let res
+  if (get(data, 'id')) res = await store.update({ ...data, ...other })
+  else res = await store.create({ ...data, ...other })
+  if ($checkRes(res, true)) ElMessage({ message: `发布成功可以长历史发布查看`, type: 'success' })
+}
+</script>
+<style scoped lang="scss"></style>

+ 145 - 0
src/views/two/add/footplate.vue

@@ -0,0 +1,145 @@
+<template>
+  <div class="index">
+    <el-row>
+      <el-col :span="24" class="main animate__animated animate__backInRight" v-loading="loading">
+        <custom-form v-model="form" :fields="formFields" :rules="rules" @save="toSave" @draftSave="toDraftSave">
+          <template #file>
+            <custom-upload model="file" :list="form.file" :limit="3" listType="picture-card" url="/files/web/cxyy_footplate/upload" @change="onUpload"></custom-upload>
+          </template>
+          <template #is_use>
+            <el-radio v-for="i in isUseList" :key="i.id" :label="i.value">{{ i.label }}</el-radio>
+          </template>
+          <template #industry>
+            <el-option v-for="i in sectorList" :key="i.id" :label="i.title" :value="i.title"></el-option>
+          </template>
+          <template #area>
+            <el-cascader v-model="form.area" :props="{ value: 'name', label: 'name' }" :options="cityList" style="width: 100%" />
+          </template>
+          <template #tags>
+            <el-select v-model="form.tags" multiple filterable allow-create default-first-option :reserve-keyword="false" placeholder="请选择标签" style="width: 100%">
+              <el-option v-for="item in tagsList" :key="item.id" :label="item.title" :value="item.title" />
+            </el-select>
+          </template>
+        </custom-form>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script setup>
+import { cloneDeep, get } from 'lodash-es'
+const $checkRes = inject('$checkRes')
+import { UserStore } from '@/store/user'
+const userStore = UserStore()
+const user = computed(() => userStore.user)
+// 接口
+import { FootplateStore } from '@/store/api/platform/footplate'
+import { DictDataStore } from '@/store/api/system/dictData'
+import { TagsStore } from '@/store/api/system/tags'
+import { SectorStore } from '@/store/api/platform/sector'
+import { RegionStore } from '@/store/api/system/region'
+const regionStore = RegionStore()
+const store = FootplateStore()
+const dictDataStore = DictDataStore()
+const tagsStore = TagsStore()
+const sectorStore = SectorStore()
+// 加载中
+const loading = ref(false)
+
+// 字典表
+const isUseList = ref([])
+const statusList = ref([])
+const cityList = ref([])
+const tagsList = ref([])
+const sectorList = ref([])
+
+const form = ref({ file: [] })
+const formFields = ref([
+  { label: '封面', model: 'file', custom: true },
+  { label: '名称', model: 'name' },
+  { label: '标签', model: 'tags', custom: true },
+  { label: '所属产业', model: 'industry', type: 'select' },
+  { label: '建设主体', model: 'build' },
+  { label: '运营主体', model: 'operate' },
+  { label: '服务产业领域', model: 'field' },
+  { label: '所在地区', model: 'area', custom: true },
+  { label: '地址', model: 'address', type: 'textarea' },
+  { label: '联系人', model: 'contacts' },
+  { label: '联系电话', model: 'phone' },
+  { label: '是否启用', model: 'is_use', type: 'radio' },
+  { label: '简介', model: 'brief', type: 'textarea' }
+])
+const rules = reactive({ name: [{ required: true, message: '请输入平台名称', trigger: 'blur' }] })
+// 请求
+onMounted(async () => {
+  loading.value = true
+  await searchOther()
+  loading.value = false
+})
+const searchOther = async () => {
+  let result
+  // 是否使用
+  result = await dictDataStore.query({ code: 'isUse', is_use: '0' })
+  if ($checkRes(result)) isUseList.value = result.data
+  // 状态
+  result = await dictDataStore.query({ code: 'examStatus', is_use: '0' })
+  if ($checkRes(result)) statusList.value = result.data
+  // 标签
+  result = await tagsStore.query({ is_use: '0' })
+  if ($checkRes(result)) tagsList.value = result.data
+  // 行业
+  result = await sectorStore.query({ is_use: '0' })
+  if ($checkRes(result)) sectorList.value = result.data
+  // 城市
+  result = await regionStore.area({ level: 'province', code: 22 })
+  if ($checkRes(result)) cityList.value = result.data
+}
+
+const toSave = async () => {
+  const data = cloneDeep(form.value)
+  const other = { status: '0', user: user.value.id }
+  let res
+  if (get(data, 'id')) res = await store.update({ ...data, ...other })
+  else res = await store.create({ ...data, ...other })
+  if ($checkRes(res, true)) ElMessage({ message: `发布成功可以长历史发布查看`, type: 'success' })
+}
+const toDraftSave = async () => {
+  const data = cloneDeep(form.value)
+  const other = { status: '-2', user: user.value.id }
+  let res
+  if (get(data, 'id')) res = await store.update({ ...data, ...other })
+  else res = await store.create({ ...data, ...other })
+  if ($checkRes(res, true)) ElMessage({ message: `发布成功可以长历史发布查看`, type: 'success' })
+}
+// 上传图片
+const onUpload = (e) => {
+  const { model, value } = e
+  form.value[model] = value
+}
+</script>
+<style scoped lang="scss">
+.main {
+  .one {
+    height: 50px;
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    margin: 0 0 10px 0;
+    .one_left {
+      background: #1875df;
+      padding: 0 10px;
+      height: 30px;
+      color: #fff;
+      line-height: 30px;
+      text-align: center;
+      font-size: 16px;
+      cursor: default;
+    }
+  }
+  .thr {
+    display: flex;
+    justify-content: center;
+    margin: 20px 0 0 0;
+  }
+}
+</style>

+ 278 - 0
src/views/two/add/match.vue

@@ -0,0 +1,278 @@
+<template>
+  <div class="index">
+    <el-row>
+      <el-col :span="24" class="main animate__animated animate__backInRight" v-loading="loading">
+        <custom-form v-model="form" :fields="formFields" :rules="rules" @save="toSave" @draftSave="toDraftSave">
+          <template #video>
+            <custom-upload model="video" :list="form.video" :limit="1" url="/files/web/cxyy_match/upload" @change="onUpload"></custom-upload>
+          </template>
+          <template #file>
+            <custom-upload model="file" :list="form.file" :limit="1" listType="picture-card" url="/files/web/cxyy_match/upload" @change="onUpload"></custom-upload>
+          </template>
+          <template #is_use>
+            <el-radio v-for="i in isUseList" :key="i.id" :label="i.value">{{ i.label }}</el-radio>
+          </template>
+          <template #industry>
+            <el-option v-for="i in sectorList" :key="i.id" :label="i.title" :value="i.title"></el-option>
+          </template>
+          <template #scale>
+            <el-radio v-for="i in scaleList" :key="i.id" :label="i.value">{{ i.label }}</el-radio>
+          </template>
+          <template #match_type>
+            <el-radio v-for="i in matchTypeList" :key="i.id" :label="i.value">{{ i.label }}</el-radio>
+          </template>
+          <template #type>
+            <el-option v-for="i in typeList" :key="i.id" :label="i.label" :value="i.value"></el-option>
+          </template>
+          <template #form>
+            <el-option v-for="i in formList" :key="i.id" :label="i.label" :value="i.value"></el-option>
+          </template>
+          <template #tags>
+            <el-select v-model="form.tags" multiple filterable allow-create default-first-option :reserve-keyword="false" placeholder="请选择标签" style="width: 100%">
+              <el-option v-for="item in tagsList" :key="item.id" :label="item.title" :value="item.title" />
+            </el-select>
+          </template>
+          <template #rules>
+            <div class="rules">
+              <custom-form v-model="form.rules" :fields="rulesFields" :useSave="false">
+                <template #rules1>
+                  <WangEditor v-model="form.rules.rules1" />
+                </template>
+                <template #rules2>
+                  <WangEditor v-model="form.rules.rules2" />
+                </template>
+                <template #rules3>
+                  <WangEditor v-model="form.rules.rules3" />
+                </template>
+                <template #rules4>
+                  <WangEditor v-model="form.rules.rules4" />
+                </template>
+                <template #rules5>
+                  <WangEditor v-model="form.rules.rules5" />
+                </template>
+                <template #rules6>
+                  <WangEditor v-model="form.rules.rules6" />
+                </template>
+                <template #rules7>
+                  <WangEditor v-model="form.rules.rules7" />
+                </template>
+                <template #rules8>
+                  <WangEditor v-model="form.rules.rules8" />
+                </template>
+                <template #rules9>
+                  <WangEditor v-model="form.rules.rules9" />
+                </template>
+                <template #rules10>
+                  <WangEditor v-model="form.rules.rules10" />
+                </template>
+                <template #rules11>
+                  <WangEditor v-model="form.rules.rules11" />
+                </template>
+                <template #rules12>
+                  <WangEditor v-model="form.rules.rules12" />
+                </template>
+              </custom-form>
+            </div>
+          </template>
+          <template #brief>
+            <WangEditor v-model="form.brief" />
+          </template>
+          <template #process>
+            <el-col :span="24" class="tables">
+              <el-col :span="24" class="tables_1">
+                <el-button type="primary" @click="addProcess()">添加</el-button>
+              </el-col>
+              <el-col :span="24">
+                <el-table :data="processList" border>
+                  <el-table-column type="index" label="序号" width="80" align="center"> </el-table-column>
+                  <el-table-column prop="name" label="流程名称" align="center">
+                    <template #default="scope">
+                      <el-input v-model="scope.row.name" placeholder="请输入流程名称" />
+                    </template>
+                  </el-table-column>
+                  <el-table-column prop="order_num" label="排序" align="center">
+                    <template #default="scope">
+                      <el-input v-model="scope.row.order_num" type="number" placeholder="请输入排序" />
+                    </template>
+                  </el-table-column>
+                  <el-table-column prop="is_use" label="是否启用" align="center">
+                    <template #default="scope">
+                      <el-select v-model="scope.row.is_use" placeholder="请选择是否启用">
+                        <el-option v-for="item in isUseList" :key="item.value" :label="item.label" :value="item.value" />
+                      </el-select>
+                    </template>
+                  </el-table-column>
+                  <el-table-column label="操作" align="center" width="100">
+                    <template #default="scope">
+                      <el-button type="danger" @click="delProcess(scope.row)">删除</el-button>
+                    </template>
+                  </el-table-column>
+                </el-table>
+              </el-col>
+            </el-col>
+          </template>
+        </custom-form>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script setup>
+// 组件
+import moment from 'moment'
+import { cloneDeep, get } from 'lodash-es'
+const $checkRes = inject('$checkRes')
+import { UserStore } from '@/store/user'
+const userStore = UserStore()
+const user = computed(() => userStore.user)
+// 接口
+import { MatchStore } from '@/store/api/platform/match'
+import { ProcessStore } from '@/store/api/platform/process'
+import { DictDataStore } from '@/store/api/system/dictData'
+import { TagsStore } from '@/store/api/system/tags'
+import { SectorStore } from '@/store/api/platform/sector'
+const store = MatchStore()
+const dictDataStore = DictDataStore()
+const tagsStore = TagsStore()
+const sectorStore = SectorStore()
+const processStore = ProcessStore()
+// 加载中
+const loading = ref(false)
+
+// 字典表
+const isUseList = ref([])
+const statusList = ref([])
+const typeList = ref([])
+const matchList = ref([])
+const formList = ref([])
+const tagsList = ref([])
+const sectorList = ref([])
+const matchTypeList = ref([])
+const scaleList = ref([])
+// 流程列表
+const processList = ref([])
+
+const form = ref({ time: [], rules: {} })
+const formFields = ref([
+  { label: '封面', model: 'file', custom: true },
+  { label: '赛事名称', model: 'name' },
+  { label: '标签', model: 'tags', custom: true },
+  { label: '类型', model: 'type', type: 'select' },
+  { label: '赛事规模', model: 'scale', type: 'radio' },
+  { label: '赛事类型', model: 'match_type', type: 'radio' },
+  { label: '路由', model: 'href', display: () => form.value.match_type == '1' },
+  { label: '组织单位', model: 'work' },
+  { label: '所属产业', model: 'industry', type: 'select' },
+  { label: '类别', model: 'form', type: 'select' },
+  { label: '奖金(万元)', model: 'money' },
+  { label: '有效期', model: 'time', type: 'daterange' },
+  { label: '是否启用', model: 'is_use', type: 'radio' },
+  { model: 'rules', custom: true },
+  { label: '简介', model: 'brief', custom: true },
+  { label: '视频', model: 'video', custom: true },
+  { label: '赛事流程', model: 'process', custom: true }
+])
+// 赛事规则
+const rulesFields = ref([
+  { label: '大赛背景', model: 'rules1', custom: true },
+  { label: '大赛主题和目标', model: 'rules2', custom: true },
+  { label: '大赛基本情况介绍', model: 'rules3', custom: true },
+  { label: '赛题任务', model: 'rules4', custom: true },
+  { label: '赛程安排', model: 'rules5', custom: true },
+  { label: '赛制阶段', model: 'rules6', custom: true },
+  { label: '参赛资格', model: 'rules7', custom: true },
+  { label: '参赛报名', model: 'rules8', custom: true },
+  { label: '奖项设置与奖励办法', model: 'rules9', custom: true },
+  { label: '组织单位', model: 'rules10', custom: true },
+  { label: '赛事联络', model: 'rules11', custom: true },
+  { label: '赛事交流', model: 'rules12', custom: true }
+])
+// 请求
+onMounted(async () => {
+  loading.value = true
+  await searchOther()
+  loading.value = false
+})
+const searchOther = async () => {
+  let result
+  // 是否使用
+  result = await dictDataStore.query({ code: 'isUse', is_use: '0' })
+  if ($checkRes(result)) isUseList.value = result.data
+  // 类型
+  result = await dictDataStore.query({ code: 'matchType', is_use: '0' })
+  if ($checkRes(result)) typeList.value = result.data
+  // 赛事类型
+  result = await dictDataStore.query({ code: 'activeType', is_use: '0' })
+  if ($checkRes(result)) matchTypeList.value = result.data
+  // 类别
+  result = await dictDataStore.query({ code: 'matchForm', is_use: '0' })
+  if ($checkRes(result)) formList.value = result.data
+  // 状态
+  result = await dictDataStore.query({ code: 'examStatus', is_use: '0' })
+  if ($checkRes(result)) statusList.value = result.data
+  // 赛事状态
+  result = await dictDataStore.query({ code: 'matchStatus', is_use: '0' })
+  if ($checkRes(result)) matchList.value = result.data
+  // 赛事规模
+  result = await dictDataStore.query({ code: 'matchScale', is_use: '0' })
+  if ($checkRes(result)) scaleList.value = result.data
+  // 标签
+  result = await tagsStore.query({ is_use: '0' })
+  if ($checkRes(result)) tagsList.value = result.data
+  // 行业
+  result = await sectorStore.query({ is_use: '0' })
+  if ($checkRes(result)) sectorList.value = result.data
+}
+const toSave = async () => {
+  const data = cloneDeep(form.value)
+  const other = { status: '0', user: user.value.id }
+  if (data.time && data.time.length > 1) {
+    data.start_time = data.time[0]
+    data.end_time = data.time[1]
+  }
+  delete data.time
+  let res
+  if (get(data, 'id')) res = await store.update({ ...data, ...other })
+  else res = await store.create({ ...data, ...other })
+  if ($checkRes(res, true)) ElMessage({ message: `发布成功可以长历史发布查看`, type: 'success' })
+}
+const toDraftSave = async () => {
+  const data = cloneDeep(form.value)
+  const other = { status: '-2', user: user.value.id }
+  if (data.time && data.time.length > 1) {
+    data.start_time = data.time[0]
+    data.end_time = data.time[1]
+  }
+  delete data.time
+  let res
+  if (get(data, 'id')) res = await store.update({ ...data, ...other })
+  else res = await store.create({ ...data, ...other })
+  if ($checkRes(res, true)) ElMessage({ message: `发布成功可以长历史发布查看`, type: 'success' })
+}
+// 上传图片
+const onUpload = (e) => {
+  const { model, value } = e
+  form.value[model] = value
+}
+// 流程添加
+const addProcess = () => {
+  let list = processList.value || []
+  list.push({ sid: moment().valueOf(), name: '', time: '', is_use: '' })
+  processList.value = list
+}
+// 流程删除
+const delProcess = async (e) => {
+  let list = processList.value.filter((i) => i.sid != e.sid)
+  processList.value = list
+  if (e.id) await processStore.del(e.id)
+}
+</script>
+<style scoped lang="scss">
+.main {
+  .tables {
+    .tables_1 {
+      margin: 0 0 10px 0;
+    }
+  }
+}
+</style>

+ 101 - 0
src/views/two/add/news2.vue

@@ -0,0 +1,101 @@
+<template>
+  <div class="index">
+    <el-row>
+      <el-col :span="24" class="main animate__animated animate__backInRight" v-loading="loading">
+        <custom-form v-model="form" :fields="formFields" :rules="rules" @save="toSave" @draftSave="toDraftSave">
+          <template #logo>
+            <custom-upload model="logo" :list="form.logo" :limit="1" url="/files/web/cxyy_news/upload" @change="onUpload" listType="picture-card"></custom-upload>
+          </template>
+          <template #is_use>
+            <el-radio v-for="i in isUseList" :key="i.id" :label="i.value">{{ i.label }}</el-radio>
+          </template>
+          <template #tags>
+            <el-select v-model="form.tags" multiple filterable allow-create default-first-option :reserve-keyword="false" placeholder="请选择标签" style="width: 100%">
+              <el-option v-for="item in tagsList" :key="item.id" :label="item.title" :value="item.title" />
+            </el-select>
+          </template>
+          <template #content>
+            <WangEditor v-model="form.content" />
+          </template>
+        </custom-form>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script setup>
+import moment from 'moment'
+import { cloneDeep, get } from 'lodash-es'
+const $checkRes = inject('$checkRes')
+import { UserStore } from '@/store/user'
+const userStore = UserStore()
+const user = computed(() => userStore.user)
+// 接口
+import { NewsStore } from '@/store/api/platform/news'
+import { DictDataStore } from '@/store/api/system/dictData'
+import { TagsStore } from '@/store/api/system/tags'
+const store = NewsStore()
+const dictDataStore = DictDataStore()
+const tagsStore = TagsStore()
+// 加载中
+const loading = ref(false)
+
+// 字典表
+const isUseList = ref([])
+const statusList = ref([])
+const tagsList = ref([])
+
+const form = ref({ logo: [], type: '2' })
+const formFields = ref([
+  { label: '封面', model: 'logo', custom: true },
+  { label: '标题', model: 'title' },
+  { label: '标签', model: 'tags', custom: true },
+  { label: '发布人', model: 'person', options: { disabled: true } },
+  { label: '发布时间', model: 'time', type: 'date', options: { disabled: true } },
+  { label: '浏览量', model: 'number', options: { disabled: true } },
+  { label: '是否公开', model: 'is_use', type: 'radio' },
+  { label: '内容', model: 'content', custom: true }
+])
+const rules = reactive({ name: [{ required: true, message: '请输入标题', trigger: 'blur' }] })
+// 请求
+onMounted(async () => {
+  loading.value = true
+  await searchOther()
+  loading.value = false
+})
+const searchOther = async () => {
+  let result
+  // 是否使用
+  result = await dictDataStore.query({ code: 'isUse', is_use: '0' })
+  if ($checkRes(result)) isUseList.value = result.data
+  // 状态
+  result = await dictDataStore.query({ code: 'examStatus', is_use: '0' })
+  if ($checkRes(result)) statusList.value = result.data
+  // 标签
+  result = await tagsStore.query({ is_use: '0' })
+  if ($checkRes(result)) tagsList.value = result.data
+}
+const toSave = async () => {
+  const data = cloneDeep(form.value)
+  const other = { status: '0', type: '2', user: user.value.id, time: moment().format('YYYY-MM-DD'), person: user.value.nick_name }
+  let res
+  if (get(data, 'id')) res = await store.update({ ...data, ...other })
+  else res = await store.create({ ...data, ...other })
+  if ($checkRes(res, true)) ElMessage({ message: `发布成功可以长历史发布查看`, type: 'success' })
+}
+const toDraftSave = async () => {
+  const data = cloneDeep(form.value)
+  const other = { status: '-2', type: '2', user: user.value.id, time: moment().format('YYYY-MM-DD'), person: user.value.nick_name }
+  let res
+  if (get(data, 'id')) res = await store.update({ ...data, ...other })
+  else res = await store.create({ ...data, ...other })
+  if ($checkRes(res, true)) ElMessage({ message: `发布成功可以长历史发布查看`, type: 'success' })
+}
+
+// 上传图片
+const onUpload = (e) => {
+  const { model, value } = e
+  form.value[model] = value
+}
+</script>
+<style scoped lang="scss"></style>

+ 158 - 0
src/views/two/add/project.vue

@@ -0,0 +1,158 @@
+<template>
+  <div class="index">
+    <el-row>
+      <el-col :span="24" class="main animate__animated animate__backInRight" v-loading="loading">
+        <custom-form v-model="form" :fields="formFields" :rules="rules" @save="toSave" @draftSave="toDraftSave">
+          <template #tags>
+            <el-select v-model="form.tags" multiple filterable allow-create default-first-option :reserve-keyword="false" placeholder="请选择标签" style="width: 100%">
+              <el-option v-for="item in tagsList" :key="item.id" :label="item.title" :value="item.title" />
+            </el-select>
+          </template>
+          <template #industry>
+            <el-option v-for="i in sectorList" :key="i.id" :label="i.title" :value="i.title"></el-option>
+          </template>
+          <template #is_use>
+            <el-radio v-for="i in isUseList" :key="i.id" :label="i.value">{{ i.label }}</el-radio>
+          </template>
+          <template #field>
+            <el-option v-for="i in fieldList" :key="i.id" :label="i.label" :value="i.label"></el-option>
+          </template>
+          <template #type>
+            <el-option v-for="i in typeList" :key="i.id" :label="i.label" :value="i.value"></el-option>
+          </template>
+          <template #maturity>
+            <el-option v-for="i in maturityList" :key="i.id" :label="i.label" :value="i.label"></el-option>
+          </template>
+          <template #skill>
+            <el-option v-for="i in skillList" :key="i.id" :label="i.label" :value="i.value"></el-option>
+          </template>
+          <template #file>
+            <custom-upload model="file" :list="form.file" :limit="1" url="/files/web/cxyy_project/upload" @change="onUpload"></custom-upload>
+          </template>
+          <template #cooperate>
+            <el-option v-for="i in cooperateList" :key="i.id" :label="i.label" :value="i.value"></el-option>
+          </template>
+          <template #area>
+            <el-cascader v-model="form.area" :props="{ value: 'name', label: 'name' }" :options="cityList" style="width: 100%" />
+          </template>
+        </custom-form>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script setup>
+import { cloneDeep, get } from 'lodash-es'
+const $checkRes = inject('$checkRes')
+import { UserStore } from '@/store/user'
+const userStore = UserStore()
+const user = computed(() => userStore.user)
+// 接口
+import { ProjectStore } from '@/store/api/platform/project'
+import { DictDataStore } from '@/store/api/system/dictData'
+import { TagsStore } from '@/store/api/system/tags'
+import { SectorStore } from '@/store/api/platform/sector'
+import { RegionStore } from '@/store/api/system/region'
+const regionStore = RegionStore()
+const store = ProjectStore()
+const dictDataStore = DictDataStore()
+const tagsStore = TagsStore()
+const sectorStore = SectorStore()
+// 加载中
+const loading = ref(false)
+// 字典表
+const isUseList = ref([])
+const statusList = ref([])
+const fieldList = ref([])
+const typeList = ref([])
+const maturityList = ref([])
+const skillList = ref([])
+const cityList = ref([])
+const cooperateList = ref([])
+const tagsList = ref([])
+const sectorList = ref([])
+
+const form = ref({ file: [] })
+const formFields = ref([
+  { label: '项目名称', model: 'name' },
+  { label: '标签', model: 'tags', custom: true, mark: 'tags' },
+  { label: '所属产业', model: 'industry', type: 'select' },
+  { label: '行业分类', model: 'type', type: 'select', code: 'industry' },
+  { label: '成熟度', model: 'maturity', type: 'select', mark: 'dict', code: 'projectMaturity' },
+  { label: '技术类型', model: 'skill', type: 'select', mark: 'dict', code: 'technology' },
+  { label: '行业领域', model: 'field', type: 'select', mark: 'dict', code: 'field' },
+  { label: '合作类型', model: 'cooperate', type: 'select', mark: 'dict', code: 'projectType' },
+  { label: '项目地区', model: 'area', custom: true, mark: 'area' },
+  { label: '发布时间', model: 'time', type: 'date' },
+  { label: '项目主体', model: 'main' },
+  { label: '项目进展', model: 'progress' },
+  { label: '跟踪支持单位', model: 'track_unit' },
+  { label: '项目来源', model: 'source' },
+  { label: '是否启用', model: 'is_use', type: 'radio', mark: 'dict', code: 'isUse' },
+  { label: '简介', model: 'brief', type: 'textarea' },
+  { label: '附件', model: 'file', custom: true }
+])
+const rules = reactive({ name: [{ required: true, message: '请输入项目名称', trigger: 'blur' }] })
+// 请求
+onMounted(async () => {
+  loading.value = true
+  await searchOther()
+  loading.value = false
+})
+const searchOther = async () => {
+  let result
+  // 是否使用
+  result = await dictDataStore.query({ code: 'isUse', is_use: '0' })
+  if ($checkRes(result)) isUseList.value = result.data
+  // 状态
+  result = await dictDataStore.query({ code: 'examStatus', is_use: '0' })
+  if ($checkRes(result)) statusList.value = result.data
+  // 行业分类
+  result = await dictDataStore.query({ code: 'industry', is_use: '0' })
+  if ($checkRes(result)) typeList.value = result.data
+  // 成熟度
+  result = await dictDataStore.query({ code: 'projectMaturity', is_use: '0' })
+  if ($checkRes(result)) maturityList.value = result.data
+  // 技术领域
+  result = await dictDataStore.query({ code: 'field', is_use: '0' })
+  if ($checkRes(result)) fieldList.value = result.data
+  // 技术类型
+  result = await dictDataStore.query({ code: 'technology', is_use: '0' })
+  if ($checkRes(result)) skillList.value = result.data
+  // 合作类型
+  result = await dictDataStore.query({ code: 'projectType', is_use: '0' })
+  if ($checkRes(result)) cooperateList.value = result.data
+  // 标签
+  result = await tagsStore.query({ is_use: '0' })
+  if ($checkRes(result)) tagsList.value = result.data
+  // 行业
+  result = await sectorStore.query({ is_use: '0' })
+  if ($checkRes(result)) sectorList.value = result.data
+  // 城市
+  result = await regionStore.area({ level: 'province', code: 22 })
+  if ($checkRes(result)) cityList.value = result.data
+}
+
+// 上传图片
+const onUpload = (e) => {
+  const { model, value } = e
+  form.value[model] = value
+}
+const toSave = async () => {
+  const data = cloneDeep(form.value)
+  const other = { status: '0', user: user.value.id }
+  let res
+  if (get(data, 'id')) res = await store.update({ ...data, ...other })
+  else res = await store.create({ ...data, ...other })
+  if ($checkRes(res, true)) ElMessage({ message: `发布成功可以长历史发布查看`, type: 'success' })
+}
+const toDraftSave = async () => {
+  const data = cloneDeep(form.value)
+  const other = { status: '-2', user: user.value.id }
+  let res
+  if (get(data, 'id')) res = await store.update({ ...data, ...other })
+  else res = await store.create({ ...data, ...other })
+  if ($checkRes(res, true)) ElMessage({ message: `发布成功可以长历史发布查看`, type: 'success' })
+}
+</script>
+<style scoped lang="scss"></style>

+ 144 - 0
src/views/two/add/supply.vue

@@ -0,0 +1,144 @@
+<template>
+  <div class="index">
+    <el-row>
+      <el-col :span="24" class="main animate__animated animate__backInRight" v-loading="loading">
+        <custom-form v-model="form" :fields="formFields" :rules="rules" @save="toSave" @draftSave="toDraftSave">
+          <template #is_use>
+            <el-radio v-for="i in isUseList" :key="i.id" :label="i.value">{{ i.label }}</el-radio>
+          </template>
+          <template #field>
+            <el-option v-for="i in fieldList" :key="i.id" :label="i.label" :value="i.label"></el-option>
+          </template>
+          <template #urgent>
+            <el-option v-for="i in urgentList" :key="i.id" :label="i.label" :value="i.value"></el-option>
+          </template>
+          <template #method>
+            <el-option v-for="i in methodList" :key="i.id" :label="i.label" :value="i.value"></el-option>
+          </template>
+          <template #industry>
+            <el-option v-for="i in sectorList" :key="i.id" :label="i.title" :value="i.title"></el-option>
+          </template>
+          <template #area>
+            <el-cascader v-model="form.area" :props="{ value: 'name', label: 'name' }" :options="cityList" style="width: 100%" />
+          </template>
+          <template #tags>
+            <el-select v-model="form.tags" multiple filterable allow-create default-first-option :reserve-keyword="false" placeholder="请选择标签" style="width: 100%">
+              <el-option v-for="item in tagsList" :key="item.id" :label="item.title" :value="item.title" />
+            </el-select>
+          </template>
+        </custom-form>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script setup>
+import { cloneDeep, get } from 'lodash-es'
+const $checkRes = inject('$checkRes')
+import { UserStore } from '@/store/user'
+const userStore = UserStore()
+const user = computed(() => userStore.user)
+// 接口
+import { SupplyStore } from '@/store/api/platform/supply'
+import { DictDataStore } from '@/store/api/system/dictData'
+import { TagsStore } from '@/store/api/system/tags'
+import { SectorStore } from '@/store/api/platform/sector'
+import { RegionStore } from '@/store/api/system/region'
+const regionStore = RegionStore()
+const store = SupplyStore()
+const dictDataStore = DictDataStore()
+const tagsStore = TagsStore()
+const sectorStore = SectorStore()
+// 加载中
+const loading = ref(false)
+// 字典表
+const isUseList = ref([])
+const statusList = ref([])
+const methodList = ref([])
+const urgentList = ref([])
+const fieldList = ref([])
+const cityList = ref([])
+const supplyList = ref([])
+const tagsList = ref([])
+const sectorList = ref([])
+
+const form = ref({ time: [] })
+const formFields = ref([
+  { label: '供给名称', model: 'name' },
+  { label: '标签', model: 'tags', custom: true, mark: 'tags' },
+  { label: '所属产业', model: 'industry', type: 'select' },
+  { label: '行业领域', model: 'field' },
+  { label: '供给紧急度', model: 'urgent', type: 'select', mark: 'dict', code: 'urgent' },
+  { label: '合作方式', model: 'method', type: 'select', mark: 'dict', code: 'method' },
+  { label: '价格(万元)', model: 'money' },
+  { label: '项目来源', model: 'source' },
+  { label: '供给地区', model: 'area', custom: true, mark: 'area' },
+  { label: '发布时间', model: 'time', type: 'daterange', mark: 'time' },
+  { label: '是否公开', model: 'is_use', type: 'radio', mark: 'dict', code: 'isUse' },
+  { label: '简介', model: 'brief', type: 'textarea' }
+])
+const rules = reactive({ name: [{ required: true, message: '请输入供给名称', trigger: 'blur' }] })
+// 请求
+onMounted(async () => {
+  loading.value = true
+  await searchOther()
+  loading.value = false
+})
+const searchOther = async () => {
+  let result
+  // 是否使用
+  result = await dictDataStore.query({ code: 'isUse', is_use: '0' })
+  if ($checkRes(result)) isUseList.value = result.data
+  // 状态
+  result = await dictDataStore.query({ code: 'examStatus', is_use: '0' })
+  if ($checkRes(result)) statusList.value = result.data
+  // 合作方式
+  result = await dictDataStore.query({ code: 'method', is_use: '0' })
+  if ($checkRes(result)) methodList.value = result.data
+  // 需求紧急度
+  result = await dictDataStore.query({ code: 'urgent', is_use: '0' })
+  if ($checkRes(result)) urgentList.value = result.data
+  // 技术领域
+  result = await dictDataStore.query({ code: 'field', is_use: '0' })
+  if ($checkRes(result)) fieldList.value = result.data
+  // 需求状态
+  result = await dictDataStore.query({ code: 'supplyStatus', is_use: '0' })
+  if ($checkRes(result)) supplyList.value = result.data
+  // 标签
+  result = await tagsStore.query({ is_use: '0' })
+  if ($checkRes(result)) tagsList.value = result.data
+  // 行业
+  result = await sectorStore.query({ is_use: '0' })
+  if ($checkRes(result)) sectorList.value = result.data
+  // 城市
+  result = await regionStore.area({ level: 'province', code: 22 })
+  if ($checkRes(result)) cityList.value = result.data
+}
+const toSave = async () => {
+  const data = cloneDeep(form.value)
+  const other = { status: '0', user: user.value.id }
+  if (data.time && data.time.length > 1) {
+    data.start_time = data.time[0]
+    data.end_time = data.time[1]
+  }
+  delete data.time
+  let res
+  if (get(data, 'id')) res = await store.update({ ...data, ...other })
+  else res = await store.create({ ...data, ...other })
+  if ($checkRes(res, true)) ElMessage({ message: `发布成功可以长历史发布查看`, type: 'success' })
+}
+const toDraftSave = async () => {
+  const data = cloneDeep(form.value)
+  const other = { status: '-2', user: user.value.id }
+  if (data.time && data.time.length > 1) {
+    data.start_time = data.time[0]
+    data.end_time = data.time[1]
+  }
+  delete data.time
+  let res
+  if (get(data, 'id')) res = await store.update({ ...data, ...other })
+  else res = await store.create({ ...data, ...other })
+  if ($checkRes(res, true)) ElMessage({ message: `发布成功可以长历史发布查看`, type: 'success' })
+}
+</script>
+<style scoped lang="scss"></style>

+ 127 - 2
src/views/two/index.vue

@@ -1,9 +1,134 @@
 <template>
-  <custom-layout class="main"> 信息发布 </custom-layout>
+  <custom-layout class="main">
+    <div class="w_1300 one">
+      <div class="tabs">
+        <div class="tab_1" @click="toTabs('0')">信息发布</div>
+        <div class="tab_2" @click="toTabs('1')">历史发布</div>
+      </div>
+      <div class="content" v-if="active == '0'">
+        <el-select v-model="value1" placeholder="请选择要发布信息类型" size="large" style="width: 240px">
+          <el-option v-for="item in options" :key="item.route_name" :label="item.name" :value="item.route_name" />
+        </el-select>
+        <div class="content_1">
+          <achievement v-if="value1 == 'achievement'"></achievement>
+          <demand v-if="value1 == 'demand'"></demand>
+          <news2 v-if="value1 == 'news2'"></news2>
+          <supply v-if="value1 == 'supply'"></supply>
+          <footplate v-if="value1 == 'footplate'"></footplate>
+          <match v-if="value1 == 'match'"></match>
+          <project v-if="value1 == 'project'"></project>
+        </div>
+      </div>
+      <div class="content" v-else>
+        <el-select v-model="value2" placeholder="请选择要历史信息类型" size="large" style="width: 240px">
+          <el-option v-for="item in options2" :key="item.route_name" :label="item.name" :value="item.route_name" />
+        </el-select>
+        <div class="content_1">
+          <achievement2 v-if="value2 == 'achievement'"></achievement2>
+          <demand2 v-if="value2 == 'demand'"></demand2>
+          <news22 v-if="value2 == 'news2'"></news22>
+          <supply2 v-if="value2 == 'supply'"></supply2>
+          <footplate2 v-if="value2 == 'footplate'"></footplate2>
+          <match2 v-if="value2 == 'match'"></match2>
+          <project2 v-if="value2 == 'project'"></project2>
+        </div>
+      </div>
+    </div>
+  </custom-layout>
 </template>
 
-<script setup></script>
+<script setup>
+// 组件
+import achievement from './add/achievement.vue'
+import demand from './add/demand.vue'
+import news2 from './add/news2.vue'
+import supply from './add/supply.vue'
+import footplate from './add/footplate.vue'
+import match from './add/match.vue'
+import project from './add/project.vue'
+// 组件
+import achievement2 from '../center/achievement.vue'
+import demand2 from '../center/demand.vue'
+import news22 from '../center/news2.vue'
+import supply2 from '../center/supply.vue'
+import footplate2 from '../center/footplate.vue'
+import match2 from '../center/match.vue'
+import project2 from '../center/project.vue'
+const active = ref('0')
+// 选择
+const toTabs = async (item) => {
+  active.value = item
+}
+const value1 = ref('')
+const value2 = ref('')
+const options = [
+  { id: 4, name: '发布成果', route_name: 'achievement', path: '/achievement', icon: 'Medal' },
+  { id: 5, name: '发布需求', route_name: 'demand', path: '/demand', icon: 'DataBoard' },
+  { id: 8, name: '行业动态', route_name: 'news2', path: '/news2', icon: 'Message' },
+  { id: 9, name: '发布供给', route_name: 'supply', path: '/supply', icon: 'Notification' },
+  { id: 10, name: '发布中试', route_name: 'footplate', path: '/footplate', icon: 'TakeawayBox' },
+  { id: 11, name: '发布赛事', route_name: 'match', path: '/match', icon: 'CollectionTag' },
+  { id: 13, name: '发布项目', route_name: 'project', path: '/project', icon: 'Trophy' }
+]
+const options2 = [
+  { id: 4, name: '成果管理', route_name: 'achievement', path: '/achievement', icon: 'Medal' },
+  { id: 5, name: '需求管理', route_name: 'demand', path: '/demand', icon: 'DataBoard' },
+  { id: 8, name: '行业动态', route_name: 'news2', path: '/news2', icon: 'Message' },
+  { id: 9, name: '供给管理', route_name: 'supply', path: '/supply', icon: 'Notification' },
+  { id: 10, name: '中试管理', route_name: 'footplate', path: '/footplate', icon: 'TakeawayBox' },
+  { id: 11, name: '赛事管理', route_name: 'match', path: '/match', icon: 'CollectionTag' },
+  { id: 13, name: '项目管理', route_name: 'project', path: '/project', icon: 'Trophy' }
+]
+</script>
 <style scoped lang="scss">
 .main {
+  .one {
+    margin: 10px auto;
+    display: flex;
+    .tabs {
+      display: flex;
+      flex-direction: column;
+      height: 80vh;
+      justify-content: center;
+      .tab_1 {
+        width: 50px;
+        color: #fff;
+        font-size: 20px;
+        background: #bd2409;
+        border-radius: 4px 0 0 4px;
+        border: 1px solid #d3d3d3;
+        display: inline-block;
+        text-align: center;
+        line-height: 25px;
+        cursor: pointer;
+        margin: 0 0 40px 0;
+        display: block;
+        padding: 10px 13px;
+      }
+      .tab_2 {
+        width: 50px;
+        color: #fff;
+        font-size: 20px;
+        background: #0258d8;
+        border-radius: 4px 0 0 4px;
+        border: 1px solid #d3d3d3;
+        display: inline-block;
+        text-align: center;
+        line-height: 25px;
+        cursor: pointer;
+        margin: 40px 0 0 0;
+        display: block;
+        padding: 10px 13px;
+      }
+    }
+    .content {
+      width: 97%;
+      border: 1px solid #d3d3d3;
+      padding: 10px;
+      .content_1 {
+        margin: 10px 0 0 0;
+      }
+    }
+  }
 }
 </style>

+ 0 - 130
src/views/two/parts/demand.vue

@@ -1,130 +0,0 @@
-<template>
-  <div class="demand">
-    <el-form ref="DemandRules" :model="form" :rules="rules" class="form">
-      <el-form-item label="需求名称" prop="name">
-        <el-input size="large" clearable v-model="form.name" placeholder="请输入需求名称"> </el-input>
-      </el-form-item>
-      <el-form-item label="行业领域" prop="field">
-        <el-select size="large" v-model="form.field" clearable placeholder="请选择行业领域">
-          <el-option v-for="(item, index) in fieldList" :key="index" :label="item.label" :value="item.label" />
-        </el-select>
-      </el-form-item>
-      <el-form-item label="需求紧急度" prop="urgent">
-        <el-select size="large" v-model="form.urgent" clearable placeholder="请选择需求紧急度">
-          <el-option v-for="(item, index) in urgentList" :key="index" :label="item.label" :value="item.label" />
-        </el-select>
-      </el-form-item>
-      <el-form-item label="合作方式" prop="method">
-        <el-select size="large" v-model="form.method" clearable placeholder="请选择合作方式">
-          <el-option v-for="(item, index) in methodList" :key="index" :label="item.label" :value="item.label" />
-        </el-select>
-      </el-form-item>
-      <el-form-item label="价格(万元)" prop="money">
-        <el-input size="large" clearable v-model="form.money" placeholder="请输入价格(万元)"> </el-input>
-      </el-form-item>
-      <el-form-item label="需求地区" prop="area">
-        <el-cascader size="large" v-model="form.area" :props="{ value: 'name', label: 'name' }" :options="cityList" style="width: 100%" />
-      </el-form-item>
-      <el-form-item label="有效期" prop="time">
-        <el-date-picker size="large" v-model="form.time" type="daterange" format="YYYY-MM-DD" value-format="YYYY-MM-DD" range-separator="至" start-placeholder="开始时间" end-placeholder="结束时间" />
-      </el-form-item>
-      <el-form-item label="是否启用" prop="is_use">
-        <el-radio-group v-model="form.is_use">
-          <el-radio v-for="(item, index) in isUseList" :key="index" :value="item.value">{{ item.label }}</el-radio>
-        </el-radio-group>
-      </el-form-item>
-      <el-row :gutter="20" align="middle">
-        <el-col :span="12">
-          <el-form-item label="上传图片" prop="file">
-            <custom-upload model="file" :list="form.file" :limit="1" url="/files/web/cxyy_demand/upload" @change="onUpload"></custom-upload>
-          </el-form-item>
-        </el-col>
-        <el-col :span="12">
-          <el-form-item label="上传视频" prop="video">
-            <custom-upload model="video" :list="form.video" :limit="1" url="/files/web/cxyy_demand/upload" @change="onUpload"></custom-upload>
-          </el-form-item>
-        </el-col>
-      </el-row>
-      <el-form-item label="简介" prop="brief">
-        <el-input size="large" v-model="form.brief" :autosize="{ minRows: 2, maxRows: 8 }" type="textarea" placeholder="请输入简介" />
-      </el-form-item>
-      <el-col :span="24" class="button">
-        <el-button type="primary" @click="submitForm(DemandRules)">发布</el-button>
-      </el-col>
-    </el-form>
-    <a-modal v-model:open="open" title="相关推荐" @ok="handleOk"> 是否查看相关供给推荐 </a-modal>
-  </div>
-</template>
-<script setup>
-import { cloneDeep, get } from 'lodash-es'
-const $checkRes = inject('$checkRes')
-import { DemandStore } from '@/store/api/platform/demand'
-const demandStore = DemandStore()
-const form = ref({})
-const DemandRules = ref()
-import { UserStore } from '@/store/user'
-const userStore = UserStore()
-const user = computed(() => userStore.user)
-// 路由
-const router = useRouter()
-// 字典表
-const isUseList = inject('isUseList')
-const methodList = inject('methodList')
-const urgentList = inject('urgentList')
-const fieldList = inject('fieldList')
-const cityList = inject('cityList')
-const rules = reactive({
-  name: [{ required: true, message: '请输入需求名称', trigger: 'blur' }],
-  field: [{ required: true, message: '请选择行业领域', trigger: 'change' }],
-  urgent: [{ required: true, message: '请选择需求紧急度', trigger: 'change' }],
-  method: [{ required: true, message: '请选择合作方式', trigger: 'change' }],
-  money: [{ required: true, message: '请输入价格', trigger: 'blur' }],
-  area: [{ required: true, message: '请选择需求地区', trigger: 'change' }],
-  time: [{ required: true, message: '请选择起始时间', trigger: 'change' }],
-  is_use: [{ required: true, message: '请选择是否使用', trigger: 'change' }],
-  brief: [{ required: true, message: '请输入简介', trigger: 'blur' }]
-})
-// 上传图片
-const onUpload = (e) => {
-  const { model, value } = e
-  form.value[model] = value
-}
-// 保存
-const submitForm = async (formEl) => {
-  if (!formEl) return
-  await formEl.validate(async (valid, fields) => {
-    if (valid) {
-      const data = cloneDeep(form.value)
-      const other = { status: '0', user: user.value.id }
-      let res
-      if (get(data, '_id')) res = await demandStore.update({ ...data, ...other })
-      else await demandStore.create({ ...data, ...other })
-      if ($checkRes(res, true)) {
-        open.value = true
-      }
-    } else {
-      console.log('error submit!', fields)
-    }
-  })
-}
-const open = ref(false)
-const handleOk = () => {
-  const query = { type: 'search' }
-  router.push({ path: '/search', query })
-}
-</script>
-<style scoped lang="scss">
-:deep(.el-form-item) {
-  margin-bottom: 10px !important;
-}
-:deep(.el-form-item__label) {
-  margin-bottom: 10px !important;
-}
-.el-form-item__label {
-  justify-content: flex-start !important;
-  max-width: 120px !important;
-}
-.button {
-  text-align: center;
-}
-</style>

+ 0 - 131
src/views/two/parts/supply.vue

@@ -1,131 +0,0 @@
-<template>
-  <div class="supply">
-    <el-form ref="SupplyRules" :model="form" :rules="rules" class="form">
-      <el-form-item label="供应名称" prop="name">
-        <el-input size="large" clearable v-model="form.name" placeholder="请输入供应名称"> </el-input>
-      </el-form-item>
-      <el-form-item label="行业领域" prop="field">
-        <el-select size="large" v-model="form.field" clearable placeholder="请选择行业领域">
-          <el-option v-for="(item, index) in fieldList" :key="index" :label="item.label" :value="item.label" />
-        </el-select>
-      </el-form-item>
-      <el-form-item label="供应紧急度" prop="urgent">
-        <el-select size="large" v-model="form.urgent" clearable placeholder="请选择供应紧急度">
-          <el-option v-for="(item, index) in urgentList" :key="index" :label="item.label" :value="item.label" />
-        </el-select>
-      </el-form-item>
-      <el-form-item label="合作方式" prop="method">
-        <el-select size="large" v-model="form.method" clearable placeholder="请选择合作方式">
-          <el-option v-for="(item, index) in methodList" :key="index" :label="item.label" :value="item.label" />
-        </el-select>
-      </el-form-item>
-      <el-form-item label="价格(万元)" prop="money">
-        <el-input size="large" clearable v-model="form.money" placeholder="请输入价格(万元)"> </el-input>
-      </el-form-item>
-      <el-form-item label="供应地区" prop="area">
-        <el-cascader size="large" v-model="form.area" :props="{ value: 'name', label: 'name' }" :options="cityList" style="width: 100%" />
-      </el-form-item>
-      <el-form-item label="有效期" prop="time">
-        <el-date-picker size="large" v-model="form.time" type="daterange" format="YYYY-MM-DD" value-format="YYYY-MM-DD" range-separator="至" start-placeholder="开始时间" end-placeholder="结束时间" />
-      </el-form-item>
-      <el-form-item label="是否启用" prop="is_use">
-        <el-radio-group v-model="form.is_use">
-          <el-radio v-for="(item, index) in isUseList" :key="index" :value="item.value">{{ item.label }}</el-radio>
-        </el-radio-group>
-      </el-form-item>
-      <el-row :gutter="20" align="middle">
-        <el-col :span="12">
-          <el-form-item label="上传图片" prop="file">
-            <custom-upload model="file" :list="form.file" :limit="1" url="/files/web/cxyy_demand/upload" @change="onUpload"></custom-upload>
-          </el-form-item>
-        </el-col>
-        <el-col :span="12">
-          <el-form-item label="上传视频" prop="video">
-            <custom-upload model="video" :list="form.video" :limit="1" url="/files/web/cxyy_demand/upload" @change="onUpload"></custom-upload>
-          </el-form-item>
-        </el-col>
-      </el-row>
-      <el-form-item label="简介" prop="brief">
-        <el-input size="large" v-model="form.brief" type="textarea" placeholder="请输入简介" />
-      </el-form-item>
-      <el-col :span="24" class="button">
-        <el-button type="primary" @click="submitForm(DemandRules)">发布</el-button>
-      </el-col>
-    </el-form>
-    <a-modal v-model:open="open" title="相关推荐" @ok="handleOk"> 是否查看相关需求推荐 </a-modal>
-  </div>
-</template>
-<script setup>
-import { cloneDeep, get } from 'lodash-es'
-const $checkRes = inject('$checkRes')
-import { SupplyStore } from '@/store/api/platform/supply'
-const supplyStore = SupplyStore()
-const form = ref({})
-const SupplyRules = ref()
-import { UserStore } from '@/store/user'
-const userStore = UserStore()
-const user = computed(() => userStore.user)
-// 路由
-const router = useRouter()
-// 字典表
-const isUseList = inject('isUseList')
-const methodList = inject('methodList')
-const urgentList = inject('urgentList')
-const fieldList = inject('fieldList')
-const cityList = inject('cityList')
-const rules = reactive({
-  name: [{ required: true, message: '请输入供应名称', trigger: 'blur' }],
-  field: [{ required: true, message: '请选择行业领域', trigger: 'change' }],
-  // type: [{ required: true, message: '请选择类型', trigger: 'change' }],
-  urgent: [{ required: true, message: '请选择供应紧急度', trigger: 'change' }],
-  method: [{ required: true, message: '请选择合作方式', trigger: 'change' }],
-  money: [{ required: true, message: '请输入价格', trigger: 'blur' }],
-  area: [{ required: true, message: '请选择供应地区', trigger: 'change' }],
-  time: [{ required: true, message: '请选择起始时间', trigger: 'change' }],
-  is_use: [{ required: true, message: '请选择是否使用', trigger: 'change' }],
-  brief: [{ required: true, message: '请输入简介', trigger: 'blur' }]
-})
-// 上传图片
-const onUpload = (e) => {
-  const { model, value } = e
-  form.value[model] = value
-}
-// 保存
-const submitForm = async (formEl) => {
-  if (!formEl) return
-  await formEl.validate(async (valid, fields) => {
-    if (valid) {
-      const data = cloneDeep(form.value)
-      const other = { status: '0', user: user.value.id }
-      let res
-      if (get(data, '_id')) res = await supplyStore.update({ ...data, ...other })
-      else res = await supplyStore.create({ ...data, ...other })
-      if ($checkRes(res, true)) {
-        open.value = true
-      }
-    } else {
-      console.log('error submit!', fields)
-    }
-  })
-}
-const open = ref(false)
-const handleOk = () => {
-  const query = { type: 'search' }
-  router.push({ path: '/search', query })
-}
-</script>
-<style scoped lang="scss">
-:deep(.el-form-item) {
-  margin-bottom: 10px !important;
-}
-:deep(.el-form-item__label) {
-  margin-bottom: 10px !important;
-}
-.el-form-item__label {
-  justify-content: flex-start !important;
-  max-width: 120px !important;
-}
-.button {
-  text-align: center;
-}
-</style>