diff --git a/.autod.conf.js b/.autod.conf.js new file mode 100644 index 0000000..8c53939 --- /dev/null +++ b/.autod.conf.js @@ -0,0 +1,29 @@ +'use strict'; + +module.exports = { + write: true, + prefix: '^', + plugin: 'autod-egg', + test: [ + 'test', + 'benchmark', + ], + dep: [ + 'egg', + 'egg-scripts', + ], + devdep: [ + 'egg-ci', + 'egg-bin', + 'egg-mock', + 'autod', + 'autod-egg', + 'eslint', + 'eslint-config-egg', + ], + exclude: [ + './test/fixtures', + './dist', + ], +}; + diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..4ebc8ae --- /dev/null +++ b/.eslintignore @@ -0,0 +1 @@ +coverage diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 0000000..f304bdd --- /dev/null +++ b/.eslintrc @@ -0,0 +1,4 @@ +{ + "extends": "eslint-config-egg", + "root": true +} diff --git a/.github/workflows/nodejs.yml b/.github/workflows/nodejs.yml new file mode 100644 index 0000000..9a4cb4d --- /dev/null +++ b/.github/workflows/nodejs.yml @@ -0,0 +1,46 @@ +# This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node +# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions + +name: Node.js CI + +on: + push: + branches: + - main + - master + pull_request: + branches: + - main + - master + schedule: + - cron: '0 2 * * *' + +jobs: + build: + runs-on: ${{ matrix.os }} + + strategy: + fail-fast: false + matrix: + node-version: [16] + os: [ubuntu-latest, windows-latest, macos-latest] + + steps: + - name: Checkout Git Source + uses: actions/checkout@v2 + + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v1 + with: + node-version: ${{ matrix.node-version }} + + - name: Install Dependencies + run: npm i + + - name: Continuous Integration + run: npm run ci + + - name: Code Coverage + uses: codecov/codecov-action@v1 + with: + token: ${{ secrets.CODECOV_TOKEN }} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d1f5b60 --- /dev/null +++ b/.gitignore @@ -0,0 +1,17 @@ +logs/ +npm-debug.log +yarn-error.log +node_modules/ +package-lock.json +yarn.lock +coverage/ +.idea/ +run/ +.DS_Store +*.sw* +*.un~ +typings/ +.nyc_output/ +database/config.json +config/config.local.js +config/config.prod.js diff --git a/.sequelizerc b/.sequelizerc new file mode 100644 index 0000000..60e09c5 --- /dev/null +++ b/.sequelizerc @@ -0,0 +1,9 @@ +"use strict"; + +const path = require("path"); + +module.exports = { + config: path.join(__dirname, "database/config.json"), + "migrations-path": path.join(__dirname, "database/migrations"), + "seeders-path": path.join(__dirname, "database/seeders"), +}; diff --git a/README.md b/README.md new file mode 100644 index 0000000..9124e73 --- /dev/null +++ b/README.md @@ -0,0 +1,68 @@ +# 用于小程序后端的简单应用(eggjs开发) + + + +## 数据库连接 + +/config/config.local.js +```js +"use strict"; + +exports.sequelize = { + dialect: "mysql", + host: "0.0.0.0", + port: 3306, + database: "name", + username: "user", + password: "password", +}; +``` + +/config/config.prod.js +```js +"use strict"; + +exports.sequelize = { + dialect: "mysql", + host: "0.0.0.0", + port: 3306, + database: "name", + username: "user", + password: "password", +}; +``` + +/database/cofig.json + +`用于migration连接数据库` +```json +{ + "development": { + "dialect": "mysql", + "host": "0.0.0.0", + "port": 3306, + "database": "name", + "username": "user", + "password": "password" + } +} +``` + + +### Development + +```bash +$ npm i +$ npm run dev +$ open http://localhost:7001/ +``` + +### Deploy + +```bash +$ npm start +$ npm stop +``` + + +[egg]: https://eggjs.org \ No newline at end of file diff --git a/app/controller/eps.js b/app/controller/eps.js new file mode 100644 index 0000000..73bed52 --- /dev/null +++ b/app/controller/eps.js @@ -0,0 +1,28 @@ +"use strict"; + +const Controller = require("egg").Controller; + +function toInt(str) { + if (typeof str === "number") return str; + if (!str) return str; + return parseInt(str, 10) || 0; +} + +class EpController extends Controller { + async index() { + const ctx = this.ctx; + const query = { + limit: toInt(ctx.query.limit), + offset: toInt(ctx.query.offset), + }; + ctx.body = await ctx.model.Ep.findAll(query); + } + + async newEps() { + const ctx = this.ctx; + + ctx.body = await ctx.model.NewEp.findAll({ limit: 1 }); + } +} + +module.exports = EpController; diff --git a/app/controller/home.js b/app/controller/home.js new file mode 100644 index 0000000..e254db3 --- /dev/null +++ b/app/controller/home.js @@ -0,0 +1,12 @@ +"use strict"; + +const Controller = require("egg").Controller; + +class HomeController extends Controller { + async index() { + const { ctx } = this; + ctx.body = "hi there"; + } +} + +module.exports = HomeController; diff --git a/app/controller/tracks.js b/app/controller/tracks.js new file mode 100644 index 0000000..bf07746 --- /dev/null +++ b/app/controller/tracks.js @@ -0,0 +1,30 @@ +"use strict"; + +const Controller = require("egg").Controller; + +function toInt(str) { + if (typeof str === "number") return str; + if (!str) return str; + return parseInt(str, 10) || 0; +} + +class TrackController extends Controller { + async show() { + const ctx = this.ctx; + const { id } = this.ctx.params; + const { limit = 20, current = 1 } = this.ctx.query; + const _limit = toInt(limit); + + // 页数从1开始 + const _current = toInt(current); + const offset = (_current - 1) * _limit; + + ctx.body = await ctx.model.Track.findAndCountAll({ + where: { ep_Id: id }, + limit: _limit, + offset, + }); + } +} + +module.exports = TrackController; diff --git a/app/model/ep.js b/app/model/ep.js new file mode 100644 index 0000000..b65c286 --- /dev/null +++ b/app/model/ep.js @@ -0,0 +1,21 @@ +"use strict"; + +module.exports = (app) => { + const { STRING, INTEGER, DATE } = app.Sequelize; + + const Ep = app.model.define("ep", { + id: { + type: INTEGER, + primaryKey: true, + autoIncrement: true, + }, + _id: { type: STRING, field: "_id" }, + name: STRING(250), + img: STRING(250), + sort: INTEGER, + created_at: DATE, + updated_at: DATE, + }); + + return Ep; +}; diff --git a/app/model/newEp.js b/app/model/newEp.js new file mode 100644 index 0000000..19f89db --- /dev/null +++ b/app/model/newEp.js @@ -0,0 +1,19 @@ +"use strict"; + +module.exports = (app) => { + const { STRING, DATE, INTEGER, BOOLEAN } = app.Sequelize; + + const NewEp = app.model.define("newEp", { + id: { + type: INTEGER, + primaryKey: true, + autoIncrement: true, + }, + hideAudio: BOOLEAN, + newEpIds: STRING(300), + createdAt: DATE, + updatedAt: DATE, + }); + + return NewEp; +}; diff --git a/app/model/track.js b/app/model/track.js new file mode 100644 index 0000000..7d5aee7 --- /dev/null +++ b/app/model/track.js @@ -0,0 +1,23 @@ +"use strict"; + +module.exports = (app) => { + const { STRING, INTEGER, DATE } = app.Sequelize; + + const Track = app.model.define("track", { + id: { + type: INTEGER, + primaryKey: true, + autoIncrement: true, + }, + _id: { type: STRING, field: "_id" }, + title: STRING(250), + epId: STRING(250), + length: STRING(250), + src: STRING(250), + sort: INTEGER, + created_at: DATE, + updated_at: DATE, + }); + + return Track; +}; diff --git a/app/router.js b/app/router.js new file mode 100644 index 0000000..e322349 --- /dev/null +++ b/app/router.js @@ -0,0 +1,14 @@ +"use strict"; + +/** + * @param {Egg.Application} app - egg application + */ +module.exports = (app) => { + const { router, controller } = app; + router.get("/", controller.home.index); + + router.get("/eps", controller.eps.index); + router.get("/newEps", controller.eps.newEps); + + router.get("/tracks/:id", controller.tracks.show); +}; diff --git a/config/config.default.js b/config/config.default.js new file mode 100644 index 0000000..892e96a --- /dev/null +++ b/config/config.default.js @@ -0,0 +1,30 @@ +/* eslint valid-jsdoc: "off" */ + +"use strict"; + +/** + * @param {Egg.EggAppInfo} appInfo app info + */ +module.exports = (appInfo) => { + /** + * built-in config + * @type {Egg.EggAppConfig} + **/ + const config = {}; + + // use for cookie sign key, should change to your own and keep security + config.keys = appInfo.name + "_1663737137179_1189"; + + // add your middleware config here + config.middleware = []; + + // add your user config here + const userConfig = { + // myAppName: 'egg', + }; + + return { + ...config, + ...userConfig, + }; +}; diff --git a/config/plugin.js b/config/plugin.js new file mode 100644 index 0000000..b6cffeb --- /dev/null +++ b/config/plugin.js @@ -0,0 +1,7 @@ +"use strict"; + +/** @type Egg.EggPlugin */ +exports.sequelize = { + enable: true, + package: "egg-sequelize", +}; diff --git a/database/migrations/20220921074526-init-eps.js b/database/migrations/20220921074526-init-eps.js new file mode 100644 index 0000000..169d153 --- /dev/null +++ b/database/migrations/20220921074526-init-eps.js @@ -0,0 +1,20 @@ +"use strict"; + +module.exports = { + async up(queryInterface, Sequelize) { + const { INTEGER, DATE, STRING } = Sequelize; + await queryInterface.createTable("eps", { + id: { type: INTEGER, primaryKey: true, autoIncrement: true }, + _id: STRING(250), + name: STRING(250), + img: STRING(250), + sort: INTEGER, + created_at: DATE, + updated_at: DATE, + }); + }, + + async down(queryInterface, Sequelize) { + await queryInterface.dropTable("eps"); + }, +}; diff --git a/database/migrations/20220922062355-init-new-eps.js b/database/migrations/20220922062355-init-new-eps.js new file mode 100644 index 0000000..802b9ec --- /dev/null +++ b/database/migrations/20220922062355-init-new-eps.js @@ -0,0 +1,18 @@ +"use strict"; + +module.exports = { + async up(queryInterface, Sequelize) { + const { INTEGER, DATE, STRING, BOOLEAN } = Sequelize; + await queryInterface.createTable("new_eps", { + id: { type: INTEGER, primaryKey: true, autoIncrement: true }, + hide_Audio: BOOLEAN(), + new_ep_ids: STRING(300), + created_at: DATE, + updated_at: DATE, + }); + }, + + async down(queryInterface, Sequelize) { + await queryInterface.dropTable("new_eps"); + }, +}; diff --git a/database/migrations/20220922071843-init-tracks.js b/database/migrations/20220922071843-init-tracks.js new file mode 100644 index 0000000..31a1f98 --- /dev/null +++ b/database/migrations/20220922071843-init-tracks.js @@ -0,0 +1,22 @@ +"use strict"; + +module.exports = { + async up(queryInterface, Sequelize) { + const { INTEGER, DATE, STRING } = Sequelize; + await queryInterface.createTable("tracks", { + id: { type: INTEGER, primaryKey: true, autoIncrement: true }, + _id: STRING(300), + ep_id: STRING(300), + length: STRING(250), + src: STRING(250), + title: STRING(250), + sort: INTEGER, + created_at: DATE, + updated_at: DATE, + }); + }, + + async down(queryInterface, Sequelize) { + await queryInterface.dropTable("tracks"); + }, +}; diff --git a/jsconfig.json b/jsconfig.json new file mode 100644 index 0000000..1bbed3f --- /dev/null +++ b/jsconfig.json @@ -0,0 +1,5 @@ +{ + "include": [ + "**/*" + ] +} \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..75d98fd --- /dev/null +++ b/package.json @@ -0,0 +1,50 @@ +{ + "name": "audio-book-backend", + "version": "1.0.0", + "description": "用于小程序后端的简单应用(eggjs开发)", + "private": true, + "egg": { + "declarations": true + }, + "dependencies": { + "egg": "^2", + "egg-scripts": "^2", + "egg-sequelize": "^6.0.0", + "mysql2": "^2.3.3" + }, + "devDependencies": { + "autod": "^3", + "autod-egg": "^1", + "egg-bin": "^4", + "egg-ci": "^2", + "egg-mock": "^4", + "eslint": "^8", + "eslint-config-egg": "^12", + "sequelize-cli": "^6.4.1" + }, + "engines": { + "node": ">=16.0.0" + }, + "scripts": { + "start": "egg-scripts start --daemon --title=egg-server-egg", + "stop": "egg-scripts stop --title=egg-server-egg", + "dev": "egg-bin dev", + "debug": "egg-bin debug", + "test": "npm run lint -- --fix && npm run test-local", + "test-local": "egg-bin test", + "cov": "egg-bin cov", + "lint": "eslint .", + "ci": "npm run lint && npm run cov", + "autod": "autod" + }, + "ci": { + "version": "16", + "type": "github" + }, + "repository": { + "type": "git", + "url": "" + }, + "author": "", + "license": "MIT" +} diff --git a/test/app/controller/home.test.js b/test/app/controller/home.test.js new file mode 100644 index 0000000..a4f0fc9 --- /dev/null +++ b/test/app/controller/home.test.js @@ -0,0 +1,20 @@ +'use strict'; + +const { app, assert } = require('egg-mock/bootstrap'); + +describe('test/app/controller/home.test.js', () => { + it('should assert', async () => { + const pkg = require('../../../package.json'); + assert(app.config.keys.startsWith(pkg.name)); + + // const ctx = app.mockContext({}); + // yield ctx.service.xx(); + }); + + it('should GET /', async () => { + return app.httpRequest() + .get('/') + .expect('hi, egg') + .expect(200); + }); +});