Jelajahi Sumber

修改发布需求

zs 1 tahun lalu
induk
melakukan
67fca8d87c

+ 4 - 4
src/layout/index.vue

@@ -38,10 +38,10 @@
                 <el-button size="small" :icon="Edit">发布</el-button>
                 <template #dropdown>
                   <el-dropdown-menu>
-                    <el-dropdown-item @click="toRelease('demand')">发布需求</el-dropdown-item>
-                    <el-dropdown-item @click="toRelease('project')">发布项目</el-dropdown-item>
-                    <el-dropdown-item @click="toRelease('match')">发布赛事</el-dropdown-item>
-                    <el-dropdown-item @click="toRelease('achievement')">发布成果</el-dropdown-item>
+                    <el-dropdown-item @click="toRelease('demand')">我的需求</el-dropdown-item>
+                    <el-dropdown-item @click="toRelease('project')">我的项目</el-dropdown-item>
+                    <el-dropdown-item @click="toRelease('match')">我的赛事</el-dropdown-item>
+                    <el-dropdown-item @click="toRelease('achievement')">我的成果</el-dropdown-item>
                   </el-dropdown-menu>
                 </template>
               </el-dropdown>

+ 177 - 7
src/views/release/index.vue

@@ -2,31 +2,201 @@
   <div id="index">
     <el-row>
       <el-col :span="24" class="main animate__animated animate__backInRight" v-loading="loading">
-        <div class="w_1200">发布</div>
+        <div class="w_1200 one">
+          <demand v-show="routeType == 'demand'"></demand>
+          <project v-show="routeType == 'project'"></project>
+          <match v-show="routeType == 'match'"></match>
+          <achievement v-show="routeType == 'achievement'"></achievement>
+        </div>
       </el-col>
     </el-row>
   </div>
 </template>
 
 <script setup>
-import { useRoute } from 'vue-router'
+const $checkRes = inject('$checkRes')
+import { cloneDeep, get } from 'lodash-es'
 const route = useRoute()
+// 接口
+import { AchievementStore } from '@/store/api/platform/achievement'
+import { DemandStore } from '@/store/api/platform/demand'
+import { ProjectStore } from '@/store/api/platform/project'
+import { MatchStore } from '@/store/api/platform/match'
+import { DictDataStore } from '@/store/api/system/dictData'
+const achieveStore = AchievementStore()
+const demandStore = DemandStore()
+const projectStore = ProjectStore()
+const matchStore = MatchStore()
+const dictDataStore = DictDataStore()
+// 组件
+import demand from './parts/demand.vue'
+import project from './parts/project.vue'
+import match from './parts/match.vue'
+import achievement from './parts/achievement.vue'
 // 加载中
 const loading = ref(false)
+// 显示类型
+const type = ref('0')
+const routeType = ref('0')
 const form = ref({})
+// 字典表
+const fieldList = ref([])
+const statusList = ref([])
+//
+const fields = ref([])
+// 列表
+const list = ref([])
+let skip = 0
+let limit = inject('limit')
+const total = ref(0)
+const currentPage = ref(1)
 // 请求
 onMounted(async () => {
   loading.value = true
-  search()
+  await searchOther()
+  await searchField()
   loading.value = false
 })
