project.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413
  1. <template>
  2. <custom-layout class="main">
  3. <el-col :span="24" class="one">
  4. <div class="w_1300">
  5. <el-col :span="24" class="one_1">
  6. <div class="search">
  7. <el-input v-model="searchForm.name" size="large" placeholder="请输入关键字" :suffix-icon="Search">
  8. <template #append>
  9. <el-button type="primary" size="large" @click="toSearchInfo">搜索</el-button>
  10. </template>
  11. </el-input>
  12. </div>
  13. </el-col>
  14. <el-col :span="24" class="one_2">
  15. <div class="one_2_1">
  16. <div class="Seacher">
  17. <div class="OneLeft">
  18. <span>行业</span>
  19. </div>
  20. <div v-if="!twoShow" class="OneRight">
  21. <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" />
  22. </div>
  23. <div v-else class="OneRight">
  24. <el-checkbox class="label" @change="oneChange" v-for="(item, index) in plateList" :key="index" v-model="checked1" :label="item.title" size="large" />
  25. </div>
  26. <div class="button">
  27. <span v-if="!twoShow" @click="twoShow = true">
  28. <el-icon><ArrowDown /></el-icon>
  29. </span>
  30. <span v-else @click="twoShow = false">
  31. <el-icon><ArrowUp /></el-icon>
  32. </span>
  33. </div>
  34. </div>
  35. <div class="Seacher">
  36. <div class="OneLeft">
  37. <span>技术领域</span>
  38. </div>
  39. <div v-if="!oneShow" class="OneRight">
  40. <el-checkbox class="label" @change="oneChange" v-for="(item, index) in typeList.slice(0, 8)" :key="index" v-model="checked2" :label="item.label" size="large" />
  41. </div>
  42. <div v-else class="OneRight">
  43. <el-checkbox class="label" @change="oneChange" v-for="(item, index) in typeList" :key="index" v-model="checked2" :label="item.label" size="large" />
  44. </div>
  45. <div class="button">
  46. <span v-if="!oneShow" @click="oneShow = true">
  47. <el-icon><ArrowDown /></el-icon>
  48. </span>
  49. <span v-else @click="oneShow = false">
  50. <el-icon><ArrowUp /></el-icon>
  51. </span>
  52. </div>
  53. </div>
  54. <div class="Seacher">
  55. <div class="OneLeft">
  56. <span>所在地</span>
  57. </div>
  58. <div class="OneRight">
  59. <el-checkbox class="label" @change="oneChange" v-for="(item, index) in cityList" :key="index" v-model="checked3" :label="item.name" size="large" />
  60. </div>
  61. </div>
  62. <div class="Seacher">
  63. <div class="OneLeft">
  64. <span>项目成熟度</span>
  65. </div>
  66. <div class="OneRight">
  67. <el-checkbox class="label" @change="oneChange" v-for="(item, index) in maturityList" :key="index" v-model="checked4" :label="item.label" size="large" />
  68. </div>
  69. </div>
  70. <div class="one_ipunt">
  71. <el-input class="input" clearable size="large" v-model="searchForm.tags" placeholder="标签名称" />
  72. <el-input class="input" clearable size="large" v-model="searchForm.source" placeholder="项目来源" />
  73. <el-input class="input" clearable size="large" v-model="searchForm.main" placeholder="项目主体" />
  74. <el-input class="input" clearable size="large" v-model="searchForm.progress" placeholder="项目进展" />
  75. <el-button class="button" size="large" type="primary" @click="toSearchInfo">检索</el-button>
  76. </div>
  77. </div>
  78. <div class="one_2_2">
  79. <div class="list" :class="['list' + index]" v-for="(item, index) in list" :key="index" @click="toView(item)">
  80. <div class="type textOne">{{ item.industry || '暂无' }}</div>
  81. <div class="title">
  82. <p class="ellipsis-3">{{ item.name || '暂无' }}</p>
  83. </div>
  84. <div class="address">
  85. <el-icon color="#595959"><Location /></el-icon>
  86. <span class="textOne">{{ item.main || '暂无' }}</span>
  87. </div>
  88. <div class="biaoqian textOne">
  89. <span v-if="item.technology">{{ item.technology }}</span>
  90. <span v-if="item.sell">{{ item.sell }}</span>
  91. </div>
  92. <span class="state" :class="['state1']"></span>
  93. </div>
  94. </div>
  95. <div class="one_2_3">
  96. <el-pagination background layout="prev, pager, next" :total="total" :page-size="limit" v-model:current-page="currentPage" @current-change="changePage" @size-change="sizeChange" />
  97. </div>
  98. </el-col>
  99. </div>
  100. </el-col>
  101. </custom-layout>
  102. </template>
  103. <script setup>
  104. const $checkRes = inject('$checkRes')
  105. // 接口
  106. import { ProjectStore } from '@/store/api/platform/project'
  107. import { DictDataStore } from '@/store/api/system/dictData'
  108. import { RegionStore } from '@/store/api/system/region'
  109. import { SectorStore } from '@/store/api/platform/sector'
  110. const store = ProjectStore()
  111. const dictDataStore = DictDataStore()
  112. const regionStore = RegionStore()
  113. const sectorStore = SectorStore()
  114. // 路由
  115. const router = useRouter()
  116. // 是否展开
  117. const twoShow = ref(false)
  118. const oneShow = ref(false)
  119. // 加载中
  120. const loading = ref(false)
  121. const checked1 = ref([])
  122. const checked2 = ref([])
  123. const checked3 = ref([])
  124. const checked4 = ref([])
  125. const typeList = ref([])
  126. const plateList = ref([])
  127. // 字典表
  128. const maturityList = ref([])
  129. const cityList = ref([])
  130. // 列表
  131. const list = ref([])
  132. let skip = 0
  133. let limit = 15
  134. const total = ref(0)
  135. // 搜索
  136. const searchForm = ref({})
  137. // 请求
  138. onMounted(async () => {
  139. loading.value = true
  140. await searchOther()
  141. await search({ skip, limit })
  142. loading.value = false
  143. })
  144. const searchOther = async () => {
  145. let result
  146. // // 合作类型
  147. // result = await dictDataStore.query({ code: 'projectType', is_use: '0' })
  148. // if ($checkRes(result)) projectList.value = result.data
  149. // 成熟度
  150. result = await dictDataStore.query({ code: 'projectMaturity', is_use: '0' })
  151. if ($checkRes(result)) maturityList.value = result.data
  152. // // 行业分类
  153. // result = await dictDataStore.query({ code: 'industry', is_use: '0' })
  154. // if ($checkRes(result)) industryList.value = result.data
  155. // 技术领域
  156. result = await dictDataStore.query({ code: 'field', is_use: '0' })
  157. if ($checkRes(result)) typeList.value = result.data
  158. // 地区
  159. result = await regionStore.list({ level: 'city', parent_code: 22 })
  160. if ($checkRes(result)) cityList.value = result.data
  161. // 行业
  162. result = await sectorStore.query({ is_use: '0' })
  163. if ($checkRes(result)) plateList.value = result.data
  164. }
  165. const search = async (query = { skip, limit }) => {
  166. skip = query.skip
  167. limit = query.limit
  168. const info = { skip: query.skip, limit: query.limit, is_use: '0', status: '1', ...searchForm.value }
  169. const res = await store.list(info)
  170. if (res.errcode == '0') {
  171. list.value = res.data
  172. total.value = res.total
  173. }
  174. }
  175. // 搜索
  176. const toSearchInfo = async () => {
  177. await search({ skip, limit })
  178. }
  179. // 查看
  180. const toView = (item) => {
  181. router.push({ path: `/project/detail`, query: { id: item.id || item._id } })
  182. }
  183. const currentPage = ref(1)
  184. // 分页
  185. const changePage = (page = currentPage.value) => {
  186. search({ skip: (page - 1) * limit, limit: limit })
  187. }
  188. const sizeChange = (limits) => {
  189. limit = limits
  190. currentPage.value = 1
  191. search({ skip: 0, limit: limit })
  192. }
  193. // 选择
  194. const oneChange = async () => {
  195. if (checked1.value && checked1.value.length > 0) {
  196. searchForm.value.industry = checked1.value
  197. } else if (checked2.value && checked2.value.length > 0) {
  198. searchForm.value.field = checked2.value
  199. } else if (checked3.value && checked3.value.length > 0) {
  200. searchForm.value.area = checked3.value
  201. } else if (checked4.value && checked4.value.length > 0) {
  202. searchForm.value.maturity = checked4.value
  203. } else searchForm.value = {}
  204. await search({ skip, limit })
  205. }
  206. </script>
  207. <style scoped lang="scss">
  208. .main {
  209. .one {
  210. background: url(/images/bg-tec-list.jpg) no-repeat;
  211. .one_1 {
  212. padding: 85px 0 0;
  213. .search {
  214. margin: 0 auto;
  215. width: 810px;
  216. :deep(.el-input--large .el-input__inner) {
  217. height: 60px;
  218. }
  219. }
  220. }
  221. .one_2 {
  222. margin-top: 100px;
  223. padding: 30px;
  224. background-color: $global-color-fff;
  225. .one_2_1 {
  226. .Seacher {
  227. display: flex;
  228. justify-content: center;
  229. align-items: stretch;
  230. position: relative;
  231. margin-bottom: 15px;
  232. .OneLeft {
  233. width: 134px;
  234. height: 36px;
  235. background-color: #f5f8ff;
  236. border-radius: 21px;
  237. font-size: $global-font-size-16;
  238. font-weight: bold;
  239. color: #000000;
  240. flex-shrink: 0;
  241. line-height: 36px;
  242. text-align: center;
  243. }
  244. .OneRight {
  245. display: flex;
  246. flex-wrap: wrap;
  247. align-items: center;
  248. padding: 0 12px;
  249. flex: 1;
  250. background-color: #fff;
  251. .label {
  252. cursor: pointer;
  253. }
  254. .label:hover {
  255. color: $global-color-107;
  256. }
  257. }
  258. .button {
  259. display: flex;
  260. align-items: center;
  261. margin: 0 5px 0 0;
  262. }
  263. }
  264. .one_ipunt {
  265. display: flex;
  266. align-items: center;
  267. justify-content: space-between;
  268. margin: 10px 0;
  269. .input {
  270. margin: 0 5px 0 0;
  271. }
  272. .button {
  273. margin: 0 0 0 5px;
  274. }
  275. }
  276. }
  277. .one_2_2 {
  278. margin: 20px 0;
  279. display: flex;
  280. flex-wrap: wrap;
  281. justify-content: center;
  282. align-items: center;
  283. .list {
  284. position: relative;
  285. margin: 0 39px 39px 0;
  286. width: 208px;
  287. height: 286px;
  288. box-shadow: 3px 4px 4px 0px rgba(41, 41, 115, 0.32);
  289. border: solid 1px #ededed;
  290. .type {
  291. margin-left: 33px;
  292. padding: 22px 10px 0 0;
  293. font-size: $global-font-size-16;
  294. color: #414141;
  295. }
  296. .title {
  297. display: flex;
  298. align-items: center;
  299. margin: 24px 18px 0;
  300. height: 100px;
  301. font-size: $global-font-size-18;
  302. font-weight: bold;
  303. color: #ffffff;
  304. .ellipsis-3 {
  305. display: -webkit-box;
  306. -webkit-box-orient: vertical;
  307. overflow: hidden;
  308. -webkit-line-clamp: 3;
  309. }
  310. }
  311. .address {
  312. margin-top: 80px;
  313. padding: 0 5px;
  314. font-size: $global-font-size-16;
  315. color: #282828;
  316. display: flex;
  317. align-items: center;
  318. justify-content: flex-end;
  319. }
  320. .biaoqian {
  321. margin: 10px 5px 0 5px;
  322. text-align: right;
  323. overflow: hidden;
  324. span {
  325. padding: 0 5px;
  326. background-color: #f5f8ff;
  327. border-radius: 3px;
  328. border: solid 1px #d2daec;
  329. font-size: $global-font-size-14;
  330. line-height: 23px;
  331. color: #7d8aaa;
  332. margin-right: 2px;
  333. }
  334. }
  335. }
  336. .state {
  337. display: block;
  338. position: absolute;
  339. right: 0px;
  340. top: 0px;
  341. width: 75px;
  342. height: 24px;
  343. background: url(/images/project/dbhi-kcxm-item-xmyl.png) no-repeat;
  344. }
  345. .state1 {
  346. background: url(/images/project/dbhi-kcxm-item-xm1.png) no-repeat;
  347. }
  348. .state2 {
  349. background: url(/images/project/dbhi-kcxm-item-xm2.png) no-repeat;
  350. }
  351. .state3 {
  352. background: url(/images/project/dbhi-kcxm-item-xm3.png) no-repeat;
  353. }
  354. .list0 {
  355. background: url(/images/project/dbhi-kcxm-item1.png) no-repeat;
  356. }
  357. .list1 {
  358. background: url(/images/project/dbhi-kcxm-item2.png) no-repeat;
  359. }
  360. .list2 {
  361. background: url(/images/project/dbhi-kcxm-item3.png) no-repeat;
  362. }
  363. .list3 {
  364. background: url(/images/project/dbhi-kcxm-item4.png) no-repeat;
  365. }
  366. .list4 {
  367. background: url(/images/project/dbhi-kcxm-item5.png) no-repeat;
  368. }
  369. .list5 {
  370. background: url(/images/project/dbhi-kcxm-item6.png) no-repeat;
  371. }
  372. .list6 {
  373. background: url(/images/project/dbhi-kcxm-item7.png) no-repeat;
  374. }
  375. .list7 {
  376. background: url(/images/project/dbhi-kcxm-item8.png) no-repeat;
  377. }
  378. .list8 {
  379. background: url(/images/project/dbhi-kcxm-item9.png) no-repeat;
  380. }
  381. .list9 {
  382. background: url(/images/project/dbhi-kcxm-item10.png) no-repeat;
  383. }
  384. .list10 {
  385. background: url(/images/project/dbhi-kcxm-item1.png) no-repeat;
  386. }
  387. .list11 {
  388. background: url(/images/project/dbhi-kcxm-item2.png) no-repeat;
  389. }
  390. .list12 {
  391. background: url(/images/project/dbhi-kcxm-item3.png) no-repeat;
  392. }
  393. .list13 {
  394. background: url(/images/project/dbhi-kcxm-item4.png) no-repeat;
  395. }
  396. .list14 {
  397. background: url(/images/project/dbhi-kcxm-item5.png) no-repeat;
  398. }
  399. .list:nth-child(5n) {
  400. margin-right: 0;
  401. }
  402. }
  403. .one_2_3 {
  404. display: flex;
  405. justify-content: center;
  406. margin: 20px 0;
  407. }
  408. }
  409. }
  410. }
  411. </style>