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

news2024/10/10 6:43:48

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

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

🚀 项目截图:

file

数据处理

感谢开源项目: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 里的数据

file

豆包Marscode

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

新建项目
file

安装依赖

pnpm add tailwindcss postcss autoprefixer
pnpm 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 项目,系统会自动构建打包上传
file

部署过程
file

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

最后

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

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

本文由博客一文多发平台 OpenWrite 发布!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2195225.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MyBatis 操作数据库入门

目录 前言 1.创建springboot⼯程 2.数据准备 3.配置Mybatis数据库连接信息 4.编写SQL语句&#xff0c;进行测试 前言 什么是MyBatis? MyBatis是⼀款优秀的 持久层 框架&#xff0c;⽤于简化JDBC的开发 Mybatis操作数据库的入门步骤&#xff1a; 1.创建springboot⼯程 2.数…

SOMEIP_ETS_171: SD_Unicast_FindService

测试目的&#xff1a; 验证DUT能够响应Tester发送的多个单播FindService消息&#xff0c;并至少回复一个单播OfferService消息。 描述 本测试用例旨在确保DUT能够正确处理单播FindService消息请求&#xff0c;并为请求的服务提供至少一个单播OfferService消息作为响应。 测…

SpringBootWeb快速入门!详解如何创建一个简单的SpringBoot项目?

在现代Web开发中&#xff0c;SpringBoot以其简化的配置和快速的开发效率而受到广大开发者的青睐。本篇文章将带领你从零开始&#xff0c;搭建一个基于SpringBoot的简单Web应用~ 一、前提准备 想要创建一个SpringBoot项目&#xff0c;需要做如下准备&#xff1a; idea集成开发…

亲身经历告诉你该如何自学编程

我2016年硕士毕业后&#xff0c;从一个纯机械学生开始转行做软件开发&#xff0c;其中少不了要自学编程&#xff0c;这其中经历的到现在看来还历历在目。 我曾经写过一些关于我转行做软件开发经历的文章&#xff0c;如果你感兴趣&#xff0c;可以点击这里的链接&#xff08;我…

国庆期间的问题,如何在老家访问杭州办公室的网络呢

背景&#xff1a;国庆期间的问题&#xff0c;如何在老家访问杭州办公室的网络呢 实现方案&#xff1a;异地组网 实现语言&#xff1a;Java 环境&#xff1a;三个网络&#xff0c;一台拥有公网IP的服务器、一台杭州本地机房内服务器、你老家所在网络中的一台电脑&#xff08;…

【Git】TortoiseGitPlink提示输入密码解决方法

问题 克隆仓库&#xff0c;TortoiseGitPlink提示输入密码 解法 1、打开TortoiseGit 下的puttygen工具 位置&#xff1a;C:\Program Files\TortoiseGit\bin\ 2、点击【Load】按钮&#xff0c;载入 C:\Users\Administrator\.ssh\ 文件夹下的id_rsa文件。 3、点击save private …

Python数据分析-远程办公与心理健康分析

一、研究背景 随着信息技术的飞速发展和全球化的推进&#xff0c;远程工作&#xff08;Remote Work&#xff09;成为越来越多企业和员工的选择。尤其是在2020年新冠疫情&#xff08;COVID-19&#xff09;爆发后&#xff0c;全球范围内的封锁措施使得远程工作模式迅速普及。根据…

Mysql数据库--JDBC编程

文章目录 1.JDBC编程基础2.驱动程序下载3.新建项目3.1导入java包3.2转换为库 4.开始创作4.1准备数据库4.2创建DataSource4.3和数据库建立连接4.4构造sql&#xff0c;准备发送到服务器4.5发送sql&#xff0c;执行sql4.6释放系统资源4.7自行输入的设置4.8插入数据完整源代码4.9查…

JavaEE之多线程进阶-面试问题

一.常见的锁策略 锁策略不是指某一个具体的锁&#xff0c;所有的锁都可以往这些锁策略中套 1.悲观锁与乐观锁 预测所冲突的概率是否高&#xff0c;悲观锁为预测锁冲突的概率较高&#xff0c;乐观锁为预测锁冲突的概率更低。 2.重量级锁和轻量级锁 从加锁的开销角度判断&am…

