diff --git a/assets/radar-rules.js b/assets/radar-rules.js
index 2edac4ae1..aa23064a1 100644
--- a/assets/radar-rules.js
+++ b/assets/radar-rules.js
@@ -801,4 +801,21 @@
},
],
},
+
+ 'yuancheng.work': {
+ _name: '远程.work',
+ '.': [
+ {
+ title: '招聘信息',
+ docs: 'https://docs.rsshub.app/other.html#yuan-cheng-work',
+ source: '/:caty',
+ target: (params, url) => {
+ if (!url) {
+ return '/remote-work';
+ }
+ return '/remote-work/' + /\w+-(\w+)-\w+/.exec(url)[1];
+ },
+ },
+ ],
+ },
});
diff --git a/docs/en/other.md b/docs/en/other.md
index 055deaf0f..e691ab0b8 100644
--- a/docs/en/other.md
+++ b/docs/en/other.md
@@ -66,3 +66,15 @@ EZTV provides an official RSS feed of all torrents: https://eztv.ag/ezrss.xml
### Hermes UK
+
+## Remote.work
+
+### Remote.work Job Information
+
+
+
+| All Jobs | Development | Design | Operation | Product | Other | Marketing | Sales |
+| :------: | :---------: | :----: | :-------: | :-----: | :---: | :-------: | :---: |
+| all | development | design | operation | product | other | marketing | sales |
+
+
diff --git a/docs/other.md b/docs/other.md
index 92f3b5120..ce3d3cf1f 100644
--- a/docs/other.md
+++ b/docs/other.md
@@ -420,6 +420,18 @@ type 为 all 时,category 参数不支持 cost 和 free
+## 远程.work
+
+### 远程.work 招聘信息
+
+
+
+| 所有职位 | 技术 | 设计 | 运营 | 产品 | 其他 | 市场 | 销售 |
+| :------: | :---------: | :----: | :-------: | :-----: | :---: | :-------: | :---: |
+| all | development | design | operation | product | other | marketing | sales |
+
+
+
## 正版中国
### 分类列表
diff --git a/lib/router.js b/lib/router.js
index ff63d0f74..b58962100 100644
--- a/lib/router.js
+++ b/lib/router.js
@@ -1988,4 +1988,7 @@ router.get('/fanfou/favorites/:uid', require('./routes/fanfou/favorites'));
router.get('/fanfou/trends', require('./routes/fanfou/trends'));
router.get('/fanfou/public_timeline/:keyword', require('./routes/fanfou/public_timeline'));
+// Remote Work
+router.get('/remote-work/:caty?', require('./routes/remote-work/index'));
+
module.exports = router;
diff --git a/lib/routes/remote-work/index.js b/lib/routes/remote-work/index.js
new file mode 100644
index 000000000..973ca4711
--- /dev/null
+++ b/lib/routes/remote-work/index.js
@@ -0,0 +1,91 @@
+const url = require('url');
+const got = require('@/utils/got');
+const cheerio = require('cheerio');
+
+const root_url = 'https://yuancheng.work/';
+
+const config = {
+ all: {
+ link: '/',
+ title: 'Remote Work|远程工作',
+ },
+ development: {
+ link: '/remote-development-jobs',
+ title: 'Remote Work-Development|远程工作-技术',
+ },
+ design: {
+ link: '/remote-design-jobs',
+ title: 'Remote Work-Design|远程工作-设计',
+ },
+ operation: {
+ link: '/remote-operation-jobs',
+ title: 'Remote Work-Operation|远程工作-运营',
+ },
+ product: {
+ link: '/remote-product-jobs',
+ title: 'Remote Work-Product|远程工作-产品',
+ },
+ other: {
+ link: '/remote-other-jobs',
+ title: 'Remote Work-Other|远程工作-其他',
+ },
+ marketing: {
+ link: '/remote-marketing-jobs',
+ title: 'Remote Work-Marketing|远程工作-市场',
+ },
+ sales: {
+ link: '/remote-sales-jobs',
+ title: 'Remote Work-Sales|远程工作-销售',
+ },
+};
+
+module.exports = async (ctx) => {
+ const cfg = config[ctx.params.caty || 'all'];
+ if (!cfg) {
+ throw Error('Bad category');
+ }
+
+ const current_url = url.resolve(root_url, cfg.link);
+ const response = await got({
+ method: 'get',
+ url: current_url,
+ });
+
+ const $ = cheerio.load(response.data);
+ const list = $('div.list-group div.job')
+ .slice(0, 10)
+ .map((_, item) => {
+ item = $(item);
+ const a = item.find('a.job-title');
+ let title = a.attr('title');
+ item.find('div.job-meta span.job-meta-value').each((_, tag) => {
+ title += '|' + $(tag).text();
+ });
+ return {
+ title: title,
+ link: a.attr('href'),
+ pubDate: new Date(item.find('div.job-foot div.job-date').attr('date') + ' GMT+8').toUTCString(),
+ };
+ })
+ .get();
+
+ const items = await Promise.all(
+ list.map(
+ async (item) =>
+ await ctx.cache.tryGet('remote-work' + item.link, async () => {
+ const res = await got({ method: 'get', url: url.resolve(root_url, item.link) });
+ const content = cheerio.load(res.data);
+ item.description = content('div.container div.main div.job-section')
+ .first()
+ .html();
+ return item;
+ })
+ )
+ );
+
+ ctx.state.data = {
+ title: cfg.title,
+ link: current_url,
+ item: items,
+ };
+};