写点什么

花半小时用豆包 Marscode 和 Supabase 免费部署了一个远程工作的导航站

作者:豆包MarsCode
  • 2024-09-24
    北京
  • 本文字数:3108 字

    阅读完需:约 10 分钟

以下是「 豆包 MarsCode 体验官」优秀文章,作者谦哥。


🚀 项目地址: remotejobs.justidea.cn/

🚀 项目截图:


数据处理

感谢开源项目:https://github.com/remoteintech/remote-jobs

网站信息获取:把项目里 md 文件里的网站列表抓取保存到 supabase 的数据库里(这一步可以在本地完成)

import fetch from 'node-fetch';import { createClient } from '@supabase/supabase-js';
const SUPABASE_URL = '';const SUPABASE_KEY = '';const supabase = createClient(SUPABASE_URL, SUPABASE_KEY);
async function fetchData() { const response = await fetch('https://raw.githubusercontent.com/remoteintech/remote-jobs/main/README.md'); const text = await response.text();
// 解析 README.md 内容,提取 name, website, region const jobs = parseJobs(text);
// 将数据存储到 Supabase for (const job of jobs) { await supabase .from('remote-jobs') .insert(job); }}
function parseJobs(mdText) { const lines = mdText.split('\n'); const jobs = []; lines.forEach(line => { // 例子:'[Bitovi](/company-profiles/bitovi.md) | https://bitovi.com/ | Worldwide' const match = line.match(/\[([^\]]+)\]\(([^)]+)\)\s*\|\s*(https?:\/\/[^\s|]+)\s*\|\s*(.+)/); if (match) { const [, name, ,website, region] = match; jobs.push({ name, website, region }); } }); return jobs;}fetchData();
复制代码

网站截图: 把上一步获取到的网址用 puppeteer 循环截图,最后上传到 supabase 的 storage 里

import puppeteer from 'puppeteer'import fs from 'fs'import { createClient } from '@supabase/supabase-js'
const SUPABASE_URL =''const SUPABASE_KEY =''
const supabase = createClient(SUPABASE_URL, SUPABASE_KEY)
async function captureScreenshots() { const { data: jobs, error } = await supabase .from('remote-jobs') .select('id, website')
if (error) { console.error('Error fetching jobs:', error) return } for (const job of jobs) { const { id, website } = job const screenshotPath = `screenshots/${id}.png`
// 生成截图 try { await generateScreenshot(website, screenshotPath) // 上传截图到 Supabase 存储 const { data, error } = await supabase.storage .from('remote-jobs') .upload(screenshotPath, fs.readFileSync(screenshotPath))
// 更新数据库中的 thumb 字段 if (!error) { const thumbUrl = data.path await supabase .from('remote-jobs') .update({ thumb: thumbUrl }) .eq('id', id) console.log(`Screenshot uploaded for job ${id}`) } } catch (error) { console.log(error) } }}
async function generateScreenshot(url, path) { const browser = await puppeteer.launch() const page = await browser.newPage() try { await page.goto(url, { waitUntil: 'networkidle2', timeout: 90000 }) await page.screenshot({ path }) } catch (error) { console.error('Error generating screenshot:', error) } finally { await browser.close() }}
captureScreenshots()
复制代码


Supabase 里的数据


豆包 Marscode

一定要选用 marscode.com 来开发项目,不然没有部署这个选项


新建项目


安装依赖

pnpm add tailwindcss postcss autoprefixerpnpm add @supabase/supabase-js
复制代码

配置 tailwind.config.js

/** @type {import('tailwindcss').Config} */export default {  content: [    './index.html',    './src/**/*.{vue,js,ts,jsx,tsx}'  ],  theme: {    extend: {},  },  plugins: [],}
复制代码

Vue 组件 JobList.vue

<template>    <div class="p-6">      <input         v-model="search"         placeholder="搜索公司名称"         class="border p-2 mb-4 w-full"      />      <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6">        <div v-for="job in paginatedJobs" :key="job.id" class="p-4 border rounded-lg shadow-md transition-transform transform hover:scale-105">          <h3 class="text-xl font-semibold">{{ job.name }}</h3>          <a :href="job.website" target="_blank" class="text-blue-500 text-xs">{{ job.website }}</a>          <p class="text-sm text-gray-500">{{ job.region }}</p>          <img v-if="job.thumb" :src="thumbUrl(job.thumb)" alt="thumbnail" class="mt-2 rounded-lg p-2" />        </div>      </div>      <div class="flex justify-between mt-4">        <button           @click="prevPage"           :disabled="currentPage === 1"           class="bg-blue-500 text-white px-4 py-2 rounded disabled:opacity-50">          上一页        </button>        <button           @click="nextPage"           :disabled="currentPage === totalPages"           class="bg-blue-500 text-white px-4 py-2 rounded disabled:opacity-50">          下一页        </button>      </div>    </div>  </template>    <script>  export default {    data() {      return {        jobs: [],        search: '',        currentPage: 1,        jobsPerPage: 20      };    },    computed: {      filteredJobs() {        return this.jobs.filter(job =>           job.name.includes(this.search) ||           job.region.includes(this.search)        );      },      totalPages() {        return Math.ceil(this.filteredJobs.length / this.jobsPerPage);      },      paginatedJobs() {        const start = (this.currentPage - 1) * this.jobsPerPage;        const end = start + this.jobsPerPage;        return this.filteredJobs.slice(start, end);      }    },    async mounted() {      const { data: jobs, error } = await this.$supabase        .from('remote-jobs')        .select('*');      if (!error) this.jobs = jobs;    },    methods: {      thumbUrl(path) {        const SUPABASE_URL = '';        //spuabase 的 storage 地址        return `${SUPABASE_URL}/storage/v1/object/public/remote-jobs/${path}`;      },      nextPage() {        if (this.currentPage < this.totalPages) {          this.currentPage++;        }      },      prevPage() {        if (this.currentPage > 1) {          this.currentPage--;        }      }    }  };  </script>    <style scoped>  input:focus {    outline: none;    border-color: #4299e1;    box-shadow: 0 0 0 3px rgba(66, 153, 225, 0.5);  }  </style>
复制代码

部署

IDE 的这两个位置都可以部署项目,对于 vue 项目,系统会自动构建打包上传


部署过程


最后绑定自己的域名就可以了,没有并发限制,并且会自动部署 ssl


最后

IDE 可以后台直接用 AI 生成大部分的业务代码,也可以直接提问,大大缩短的一个项目上线的时间。

最重要的是豆包Marscode 和 supabase 都是免费的🤣,这个项目的目的只是测试搭建难度,希望这个想法对你有帮助。

用户头像

还未添加个人签名 2024-08-27 加入

用 AI 激发创造

评论

发布
暂无评论
花半小时用豆包Marscode 和 Supabase免费部署了一个远程工作的导航站_人工智能_豆包MarsCode_InfoQ写作社区