OJ在线评测系统 微服务 用分布式消息队列 RabbitMQ 解耦判题服务和题目服务 手搓交换机和队列 实现项目异步化

消息队列解耦 项目异步化 分布式消息队列 分布式消息队列是一种用于异步通信的系统&#xff0c;它允许不同的应用程序或服务之间传递消息。消息队列的核心理念是将消息存储在一个队列中&#xff0c;发送方可以将消息发送到队列&#xff0c;而接收方则可以在适当的时候从队列中…

Vue2电商平台(六)、注册登录,请求头配置token,token持久化存储;导航守卫(重点);组件内守卫、路由独享守卫

文章目录 一、注册1. 获取注册验证码2. 完成注册用户 二、登录1. 登录获取token2. Home首页携带token获取用户数据3. 持久化存储token4. 退出登录5. 导航守卫 (牛)6. 路由独享守卫beforeEnter7. 组件内守卫&#xff08;用的很少&#xff09; 一、注册 1. 获取注册验证码 本系…

基于SSM+小程序的线上教育商城管理系统(教育2)

&#x1f449;文末查看项目功能视频演示获取源码sql脚本视频导入教程视频 1、项目介绍 微信小程序线上教育商城有管理员&#xff0c;教师&#xff0c;学生三个角色。 1、管理员功能有个人中心&#xff0c;学生管理&#xff0c;教师管理&#xff0c;类型管理&#xff0c;课程…

diffusion model(1.1) 为什么前向传播和反向传播都遵循高斯分布?

DDPM的引用[53]为Deep Unsupervised Learning using Nonequilibrium Thermodynamics&#xff0c;它证明了当 β t \beta_t βt​ 较小时&#xff0c;前向传播和反向传播前向分布和后向分布拥有同样的分布形式。 所引论文的内容如下&#xff0c; 后者又引用了另一篇论文(Fell…

分层解耦-04.IOCDI-IOC详解

一.Bean的声明 springboot为了更好地标识web应用开发中bean对象到底归属于哪一层&#xff0c;在Component注解的基础上又衍生出了三个注解Controller、Service和Repository。分别应用于Controller层&#xff0c;Service层和Dao层。推荐使用衍生注解&#xff0c;当无法判断该be…

Java-数据结构-反射、枚举 |ू・ω・` )

目录 ❄️一、反射&#xff1a; 1、定义&#xff1a; 2、用途&#xff1a; 3、反射相关的类&#xff1a; 4、Class类&#xff1a; 1、Class类中相关的方法&#xff1a; 5、Class反射实例&#xff1a; 1、获得Class对象的三种方式&#xff1a; 2、反射的使用&#xff1a; 6、反…

网络基础擅长组建乐队

让我们荡起双桨 来说说网络吧 现有计算机要进行协作&#xff0c;网络的产生是必然的 局域网&#xff1a;计算机数量更多了, 通过交换机和路由器连接在一起 广域网&#xff1a;将远隔千里的计算机都连在一起 交换机路由器等设备就应运而生 计算机是人的工具&#xff0c;人要协…

layernorm笔记

文章目录 layer norm的解释二维三维 batchnorm和layernorm主要的区别为什么要在序列转录模型中使用layer norm&#xff1f; layer norm的解释 二维 红色为batchnorm&#xff0c;蓝色为layer norm batchnorm对每一个特征算均值和方差 layer norm对每一个批次算均值和方差 三…

窗口系统与图形绘制接口

个人博客:Sekyoro的博客小屋 个人网站:Proanimer的个人网站 当我们想要进行底层图形应用(GUI)开发时,往往需要用到窗口系统和图形库,这里简单介绍一下 视窗系统(window system)与通信协议 下面内容主要针对Unix-like操作系统 视窗系统是以使用视窗作为主要特征之一的图形用…

【含开题报告+文档+PPT+源码】基于SSM + Vue的养老院管理系统【包运行成功】

开题报告 随着社会的发展和经济的进步&#xff0c;人口老龄化问题逐渐凸显。统计数据显示&#xff0c;全球范围内的老龄人口比例正在逐年上升&#xff0c;养老需求也随之增长。养老院作为提供专业养老服务的机构&#xff0c;承担着照料老人、提供医疗保健和社交活动等责任。传…