-const search = async () => {}
+
+const searchField = async () => {
+  routeType.value = route.query.type
+  if (routeType.value == 'achievement') {
+    fields.value = [
+      { label: '成果名称', model: 'name', type: 'name' },
+      { label: '技术领域:', model: 'field', type: 'dict' },
+      { label: '成果地区:', model: 'area', type: 'area' },
+      { label: '状态:', model: 'status', type: 'dict' }
+    ]
+  } else if (routeType.value == 'demand') {
+    fields.value = [
+      { label: '需求名称', model: 'name', type: 'name' },
+      { label: '技术领域:', model: 'field', type: 'dict' },
+      { label: '需求地区:', model: 'area', type: 'area' },
+      { label: '状态:', model: 'status', type: 'dict' }
+    ]
+  } else if (routeType.value == 'project') {
+    fields.value = [
+      { label: '项目名称', model: 'name', type: 'name' },
+      { label: '技术领域:', model: 'field', type: 'dict' },
+      { label: '发布时间:', model: 'time' },
+      { label: '状态:', model: 'status', type: 'dict' }
+    ]
+  } else if (routeType.value == 'match') {
+    fields.value = [
+      { label: '比赛名称', model: 'name', type: 'name' },
+      { label: '比赛金额:', model: 'money' },
+      { label: '比赛日期:', model: 'time', type: 'time' },
+      { label: '状态:', model: 'status', type: 'dict' }
+    ]
+  }
+  await search({ skip, limit })
+}
+const search = async (query = { skip: 0, limit }) => {
+  const info = {
+    skip: query.skip,
+    limit: query.limit,
+    is_use: '0',
+    status: '1'
+  }
+  let res
+  if (routeType.value == 'achievement') res = await achieveStore.query(info)
+  else if (routeType.value == 'demand') res = await demandStore.query(info)
+  else if (routeType.value == 'project') res = await projectStore.query(info)
+  else if (routeType.value == 'match') res = await matchStore.query(info)
+  if (res.errcode == '0') {
+    list.value = res.data
+    total.value = res.total
+  }
+}
+// 保存
+const submitForm = async (formEl) => {
+  if (!formEl) return
+  await formEl.validate(async (valid, fields) => {
+    if (valid) {
+      const data = cloneDeep(form.value)
+      console.log(data)
+    } else {
+      console.log('error submit!', fields)
+    }
+  })
+}
+const searchOther = async () => {
+  let result
+  // 技术领域
+  result = await dictDataStore.query({ code: 'field', is_use: '0' })
+  if ($checkRes(result)) fieldList.value = result.data
+  // 状态
+  result = await dictDataStore.query({ code: 'examStatus', is_use: '0' })
+  if ($checkRes(result)) statusList.value = result.data
+}
+// 字典数据转换
+const getDict = (data, model) => {
+  let res
+  if (model == 'field') res = fieldList.value.find((f) => f.value == data)
+  if (model == 'status') res = statusList.value.find((f) => f.value == data)
+  return get(res, 'label')
+}
+// 地区显示
+const getArea = (data) => {
+  if (data) return data.join(',')
+}
+// 时间
+const getTime = (data) => {
+  if (data) return `${data[0]} - ${data[1]}`
+}
+const toCommon = (data) => {
+  type.value = data
+}
+// 查看
+const toView = (item) => {
+  console.log(item)
+}
+// 修改
+const toEdit = (item) => {
+  console.log(item)
+}
+// 分页
+const changePage = (page = currentPage.value) => {
+  search({ skip: (page - 1) * limit, limit: limit })
+}
+const sizeChange = (limits) => {
+  limit = limits
+  currentPage.value = 1
+  search({ skip: 0, limit: limit })
+}
+watch(
+  route,
+  (newVal) => {
+    if (newVal) {
+      searchField()
+    }
+  },
+  {
+    immediate: true //初始化立即执行
+  }
+)
+// provide
+provide('form', form)
+provide('type', type)
+provide('toCommon', toCommon)
+provide('submitForm', submitForm)
+provide('fields', fields)
+provide('list', list)
+provide('toView', toView)
+provide('toEdit', toEdit)
+provide('getArea', getArea)
+provide('getTime', getTime)
+provide('getDict', getDict)
+provide('limit', limit)
+provide('total', total)
+provide('currentPage', currentPage)
+provide('sizeChange', sizeChange)
+provide('changePage', changePage)
 </script>
 <style scoped lang="scss">
 .main {
+  background-color: #f1f2f5;
   padding: 20px;
-  .button {
-    text-align: center;
-  }
+  min-height: 77vh;
 }
 </style>

+ 95 - 0
src/views/release/parts/achievement.vue

