index.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426
  1. <template>
  2. <div :class="{isMobile: mobile}">
  3. <div v-if="!mobile" class="kaifain">
  4. <div class="topArea">
  5. <div class="bgImage">
  6. <img src="~@/assets/img/kaifain/banner_bj@2x.png" alt/>
  7. </div>
  8. <div class="topContent">
  9. <div class="wordImg">
  10. <img src="~@/assets/img/kaifain/top_name@2x.png" alt/>
  11. </div>
  12. <div class="btnList">
  13. <div class="freeSubmit" @click="isShowToast = true">
  14. <p>免费发布需求</p>
  15. </div>
  16. <div class="bePartner" @click="handleApplyBtnClick">
  17. <p>申请入驻</p>
  18. </div>
  19. </div>
  20. </div>
  21. </div>
  22. <div class="contentArea">
  23. <div class="selectArea" v-if="!isSeoList">
  24. <div class="content" :key="key" v-for="(key, i) in Object.keys(typeList)">
  25. <div class="left">
  26. <p>{{typeList[key].title}}</p>
  27. </div>
  28. <div class="right">
  29. <div
  30. class="cell"
  31. v-for="(item, ii) in typeList[key].list"
  32. :key="item.id"
  33. :class="{selected: item.id === selected[key]}"
  34. @click="changeIndexSeo(key, item)"
  35. v-if="ii < 8 || expansion[key]"
  36. >
  37. <p>{{item.name}}</p>
  38. </div>
  39. </div>
  40. <div
  41. class="more"
  42. @click="changeExpansion(key)"
  43. v-if="typeList[key].list.length > 8"
  44. >{{expansion[key] ? "收起" : "更多"}}
  45. </div>
  46. </div>
  47. </div>
  48. <div class="listArea">
  49. <h1 class="sTitle" v-if="!page.keyword">{{head.h1 || '解决方案'}}</h1>
  50. <h1 class="sTitle" v-else>搜索包含"{{page.keyword}}"的解决方案</h1>
  51. <div class="list" v-loading="loading">
  52. <nuxt-link
  53. class="cell"
  54. v-for="item in dataList"
  55. :key="item.id"
  56. :to="`/s/${item.hash_id}`"
  57. target="_blank"
  58. :title="item.name"
  59. >
  60. <div class="left">
  61. <img :src="item.images" alt="解决方案images"/>
  62. </div>
  63. <div class="right">
  64. <div class="top">
  65. <div class="titleA">
  66. <div class="title">{{item.title}}</div>
  67. <div class="tips" v-if="item.city_op_name">{{item.city_op_name}}</div>
  68. <div class="tips" v-if="item.industry_name">{{item.industry_name}}</div>
  69. <div class="tips" v-if="item.tech_type_name">{{item.tech_type_name}}</div>
  70. </div>
  71. <div class="intro">
  72. <p class="tt">介绍:</p>
  73. <p class="value">{{item.description}}</p>
  74. </div>
  75. <div class="ep">
  76. <p class="tt">案例:</p>
  77. <p class="value">
  78. <span>{{item.successCase || '暂未提供'}}</span>
  79. </p>
  80. </div>
  81. </div>
  82. <div class="bottom">
  83. <div class="icon">
  84. <img
  85. :src="item.company_logo"
  86. alt
  87. onerror="this.src='https://stacdn.proginn.com/image/uCenter/company_logo.png'"
  88. />
  89. </div>
  90. <p class="word">{{item.company_name || '' }}</p>
  91. <p class="status" v-if="item.company_verify_status == 2">{{"已认证"}}</p>
  92. </div>
  93. </div>
  94. </nuxt-link>
  95. <div v-if="dataList.length === 0" class="noneData">
  96. <p>没有数据</p>
  97. </div>
  98. </div>
  99. </div>
  100. <div class="pagination">
  101. <el-pagination
  102. v-if="!isSeoList"
  103. background
  104. layout="prev, pager, next"
  105. :total="page.total"
  106. :page-size="page.size"
  107. @current-change="pageChange"
  108. ></el-pagination>
  109. <div v-else>
  110. <div class="list">
  111. <nuxt-link
  112. v-for="(item,index) in new Array(Math.ceil(page.total / page.size))"
  113. :to="`/s/?page=${index+1}`"
  114. :key="(page)+index"
  115. >{{index+1}}
  116. </nuxt-link>
  117. </div>
  118. </div>
  119. </div>
  120. </div>
  121. </div>
  122. <div class="kaifainMobile" v-else>
  123. <div class="topSelect" v-if="!isSeoList">
  124. <van-dropdown-menu>
  125. <van-dropdown-item
  126. v-for="(key, i) in Object.keys(typeList)"
  127. v-model="selected[key]"
  128. :options="typeList[key].list"
  129. :key="key+i"
  130. @change="changeIndex"
  131. />
  132. </van-dropdown-menu>
  133. </div>
  134. <h1>{{head.h1 || '解决方案'}}</h1>
  135. <van-pull-refresh
  136. v-model="refreshing"
  137. @refresh="onRefresh"
  138. class="listArea"
  139. :class="{noneInWx: !$deviceType.app}"
  140. >
  141. <div style="text-align: center" v-if="firstLoading">
  142. <van-loading size="24px">加载中...</van-loading>
  143. </div>
  144. <van-list
  145. v-else
  146. v-model="loading"
  147. :finished="finished"
  148. finished-text="没有更多了"
  149. @load="onLoad"
  150. :immediate-check="false"
  151. >
  152. <nuxt-link
  153. class="cell"
  154. v-for="item in dataList"
  155. :key="item.id"
  156. :to="`/s/${item.hash_id}`"
  157. target="_blank"
  158. >
  159. <div class="bodyCont">
  160. <div class="left">
  161. <img :src="item.images" alt/>
  162. </div>
  163. <div class="right">
  164. <div class="cellTitle">{{item.title}}</div>
  165. <div class="spanList">
  166. <div class="tips" v-if="item.city_op_name">{{item.city_op_name}}</div>
  167. <div class="tips" v-if="item.industry_name">{{item.industry_name}}</div>
  168. <div class="tips" v-if="item.tech_type_name">{{item.tech_type_name}}</div>
  169. </div>
  170. <div class="desc">{{item.description}}</div>
  171. </div>
  172. </div>
  173. <div class="bottomCont">
  174. <p class="icon" v-if="item.company_name"></p>
  175. <p class="word" v-if="item.company_name ">{{item.company_name || '' }}</p>
  176. </div>
  177. </nuxt-link>
  178. </van-list>
  179. </van-pull-refresh>
  180. <!-- <a v-if="!deviceType.app && mobile" class="downapp" href="">下载APP</a>-->
  181. </div>
  182. <ConnectUs
  183. :source="'开发屋'"
  184. :isShowToast="isShowToast"
  185. @close="isShowToast=false"
  186. v-if="!isSeoList"
  187. ></ConnectUs>
  188. <BindMobile ref="bindMobile" v-if="!isSeoList"></BindMobile>
  189. <KaifainFooter style="margin-top: 30px;" :data="footer"/>
  190. </div>
  191. </template>
  192. <script>
  193. import ConnectUs from "@/components/common/connectUs";
  194. import BindMobile from "@/components/common/bindMobile";
  195. import DealSeoData from "@/components/kaifain/dealSeoIndex";
  196. import DealSeoFooter from "@/components/kaifain/dealSeoFooter";
  197. import KaifainFooter from "@/components/SeoFooter";
  198. import {mapState, mapMutations} from "vuex";
  199. import deviceType from "../../plugins/deviceType";
  200. export default {
  201. layout: "opacity_header_kf_tmp",
  202. showCommonFooter: false,
  203. components: {ConnectUs, BindMobile, KaifainFooter},
  204. head() {
  205. let {
  206. title = "",
  207. keyword = "",
  208. descrption = "",
  209. h1 = "",
  210. canonical = "",
  211. metaLocation,
  212. } = this.head || {};
  213. if (this.$deviceType.app) {
  214. title = "开发屋-解决方案";
  215. }
  216. let obj = {
  217. title: title,
  218. meta: [
  219. {
  220. name: "keywords",
  221. content: keyword,
  222. },
  223. {
  224. name: "descrption",
  225. content: descrption,
  226. },
  227. {
  228. name: "h1",
  229. content: h1,
  230. },
  231. ],
  232. link: [{rel: "canonical", href: canonical}],
  233. };
  234. if (metaLocation) {
  235. obj.meta.push({name: "location", content: metaLocation});
  236. }
  237. return obj;
  238. },
  239. async asyncData({...params}) {
  240. try {
  241. params.store.commit("updateNoneCommonFooter", true);
  242. } catch (e) {
  243. console.log("updateNoneCommonFooter", e);
  244. }
  245. let dealDataObj = new DealSeoData(params);
  246. let ans = await dealDataObj.dealData();
  247. let dealSeoFooterObj = new DealSeoFooter(params);
  248. let footer = await dealSeoFooterObj.dealData();
  249. let domainConfig = params.store.state.domainConfig;
  250. return {
  251. ...domainConfig,
  252. ...ans,
  253. ...footer,
  254. };
  255. },
  256. data() {
  257. return {
  258. kaifainUrl: "",
  259. expansion: {
  260. city: 0,
  261. industry: 0,
  262. techType: 0,
  263. },
  264. isShowToast: false,
  265. name: "",
  266. phone: "",
  267. loading: false,
  268. refreshing: false,
  269. firstLoading: false, //移动端加载loading
  270. };
  271. },
  272. created() {
  273. const {kaifainUrl, siteUrl} = this.$store.state.domainConfig;
  274. this.kaifainUrl = kaifainUrl;
  275. this.siteUrl = siteUrl;
  276. },
  277. computed: {
  278. ...mapState(["isPC", "isWeixin", "deviceType", "noneCommonFooter"]),
  279. },
  280. mounted() {
  281. if (this.mobile) {
  282. document.body.style = "overflow:hidden;";
  283. }
  284. console.log(this.dataList);
  285. },
  286. methods: {
  287. changeIndex(key, item) {
  288. this.page.page = 1;
  289. this.page.total = 0;
  290. this.firstLoading = true;
  291. if (item) {
  292. this.selected[key] = item.id;
  293. this.getList();
  294. } else {
  295. this.getList();
  296. }
  297. },
  298. changeIndexSeo(key, item) {
  299. console.log("key:", key, "item:", item, "selected:", this.selected);
  300. this.selected[key] = item.id;
  301. this.selected[key + "Slug"] = item.slug;
  302. let {citySlug, industrySlug, techTypeSlug} = this.selected;
  303. let url = this.kaifainUrl + "/";
  304. if (citySlug) {
  305. url += citySlug + "/";
  306. }
  307. if (industrySlug) {
  308. url += industrySlug + "/";
  309. }
  310. if (techTypeSlug) {
  311. url += techTypeSlug + "/";
  312. }
  313. location.href = url;
  314. },
  315. changeExpansion(key) {
  316. this.expansion[key] = !this.expansion[key];
  317. },
  318. getList() {
  319. const {page, selected} = this;
  320. let p = {
  321. city: selected.city,
  322. tech_type: selected.techType,
  323. industry: selected.industry,
  324. ...page,
  325. };
  326. this.loading = true;
  327. // let params = new URLSearchParams(p).toString()
  328. this.$axios
  329. .post("/api/kaifawu/index", p)
  330. .then((res) => {
  331. if (Number(res.data.status) === 1) {
  332. let data = res.data.data;
  333. this.page.total = data.total;
  334. let dataList = data.providers || [];
  335. dataList.forEach((item) => {
  336. item["successCase"] = "";
  337. if (Array.isArray(item.successful_case)) {
  338. let tem = item.successful_case.map((item) => item.title);
  339. item["successCase"] = tem.join("、");
  340. }
  341. });
  342. if (this.page.page === 1 || !this.mobile) {
  343. this.dataList = [...dataList];
  344. } else {
  345. this.dataList = [...this.dataList, ...dataList];
  346. }
  347. this.page.page += 1;
  348. if (this.page.total <= this.dataList.length) {
  349. this.finished = true;
  350. }
  351. }
  352. })
  353. .finally(() => {
  354. this.firstLoading = false;
  355. this.refreshing = false;
  356. this.loading = false;
  357. console.log("this.finished", this.finished);
  358. });
  359. },
  360. pageChange(i) {
  361. this.page.page = i;
  362. this.getList();
  363. },
  364. handleApplyBtnClick() {
  365. const {userinfo} = this.$store.state || {};
  366. //检查登录
  367. if (!userinfo || !userinfo.uid) {
  368. this.$message.info("请先登录!");
  369. location.href =
  370. "/?loginbox=show&next=" + encodeURIComponent(location.href);
  371. return;
  372. }
  373. //去绑定手机号
  374. if (!userinfo.mobile) {
  375. this.$message.info("请先绑定手机号");
  376. this.$refs.bindMobile.open();
  377. return;
  378. }
  379. //判断是否是首次入驻 非首次入驻 跳转到企业主页
  380. if (Number(userinfo.has_attend_service_provider) !== 0) {
  381. location.href = this.siteUrl + "/company/" + userinfo.uid;
  382. return;
  383. }
  384. location.href = this.siteUrl + "/otherpage/companyComplete";
  385. },
  386. /** 移动端下拉刷新 **/
  387. onRefresh() {
  388. // 清空列表数据
  389. this.finished = false;
  390. this.loading = true;
  391. this.onLoad();
  392. },
  393. onLoad() {
  394. this.getList();
  395. },
  396. },
  397. };
  398. </script>
  399. <style scope lang="scss">
  400. @import "../../assets/css/kaifain/index.scss";
  401. </style>
  402. <style lang="scss">
  403. .van-dropdown-menu__title {
  404. color: #666;
  405. }
  406. .downapp {
  407. position: absolute;
  408. bottom: 0;
  409. z-index: 1000;
  410. width: 100vw;
  411. height: 50px;
  412. background: cornflowerblue;
  413. color: white;
  414. font-size: 15px;
  415. text-align: center;
  416. line-height: 50px;
  417. }
  418. </style>