花半小时用豆包 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 都是免费的🤣,这个项目的目的只是测试搭建难度,希望这个想法对你有帮助。
划线
评论
复制
发布于: 刚刚阅读数: 4
豆包MarsCode
关注
还未添加个人签名 2024-08-27 加入
用 AI 激发创造









评论