@@ -0,0 +1,95 @@
+<template>
+  <div class="demand">
+    <el-col :span="24" class="one" v-if="type == '0'">
+      <el-col :span="24" class="one_1">
+        <el-button type="primary" @click="toCommon('1')">新增</el-button>
+      </el-col>
+      <el-col :span="24" class="one_2">
+        <List></List>
+      </el-col>
+    </el-col>
+    <el-col :span="24" class="two" v-else>
+      <el-col :span="24" class="two_1">
+        <el-button type="primary" @click="toCommon('0')">返回</el-button>
+      </el-col>
+      <el-col :span="24" class="two_2">
+        <el-form
+          label-position="top"
+          ref="ruleFormRef"
+          :model="form"
+          :rules="rules"
+          label-width="80px"
+          class="form"
+        >
+          <el-form-item label="账号" prop="account">
+            <el-input v-model="form.account" placeholder="请输入账号"> </el-input>
+          </el-form-item>
+          <el-form-item label="昵称" prop="nick_name">
+            <el-input v-model="form.nick_name" placeholder="请输入昵称"> </el-input>
+          </el-form-item>
+          <el-form-item label="性别" prop="gender">
+            <el-select v-model="form.gender" width="100%" placeholder="请选择性别">
+              <el-option
+                v-for="(item, index) in genderList"
+                :key="index"
+                :label="item.label"
+                :value="item.value"
+              />
+            </el-select>
+          </el-form-item>
+          <el-form-item label="手机号" prop="phone">
+            <el-input v-model="form.phone" placeholder="请输入手机号"> </el-input>
+          </el-form-item>
+        </el-form>
+        <el-col :span="24" class="button">
+          <el-button type="primary" @click="submitForm(ruleFormRef)">保存</el-button>
+        </el-col>
+      </el-col>
+    </el-col>
+  </div>
+</template>
+<script setup>
+// 组件
+import List from './parts/list.vue'
+const form = inject('form')
+const type = inject('type')
+const submitForm = inject('submitForm')
+const toCommon = inject('toCommon')
+const validatePhoneNumber = (rule, value, callback) => {
+  const reg = /^1[3-9]\d{9}$/
+  if (!value) {
+    return callback(new Error('手机号不能为空'))
+  }
+  if (!reg.test(value)) {
+    return callback(new Error('请输入正确的手机号'))
+  }
+  callback()
+}
+const rules = reactive({
+  nick_name: [{ required: true, message: '请输入昵称', trigger: 'blur' }],
+  gender: [{ required: true, message: '请选择性别', trigger: 'blur' }],
+  phone: [{ required: true, validator: validatePhoneNumber, trigger: 'blur' }],
+  account: [{ required: true, message: '请输入账号', trigger: 'blur' }]
+})
+</script>
+<style scoped lang="scss">
+.one {
+  .one_1 {
+    margin: 10px;
+    text-align: right;
+  }
+}
+.two {
+  background-color: #fff;
+  padding: 20px;
+  border-radius: 10px;
+  .two_1 {
+    text-align: right;
+  }
+  .two_2 {
+    .button {
+      text-align: center;
+    }
+  }
+}
+</style>

+ 95 - 0
src/views/release/parts/demand.vue

@@ -0,0 +1,95 @@
+<template>
+  <div class="demand">
+    <el-col :span="24" class="one" v-if="type == '0'">
+      <el-col :span="24" class="one_1">
+        <el-button type="primary" @click="toCommon('1')">新增</el-button>
+      </el-col>
+      <el-col :span="24" class="one_2">
+        <List></List>
+      </el-col>
+    </el-col>
+    <el-col :span="24" class="two" v-else>
+      <el-col :span="24" class="two_1">
+        <el-button type="primary" @click="toCommon('0')">返回</el-button>
+      </el-col>
+      <el-col :span="24" class="two_2">
+        <el-form
+          label-position="top"
+          ref="ruleFormRef"
+          :model="form"
+          :rules="rules"
+          label-width="80px"
+          class="form"
+        >
+          <el-form-item label="账号" prop="account">
+            <el-input v-model="form.account" placeholder="请输入账号"> </el-input>
+          </el-form-item>
+          <el-form-item label="昵称" prop="nick_name">
+            <el-input v-model="form.nick_name" placeholder="请输入昵称"> </el-input>
+          </el-form-item>
+          <el-form-item label="性别" prop="gender">
+            <el-select v-model="form.gender" width="100%" placeholder="请选择性别">
+              <el-option
+                v-for="(item, index) in genderList"
+                :key="index"
+                :label="item.label"
+                :value="item.value"
+              />
+            </el-select>
+          </el-form-item>
+          <el-form-item label="手机号" prop="phone">
+            <el-input v-model="form.phone" placeholder="请输入手机号"> </el-input>
+          </el-form-item>
+        </el-form>
+        <el-col :span="24" class="button">
+          <el-button type="primary" @click="submitForm(ruleFormRef)">保存</el-button>
+        </el-col>
+      </el-col>
+    </el-col>
+  </div>
+</template>
+<script setup>
+// 组件
+import List from './parts/list.vue'
+const form = inject('form')
+const type = inject('type')
+const submitForm = inject('submitForm')
+const toCommon = inject('toCommon')
+const validatePhoneNumber = (rule, value, callback) => {
+  const reg = /^1[3-9]\d{9}$/
+  if (!value) {
+    return callback(new Error('手机号不能为空'))
+  }
+  if (!reg.test(value)) {
+    return callback(new Error('请输入正确的手机号'))
+  }
+  callback()
+}
+const rules = reactive({
+  nick_name: [{ required: true, message: '请输入昵称', trigger: 'blur' }],
+  gender: [{ required: true, message: '请选择性别', trigger: 'blur' }],
+  phone: [{ required: true, validator: validatePhoneNumber, trigger: 'blur' }],
+  account: [{ required: true, message: '请输入账号', trigger: 'blur' }]
+})
+</script>
+<style scoped lang="scss">
+.one {
+  .one_1 {
+    margin: 10px;
+    text-align: right;
+  }
+}
+.two {
+  background-color: #fff;
+  padding: 20px;
+  border-radius: 10px;
+  .two_1 {
+    text-align: right;
+  }
+  .two_2 {
+    .button {
+      text-align: center;
+    }
+  }
+}
+</style>

+ 95 - 0
src/views/release/parts/match.vue

@@ -0,0 +1,95 @@
+<template>
+  <div class="demand">
+    <el-col :span="24" class="one" v-if="type == '0'">
+      <el-col :span="24" class="one_1">
+        <el-button type="primary" @click="toCommon('1')">新增</el-button>
+      </el-col>
+      <el-col :span="24" class="one_2">
+        <List></List>
+      </el-col>
+    </el-col>
+    <el-col :span="24" class="two" v-else>
+      <el-col :span="24" class="two_1">
+        <el-button type="primary" @click="toCommon('0')">返回</el-button>
+      </el-col>
+      <el-col :span="24" class="two_2">
+        <el-form
+          label-position="top"
+          ref="ruleFormRef"
+          :model="form"
+          :rules="rules"
+          label-width="80px"
+          class="form"
+        >
+          <el-form-item label="账号" prop="account">
+            <el-input v-model="form.account" placeholder="请输入账号"> </el-input>
+          </el-form-item>
+          <el-form-item label="昵称" prop="nick_name">
+            <el-input v-model="form.nick_name" placeholder="请输入昵称"> </el-input>
+          </el-form-item>
+          <el-form-item label="性别" prop="gender">
+            <el-select v-model="form.gender" width="100%" placeholder="请选择性别">
+              <el-option
+                v-for="(item, index) in genderList"
+                :key="index"
+                :label="item.label"
+                :value="item.value"
+              />
+            </el-select>
+          </el-form-item>
+          <el-form-item label="手机号" prop="phone">
+            <el-input v-model="form.phone" placeholder="请输入手机号"> </el-input>
+          </el-form-item>
+        </el-form>
+        <el-col :span="24" class="button">
+          <el-button type="primary" @click="submitForm(ruleFormRef)">保存</el-button>
+        </el-col>
+      </el-col>
+    </el-col>
+  </div>
+</template>
+<script setup>
+// 组件
+import List from './parts/list.vue'
+const form = inject('form')
+const type = inject('type')
+const submitForm = inject('submitForm')
+const toCommon = inject('toCommon')
+const validatePhoneNumber = (rule, value, callback) => {
+  const reg = /^1[3-9]\d{9}$/
+  if (!value) {
+    return callback(new Error('手机号不能为空'))
+  }
+  if (!reg.test(value)) {
+    return callback(new Error('请输入正确的手机号'))
+  }
+  callback()
+}
+const rules = reactive({
+  nick_name: [{ required: true, message: '请输入昵称', trigger: 'blur' }],
+  gender: [{ required: true, message: '请选择性别', trigger: 'blur' }],
+  phone: [{ required: true, validator: validatePhoneNumber, trigger: 'blur' }],
+  account: [{ required: true, message: '请输入账号', trigger: 'blur' }]
+})
+</script>
+<style scoped lang="scss">
+.one {
+  .one_1 {
+    margin: 10px;
+    text-align: right;
+  }
+}
+.two {
+  background-color: #fff;
+  padding: 20px;
+  border-radius: 10px;
+  .two_1 {
+    text-align: right;
+  }
+  .two_2 {
+    .button {
+      text-align: center;
+    }
+  }
+}
+</style>

+ 159 - 0
src/views/release/parts/parts/list.vue

@@ -0,0 +1,159 @@
+<template>
+  <div id="index">
+    <el-row>
+      <el-col :span="24" class="main">
+        <div class="w_1200">
+          <el-col :span="24" class="one">
+            <a-list :loading="loading" :grid="{ gutter: 14, column: 4 }" :data-source="list">
+              <template #renderItem="{ item }">
+                <el-col :span="24" class="list">
+                  <el-col :span="24" v-for="(i, f) in fields" :key="f">
+                    <el-col :span="24" class="name textOver" v-if="i.type == 'name'">
+                      <el-tooltip effect="dark" :content="item[i.model]" placement="top">
+                        {{ item[i.model] || '暂无' }}
+                      </el-tooltip>
+                    </el-col>
+                    <el-col
+                      :span="24"
+                      class="other_1"
+                      :class="[i.model == 'status' ? 'red' : '']"
+                      v-else-if="i.type == 'dict'"
+                    >
+                      <span>{{ i.label }}</span>
+                      {{ getDict(item[i.model] || '暂无', [i.model]) }}
+                    </el-col>
+                    <el-col :span="24" class="other_1" v-else-if="i.type == 'area'">
+                      <span>{{ i.label }}</span>
+                      {{ getArea(item[i.model] || '暂无') }}
+                    </el-col>
+                    <el-col :span="24" class="other_1" v-else-if="i.type == 'time'">
+                      <span>{{ i.label }}</span>
+                      {{ getTime(item[i.model] || '暂无') }}
+                    </el-col>
+                    <el-col :span="24" v-else class="other_1 textOver">
+                      <span>{{ i.label }}</span>
+                      {{ item[i.model] || '暂无' }}
+                    </el-col>
+                  </el-col>
+                  <el-col :span="24" class="bottom">
+                    <el-button @click.stop="toEdit(item)" size="small">修改</el-button>
+                    <el-button @click.stop="toView(item)" type="primary" size="small"
+                      >查看详情</el-button
+                    >
+                  </el-col>
+                </el-col>
+              </template>
+            </a-list>
+          </el-col>
+          <el-col :span="24" class="two">
+            <el-pagination
+              background
+              layout="total, prev, pager, next"
+              :page-sizes="[10, 20, 50, 100, 200]"
+              :total="total"
+              :page-size="limit"
+              v-model:current-page="currentPage"
+              @current-change="changePage"
+              @size-change="sizeChange"
+            >
+            </el-pagination>
+          </el-col>
+        </div>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script setup>
+const fields = inject('fields')
+const list = inject('list')
+const total = inject('total')
+const limit = inject('limit')
+const getDict = inject('getDict')
+const getArea = inject('getArea')
+const getTime = inject('getTime')
+const toView = inject('toView')
+const toEdit = inject('toEdit')
+const currentPage = inject('currentPage')
+const changePage = inject('changePage')
+const sizeChange = inject('sizeChange')
+</script>
+<style scoped lang="scss">
+.main {
+  .one {
+    .list {
+      background: #fff;
+      box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.03);
+      border-radius: 2px;
+      width: 285px;
+      height: 175px;
+      margin-bottom: 15px;
+      cursor: pointer;
+      transition: all 0.3s;
+      padding: 20px;
+
+      .name {
+        display: flex;
+        align-items: center;
+        font-size: 16px;
+        color: #121834;
+        font-weight: 500;
+        margin: 5px 0 0 0;
+        .tags {
+          grid-gap: 0.5rem;
+          gap: 0.5rem;
+          display: flex;
+          margin: 0 0 0 10px;
+        }
+      }
+
+      .name:hover {
+        color: #2374ff;
+      }
+
+      .other_1 {
+        font-size: 12px;
+        text-align: justify;
+        line-height: 12px;
+        font-weight: 400;
+        letter-spacing: 0;
+        color: #8f97a3;
+        margin-top: 10px;
+
+        span:last-child {
+          color: #525a68;
+        }
+      }
+      .red {
+        color: red;
+      }
+
+      .bottom {
+        margin: 20px 10px;
+        text-align: right;
+        .button {
+          font-size: 12px;
+          color: #fff;
+          text-align: center;
+          line-height: 12px;
+          font-weight: 500;
+          padding: 5px 12px;
+          background: #2374ff;
+          box-shadow: 0 3px 6px 0 rgba(35, 116, 255, 0.1);
+          border-radius: 2px;
+        }
+      }
+    }
+
+    .list:hover {
+      background: #f0f7ff;
+      box-shadow: 0 0 16px rgba(205, 205, 205, 0.6);
+    }
+  }
+  .two {
+    display: flex;
+    flex-direction: row-reverse;
+    padding: 20px;
+  }
+}
+</style>

+ 95 - 0
src/views/release/parts/project.vue

@@ -0,0 +1,95 @@
+<template>
+  <div class="demand">
+    <el-col :span="24" class="one" v-if="type == '0'">
+      <el-col :span="24" class="one_1">
+        <el-button type="primary" @click="toCommon('1')">新增</el-button>
+      </el-col>
+      <el-col :span="24" class="one_2">
+        <List></List>
+      </el-col>
+    </el-col>
+    <el-col :span="24" class="two" v-else>
+      <el-col :span="24" class="two_1">
+        <el-button type="primary" @click="toCommon('0')">返回</el-button>
+      </el-col>
+      <el-col :span="24" class="two_2">
+        <el-form
+          label-position="top"
+          ref="ruleFormRef"
+          :model="form"
+          :rules="rules"
+          label-width="80px"
+          class="form"
+        >
+          <el-form-item label="账号" prop="account">
+            <el-input v-model="form.account" placeholder="请输入账号"> </el-input>
+          </el-form-item>
+          <el-form-item label="昵称" prop="nick_name">
+            <el-input v-model="form.nick_name" placeholder="请输入昵称"> </el-input>
+          </el-form-item>
+          <el-form-item label="性别" prop="gender">
+            <el-select v-model="form.gender" width="100%" placeholder="请选择性别">
+              <el-option
+                v-for="(item, index) in genderList"
+                :key="index"
+                :label="item.label"
+                :value="item.value"
+              />
+            </el-select>
+          </el-form-item>
+          <el-form-item label="手机号" prop="phone">
+            <el-input v-model="form.phone" placeholder="请输入手机号"> </el-input>
+          </el-form-item>
+        </el-form>
+        <el-col :span="24" class="button">
+          <el-button type="primary" @click="submitForm(ruleFormRef)">保存</el-button>
+        </el-col>
+      </el-col>
+    </el-col>
+  </div>
+</template>
+<script setup>
+// 组件
+import List from './parts/list.vue'
+const form = inject('form')
+const type = inject('type')
+const submitForm = inject('submitForm')
+const toCommon = inject('toCommon')
+const validatePhoneNumber = (rule, value, callback) => {
+  const reg = /^1[3-9]\d{9}$/
+  if (!value) {
+    return callback(new Error('手机号不能为空'))
+  }
+  if (!reg.test(value)) {
+    return callback(new Error('请输入正确的手机号'))
+  }
+  callback()
+}
+const rules = reactive({
+  nick_name: [{ required: true, message: '请输入昵称', trigger: 'blur' }],
+  gender: [{ required: true, message: '请选择性别', trigger: 'blur' }],
+  phone: [{ required: true, validator: validatePhoneNumber, trigger: 'blur' }],
+  account: [{ required: true, message: '请输入账号', trigger: 'blur' }]
+})
+</script>
+<style scoped lang="scss">
+.one {
+  .one_1 {
+    margin: 10px;
+    text-align: right;
+  }
+}
+.two {
+  background-color: #fff;
+  padding: 20px;
+  border-radius: 10px;
+  .two_1 {
+    text-align: right;
+  }
+  .two_2 {
+    .button {
+      text-align: center;
+    }
+  }
+}
+</style>