├── src
├── app.d.ts
├── uni_modules
│ ├── menu-drawer
│ │ ├── changelog.md
│ │ ├── readme.md
│ │ └── package.json
│ ├── uni-transition
│ │ ├── changelog.md
│ │ ├── package.json
│ │ └── readme.md
│ ├── robin-editor
│ │ ├── changelog.md
│ │ ├── components
│ │ │ ├── robin-editor
│ │ │ │ └── editor-icon.ttf
│ │ │ └── robin-editor-header
│ │ │ │ └── robin-editor-header.vue
│ │ ├── package.json
│ │ └── readme.md
│ ├── uni-icons
│ │ ├── changelog.md
│ │ ├── components
│ │ │ └── uni-icons
│ │ │ │ └── uni.ttf
│ │ ├── readme.md
│ │ └── package.json
│ ├── uni-popup
│ │ ├── changelog.md
│ │ ├── components
│ │ │ ├── uni-popup
│ │ │ │ ├── share.js
│ │ │ │ ├── message.js
│ │ │ │ ├── popup.js
│ │ │ │ └── keypress.js
│ │ │ ├── uni-popup-dialog
│ │ │ │ └── keypress.js
│ │ │ └── uni-popup-message
│ │ │ │ └── uni-popup-message.vue
│ │ └── package.json
│ └── uni-search-bar
│ │ ├── changelog.md
│ │ ├── package.json
│ │ └── readme.md
├── static
│ ├── user
│ │ ├── qq.png
│ │ ├── auth.png
│ │ ├── card.png
│ │ ├── wechat.png
│ │ ├── helloworld.png
│ │ ├── topBackground.png
│ │ └── userBackground.png
│ ├── index
│ │ ├── user.png
│ │ ├── search.png
│ │ ├── indexFile.png
│ │ ├── indexNews.png
│ │ ├── indexDiscuss.png
│ │ └── indexBackground.png
│ ├── common
│ │ ├── back.png
│ │ └── notResult.png
│ └── question
│ │ ├── eyes.png
│ │ ├── quote.png
│ │ ├── explanationTop.png
│ │ ├── questionBookBackrgound.png
│ │ └── questionWriteBackrgound.png
├── main.js
├── App.vue
├── components
│ ├── i-uniapp
│ │ ├── css
│ │ │ └── style.components.scss
│ │ ├── i-form
│ │ │ └── i-form.vue
│ │ ├── i-icon
│ │ │ ├── readme.md
│ │ │ └── i-icon.vue
│ │ ├── i-input
│ │ │ └── i-input.vue
│ │ ├── i-field
│ │ │ └── i-field.vue
│ │ ├── i-navigation-bar
│ │ │ └── i-navigation-bar.vue
│ │ └── i-mask
│ │ │ └── i-mask.vue
│ └── common
│ │ └── commonFill.vue
├── util
│ ├── common.scss
│ ├── notLogin.ts
│ └── common.ts
├── shims-vue.d.ts
├── api
│ ├── questionArea.ts
│ ├── certificationApplyOrder.ts
│ ├── article.ts
│ ├── collect.ts
│ ├── search.ts
│ ├── common.ts
│ ├── user.ts
│ └── question.ts
├── pages
│ ├── common
│ │ ├── noRelease.vue
│ │ └── webview.vue
│ ├── question
│ │ └── index.vue
│ └── user
│ │ └── setPassword.vue
├── common
│ ├── request.ts
│ └── uni-ui.scss
└── manifest.json
├── .prettierignore
├── .husky
└── pre-commit
├── out
└── doc
│ └── db
│ ├── core
│ └── core.png
│ ├── pull
│ └── pull.png
│ ├── pushQuestion
│ └── pushQuestion.png
│ └── examineQuestion
│ └── examineQuestion.png
├── uniCloud-aliyun
├── cloudfunctions
│ ├── v1
│ │ ├── etsc.config.js
│ │ ├── nodemon.etsc.json
│ │ ├── proto
│ │ │ ├── search.ts
│ │ │ ├── questionTag.ts
│ │ │ ├── article.ts
│ │ │ ├── questionArea.ts
│ │ │ ├── openapi.ts
│ │ │ ├── questionExplanation.ts
│ │ │ ├── certificationApplyOrder.ts
│ │ │ ├── question.ts
│ │ │ └── user.ts
│ │ ├── nodemon.proto.json
│ │ ├── src
│ │ │ ├── router
│ │ │ │ ├── search.ts
│ │ │ │ ├── article.ts
│ │ │ │ ├── questionTag.ts
│ │ │ │ ├── questionArea.ts
│ │ │ │ ├── certificationApplyOrder.ts
│ │ │ │ ├── questionExplanation.ts
│ │ │ │ ├── question.ts
│ │ │ │ ├── openApi.ts
│ │ │ │ └── user.ts
│ │ │ ├── service
│ │ │ │ ├── search.ts
│ │ │ │ ├── article.ts
│ │ │ │ ├── questionArea.ts
│ │ │ │ ├── questionTag.ts
│ │ │ │ └── certificationApplyOrder.ts
│ │ │ └── controller
│ │ │ │ ├── search.ts
│ │ │ │ ├── article.ts
│ │ │ │ ├── questionTag.ts
│ │ │ │ ├── questionArea.ts
│ │ │ │ ├── openApi.ts
│ │ │ │ ├── questionExplanation.ts
│ │ │ │ ├── certificationApplyOrder.ts
│ │ │ │ └── question.ts
│ │ ├── tsconfig.json
│ │ ├── package-lock.json
│ │ ├── schemas
│ │ │ └── genSchemas.js
│ │ ├── filters
│ │ │ └── tokenFilter.js
│ │ └── package.json
│ ├── qq-robot
│ │ ├── package-lock.json
│ │ ├── src
│ │ │ ├── package
│ │ │ │ └── myqq
│ │ │ │ │ └── connection.ts
│ │ │ └── services
│ │ │ │ ├── group.ts
│ │ │ │ └── callback.ts
│ │ ├── nodemon.json
│ │ ├── qq-robot.param.json
│ │ ├── etsc.config.js
│ │ ├── package.json
│ │ └── index.js
│ ├── common
│ │ ├── uni-config-center
│ │ │ ├── changelog.md
│ │ │ ├── package.json
│ │ │ └── readme.md
│ │ ├── sword-recommend
│ │ │ ├── index.js
│ │ │ └── package.json
│ │ ├── form-data-utils
│ │ │ ├── index.js
│ │ │ ├── package.json
│ │ │ ├── parser.js
│ │ │ └── builder.js
│ │ ├── explain-cache
│ │ │ ├── package-lock.json
│ │ │ ├── package.json
│ │ │ └── index.js
│ │ ├── uni-id
│ │ │ ├── package-lock.json
│ │ │ └── package.json
│ │ ├── explain
│ │ │ ├── abstracts
│ │ │ │ ├── service.js
│ │ │ │ └── filter.js
│ │ │ ├── utils
│ │ │ │ ├── object.js
│ │ │ │ └── datetime.js
│ │ │ ├── index.js
│ │ │ ├── package.json
│ │ │ ├── program
│ │ │ │ └── middleware.js
│ │ │ └── LICENSE
│ │ ├── we-chat-api
│ │ │ ├── package.json
│ │ │ └── index.js
│ │ ├── uni-captcha
│ │ │ └── package.json
│ │ ├── tsbuffer-params-validate
│ │ │ ├── package.json
│ │ │ ├── index.js
│ │ │ └── package-lock.json
│ │ └── get-accesstoken
│ │ │ ├── package.json
│ │ │ ├── package-lock.json
│ │ │ └── index.js
│ ├── content-security
│ │ ├── content-security.param.json
│ │ ├── package.json
│ │ ├── package-lock.json
│ │ └── index.js
│ ├── pull
│ │ ├── package-lock.json
│ │ ├── readme.md
│ │ ├── package.json
│ │ ├── index.js
│ │ └── Dada-interview-answe.js
│ ├── dingtalk-robot
│ │ ├── dingtalk-robot.param.json
│ │ ├── package.json
│ │ ├── index.js
│ │ └── package-lock.json
│ ├── send-template-msg
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ └── index.js
│ ├── explain-cache-clear-timeout
│ │ ├── index.js
│ │ ├── package.json
│ │ └── package-lock.json
│ ├── day-satistics
│ │ ├── package.json
│ │ └── index.js
│ ├── open-api-reset-request-number
│ │ ├── package.json
│ │ └── index.js
│ ├── open-api
│ │ ├── openApi.param.json
│ │ └── package.json
│ ├── uni-analyse-searchhot
│ │ ├── package.json
│ │ └── index.js
│ └── uni-id-cf
│ │ ├── package.json
│ │ └── package-lock.json
└── database
│ ├── userCollect.schema.json
│ ├── opendb-search-hot.schema.json
│ ├── opendb-search-log.schema.json
│ ├── questionTag.schema.json
│ ├── questionArea.schema.json
│ ├── certificationApplyOrder.schema.json
│ ├── opendb-verify-codes.schema.json
│ ├── uni-id-log.schema.json
│ ├── openApi.schema.json
│ ├── uni-id-roles.schema.json
│ ├── uni-id-permissions.schema.json
│ ├── questionExplanation.schema.json
│ ├── question.schema.json
│ ├── article.schema.json
│ └── opendb-admin-menus.schema.json
├── vue.config.js
├── tsconfig.json
├── .eslintignore
├── doc
├── business
│ ├── pull.puml
│ ├── contentSecurity.puml
│ ├── examineQuestion.puml
│ ├── userBind.puml
│ └── pushQuestion.puml
└── db
│ └── microfunction.puml
├── .vscode
└── settings.json
├── .prettierrc
├── .gitignore
├── .editorconfig
├── .eslintrc.js
├── jest.config.js
├── postcss.config.js
├── .github
└── workflows
│ └── sync2gitee.yml
├── public
└── index.html
├── babel.config.js
└── manifest.json
/src/app.d.ts:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/uni_modules/menu-drawer/changelog.md:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | dist/
2 | node_modules
3 | *.log
--------------------------------------------------------------------------------
/src/uni_modules/menu-drawer/readme.md:
--------------------------------------------------------------------------------
1 | # menu-drawer
--------------------------------------------------------------------------------
/src/static/user/qq.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/swordjs/app/HEAD/src/static/user/qq.png
--------------------------------------------------------------------------------
/src/uni_modules/uni-transition/changelog.md:
--------------------------------------------------------------------------------
1 | ## 1.0.2(2021-02-05)
2 | - 调整为uni_modules目录规范
3 |
--------------------------------------------------------------------------------
/.husky/pre-commit:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | . "$(dirname "$0")/_/husky.sh"
3 |
4 | npm run lint-staged
5 |
--------------------------------------------------------------------------------
/out/doc/db/core/core.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/swordjs/app/HEAD/out/doc/db/core/core.png
--------------------------------------------------------------------------------
/out/doc/db/pull/pull.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/swordjs/app/HEAD/out/doc/db/pull/pull.png
--------------------------------------------------------------------------------
/src/static/index/user.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/swordjs/app/HEAD/src/static/index/user.png
--------------------------------------------------------------------------------
/src/static/user/auth.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/swordjs/app/HEAD/src/static/user/auth.png
--------------------------------------------------------------------------------
/src/static/user/card.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/swordjs/app/HEAD/src/static/user/card.png
--------------------------------------------------------------------------------
/src/static/common/back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/swordjs/app/HEAD/src/static/common/back.png
--------------------------------------------------------------------------------
/src/static/index/search.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/swordjs/app/HEAD/src/static/index/search.png
--------------------------------------------------------------------------------
/src/static/question/eyes.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/swordjs/app/HEAD/src/static/question/eyes.png
--------------------------------------------------------------------------------
/src/static/user/wechat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/swordjs/app/HEAD/src/static/user/wechat.png
--------------------------------------------------------------------------------
/src/uni_modules/robin-editor/changelog.md:
--------------------------------------------------------------------------------
1 | ## 2.0.0(2021-02-08)
2 | 迁移至uni_modules
3 | 迁移至uni_modules
--------------------------------------------------------------------------------
/src/static/index/indexFile.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/swordjs/app/HEAD/src/static/index/indexFile.png
--------------------------------------------------------------------------------
/src/static/index/indexNews.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/swordjs/app/HEAD/src/static/index/indexNews.png
--------------------------------------------------------------------------------
/src/static/question/quote.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/swordjs/app/HEAD/src/static/question/quote.png
--------------------------------------------------------------------------------
/src/static/user/helloworld.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/swordjs/app/HEAD/src/static/user/helloworld.png
--------------------------------------------------------------------------------
/src/main.js:
--------------------------------------------------------------------------------
1 | import { createApp } from 'vue';
2 | import App from './App.vue';
3 | createApp(App).mount();
4 |
--------------------------------------------------------------------------------
/src/static/common/notResult.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/swordjs/app/HEAD/src/static/common/notResult.png
--------------------------------------------------------------------------------
/src/static/index/indexDiscuss.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/swordjs/app/HEAD/src/static/index/indexDiscuss.png
--------------------------------------------------------------------------------
/src/static/user/topBackground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/swordjs/app/HEAD/src/static/user/topBackground.png
--------------------------------------------------------------------------------
/src/static/user/userBackground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/swordjs/app/HEAD/src/static/user/userBackground.png
--------------------------------------------------------------------------------
/src/static/index/indexBackground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/swordjs/app/HEAD/src/static/index/indexBackground.png
--------------------------------------------------------------------------------
/src/static/question/explanationTop.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/swordjs/app/HEAD/src/static/question/explanationTop.png
--------------------------------------------------------------------------------
/out/doc/db/pushQuestion/pushQuestion.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/swordjs/app/HEAD/out/doc/db/pushQuestion/pushQuestion.png
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/v1/etsc.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | esbuild: {
3 | minify: false
4 | }
5 | };
6 |
--------------------------------------------------------------------------------
/vue.config.js:
--------------------------------------------------------------------------------
1 | process.env.UNI_USING_VUE3 = true;
2 | process.env.UNI_USING_VUE3_OPTIONS_API = true;
3 | module.exports = {};
4 |
--------------------------------------------------------------------------------
/src/uni_modules/uni-icons/changelog.md:
--------------------------------------------------------------------------------
1 | ## 1.1.5(2021-05-12)
2 | - 新增 组件示例地址
3 | ## 1.1.4(2021-02-05)
4 | - 调整为uni_modules目录规范
5 |
--------------------------------------------------------------------------------
/out/doc/db/examineQuestion/examineQuestion.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/swordjs/app/HEAD/out/doc/db/examineQuestion/examineQuestion.png
--------------------------------------------------------------------------------
/src/static/question/questionBookBackrgound.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/swordjs/app/HEAD/src/static/question/questionBookBackrgound.png
--------------------------------------------------------------------------------
/src/static/question/questionWriteBackrgound.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/swordjs/app/HEAD/src/static/question/questionWriteBackrgound.png
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/qq-robot/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "qq-robot",
3 | "version": "1.0.0",
4 | "lockfileVersion": 1
5 | }
6 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/common/uni-config-center/changelog.md:
--------------------------------------------------------------------------------
1 | ## 0.0.2(2021-04-16)
2 | - 修改插件package信息
3 | ## 0.0.1(2021-03-15)
4 | - 初始化项目
5 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/qq-robot/src/package/myqq/connection.ts:
--------------------------------------------------------------------------------
1 | // export default class Connection {
2 | // static collection() {}
3 | // }
4 |
--------------------------------------------------------------------------------
/src/uni_modules/uni-icons/components/uni-icons/uni.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/swordjs/app/HEAD/src/uni_modules/uni-icons/components/uni-icons/uni.ttf
--------------------------------------------------------------------------------
/src/App.vue:
--------------------------------------------------------------------------------
1 |
8 |
9 |
11 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/qq-robot/nodemon.json:
--------------------------------------------------------------------------------
1 | {
2 | "watch": ["src"],
3 | "ext": "ts,js,json",
4 | "exec": "etsc",
5 | "legacyWatch": true
6 | }
7 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/v1/nodemon.etsc.json:
--------------------------------------------------------------------------------
1 | {
2 | "watch": ["src"],
3 | "ext": "ts,js,json",
4 | "exec": "etsc",
5 | "legacyWatch": true
6 | }
7 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/v1/proto/search.ts:
--------------------------------------------------------------------------------
1 | export interface AddSeachLog {
2 | content: string;
3 | device_id?: string;
4 | user_id?: string;
5 | }
6 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/qq-robot/qq-robot.param.json:
--------------------------------------------------------------------------------
1 | {
2 | "service": "callback",
3 | "action": "main",
4 | "method": "POST",
5 | "data": {}
6 | }
7 |
--------------------------------------------------------------------------------
/src/uni_modules/robin-editor/components/robin-editor/editor-icon.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/swordjs/app/HEAD/src/uni_modules/robin-editor/components/robin-editor/editor-icon.ttf
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/v1/nodemon.proto.json:
--------------------------------------------------------------------------------
1 | {
2 | "watch": ["proto"],
3 | "ext": "ts",
4 | "exec": "node schemas/genSchemas.js",
5 | "legacyWatch": true
6 | }
7 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/common/sword-recommend/index.js:
--------------------------------------------------------------------------------
1 | module.exports = function (e) {
2 | // 公用模块用法请参考 https://uniapp.dcloud.io/uniCloud/cf-common
3 | return e;
4 | };
5 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "lib": ["es2015", "es2017"],
4 | "typeRoots": ["./typings", "./node_modules/@types", "node_modules/sword-typescript-type-core"]
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/common/form-data-utils/index.js:
--------------------------------------------------------------------------------
1 | const FormData = require('./builder');
2 | const formParser = require('./parser');
3 | module.exports = {
4 | FormData,
5 | formParser
6 | };
7 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | src/uni_modules/**/*
2 | # explain框架核心模块
3 | uniCloud-aliyun/cloudfunctions/common/explain/**/*
4 |
5 | # uni-config-center 核心模块
6 | # uni-id 核心模块
7 | uniCloud-aliyun/cloudfunctions/common/uni-*/**/*
8 |
--------------------------------------------------------------------------------
/src/components/i-uniapp/css/style.components.scss:
--------------------------------------------------------------------------------
1 | /* 组件主题色 */
2 | $i-type--primary: #0069fa;
3 | $i-type--success: #07c160;
4 | $i-type--warning: #ff976a;
5 | $i-type--danger: #ee0a24;
6 | /* 内容默认颜色 */
7 | $i-content--color: black;
8 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/content-security/content-security.param.json:
--------------------------------------------------------------------------------
1 | // 本文件中的json内容将在云函数【运行】时作为参数传给云函数。
2 | // 配置教程参考:https://uniapp.dcloud.net.cn/uniCloud/quickstart?id=runparam
3 | {
4 | "platform": "mp-weixin",
5 | "content": ""
6 | }
7 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/qq-robot/etsc.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | outDir: './dist',
3 | esbuild: {
4 | target: 'es2015'
5 | },
6 | assets: {
7 | baseDir: 'src',
8 | filePatterns: ['**/*.json']
9 | }
10 | };
11 |
--------------------------------------------------------------------------------
/doc/business/pull.puml:
--------------------------------------------------------------------------------
1 | @startuml
2 | (*) --> "第三方API以及Python爬虫题源"
3 | --> "固定时间段进行拉取新题源"
4 | if "类型" then
5 | --> [服务号推送] "推送到用户关联的服务号中"
6 | -right-> [入库] "新题入库推荐给用户(特定的专区)"
7 | else
8 | -right-> [入库] "新题入库推荐给用户(特定的专区)"
9 | Endif
10 | --> (*)
11 | @enduml
--------------------------------------------------------------------------------
/src/uni_modules/uni-popup/changelog.md:
--------------------------------------------------------------------------------
1 | ## 1.2.9(2021-02-05)
2 | - 优化 组件引用关系,通过uni_modules引用组件
3 | ## 1.2.8(2021-02-05)
4 | - 调整为uni_modules目录规范
5 | ## 1.2.7(2021-02-05)
6 | - 调整为uni_modules目录规范
7 | - 新增 支持 PC 端
8 | - 新增 uni-popup-message 、uni-popup-dialog扩展组件支持 PC 端
9 |
--------------------------------------------------------------------------------
/doc/business/contentSecurity.puml:
--------------------------------------------------------------------------------
1 | @startuml
2 |
3 | start
4 | :进入内容安全公共模块;
5 | if (文本识别) then ( )
6 | :将不安全的字符进行*处理;
7 | elseif (图片识别) then( )
8 | :屏蔽反暴力血腥等不合法图片;
9 | elseif (富文本识别) then( )
10 | :对富文本中不正当词汇做出预警判断;
11 | endif
12 |
13 | stop
14 |
15 | @enduml
--------------------------------------------------------------------------------
/doc/business/examineQuestion.puml:
--------------------------------------------------------------------------------
1 | @startuml
2 | (*) --> "具有Push Question权限的角色发布一道题"
3 | --> "具有ANY权限的admin校验题目真实性以及可靠性"
4 | if "审核" then
5 | --> [审核成功] "题目状态更改为pass"
6 | --> (*)
7 | else
8 | --> [审核失败] "填写失败原因,状态更改为reject,出题人可再次提交"
9 | --> "具有ANY权限的admin校验题目真实性以及可靠性"
10 | @enduml
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "npm-scripts.showStartNotification": false,
3 | "editor.defaultFormatter": "esbenp.prettier-vscode",
4 | "typescript.preferences.importModuleSpecifier": "relative",
5 | "editor.codeActionsOnSave": {
6 | "source.fixAll.eslint": true
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/common/form-data-utils/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "form-data-utils",
3 | "version": "1.0.1",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {},
7 | "keywords": [],
8 | "author": "",
9 | "license": "Apache-2.0"
10 | }
11 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/common/explain-cache/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "explain-cache",
3 | "version": "1.0.1",
4 | "lockfileVersion": 1,
5 | "requires": true,
6 | "dependencies": {
7 | "explain": {
8 | "version": "file:../explain"
9 | }
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/pull/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "pull",
3 | "version": "1.0.0",
4 | "lockfileVersion": 1,
5 | "requires": true,
6 | "dependencies": {
7 | "uni-config-center": {
8 | "version": "file:../common/uni-config-center"
9 | }
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/pull/readme.md:
--------------------------------------------------------------------------------
1 | #关于题库版权问题
2 | 《剑指题解》团队不管是小程序引用的题库,还是其他渠道引用的题库,我们都会与相关题库负责人进行洽谈,在此项目的readme中我们对所有支持剑指题解项目的开源题库项目都表示了敬意,同时也在我们的文档语雀中罗列了所有支持我们的题库列表,所以此Pull项目的意图并不是违规的操作,而是针对我们系统内部推送功能所开发的一个便于我们工作的小模块而已。
3 | #郑重声明
4 | 如果您想使用此题库的Pull项目作为商业用途,请自行联系各家题库负责人,在后续版本更新中,可能我们将此部分的代码不进行开源
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/common/uni-id/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "uni-id",
3 | "version": "3.3.5",
4 | "lockfileVersion": 1,
5 | "requires": true,
6 | "dependencies": {
7 | "uni-config-center": {
8 | "version": "file:../uni-config-center"
9 | }
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/dingtalk-robot/dingtalk-robot.param.json:
--------------------------------------------------------------------------------
1 | // 本文件中的json内容将在云函数【运行】时作为参数传给云函数。
2 |
3 | // 配置教程参考:https://uniapp.dcloud.net.cn/uniCloud/quickstart?id=runparam
4 |
5 | {
6 | "content": "大家好,我是群主小助理,我将会提示大家,剑指题解项目组中的运营数据,包括但不限于用户增长,申请认证记录,题目待审核记录,用户申请加入开源组织记录,用户提交的bug和建议"
7 | }
8 |
--------------------------------------------------------------------------------
/src/util/common.scss:
--------------------------------------------------------------------------------
1 | // 自定义多行超出省略号
2 | @mixin text-ellipsis($line: 1) {
3 | overflow: hidden;
4 | text-overflow: ellipsis;
5 | @if $line == 1 {
6 | white-space: nowrap;
7 | } @else {
8 | display: -webkit-box;
9 | -webkit-line-clamp: $line;
10 | -webkit-box-orient: vertical;
11 | }
12 | }
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/send-template-msg/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "send-template-msg",
3 | "version": "1.0.0",
4 | "lockfileVersion": 1,
5 | "requires": true,
6 | "dependencies": {
7 | "we-chat-api": {
8 | "version": "file:../common/we-chat-api"
9 | }
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/common/explain/abstracts/service.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * 服务抽象基类
5 | */
6 | module.exports = class service {
7 | constructor({ event, context, explain }) {
8 | this.event = event;
9 | this.context = context;
10 | this.explain = explain;
11 | }
12 | };
13 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/v1/src/router/search.ts:
--------------------------------------------------------------------------------
1 | const router: CloudRouter = {
2 | route: 'api/search',
3 | service: 'search',
4 | routes: [
5 | {
6 | route: 'addSeachLog',
7 | action: 'addSeachLog',
8 | httpMethod: 'POST'
9 | }
10 | ]
11 | };
12 |
13 | export = router;
14 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/explain-cache-clear-timeout/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const explain = require('explain');
4 | explain.cache = require('explain-cache');
5 |
6 | exports.main = async () => {
7 | var deleted = await explain.cache.clearTimeout();
8 | console.log(`已清理过期数据 ${deleted} 条。`);
9 | };
10 |
--------------------------------------------------------------------------------
/src/shims-vue.d.ts:
--------------------------------------------------------------------------------
1 | declare module '*.vue' {
2 | import type { DefineComponent } from 'vue';
3 | const component: DefineComponent, Record, unknown>;
4 | export default component;
5 | }
6 |
7 | interface ActionResult {
8 | success: boolean;
9 | data?: T;
10 | }
11 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/v1/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "outDir": "./dist",
4 | "target": "es6",
5 | "module": "CommonJS",
6 | "typeRoots": ["./typings", "./node_modules/@types", "../../../node_modules/sword-typescript-type-core"]
7 | },
8 | "include": ["./src/**/*.ts"]
9 | }
10 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/common/we-chat-api/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "we-chat-api",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "keywords": [],
10 | "author": "",
11 | "license": "ISC"
12 | }
13 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/database/userCollect.schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "bsonType": "object",
3 | "required": [],
4 | "permission": {
5 | "read": true,
6 | "create": false,
7 | "update": false,
8 | "delete": false
9 | },
10 | "properties": {
11 | "_id": {
12 | "description": "ID,系统自动生成"
13 | }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/common/sword-recommend/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "sword-recommend",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "keywords": [],
10 | "author": "",
11 | "license": "ISC"
12 | }
13 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/day-satistics/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "cloudfunction-config": {
3 | "memorySize": 128,
4 | "timeout": 5,
5 | "triggers": [
6 | {
7 | "name": "myTrigger",
8 | "type": "timer",
9 | "config": "0 0 8 * * * *"
10 | }
11 | ],
12 | "path": "/http/day-satistics"
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/open-api-reset-request-number/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "cloudfunction-config": {
3 | "memorySize": 128,
4 | "timeout": 5,
5 | "triggers": [
6 | {
7 | "name": "myTrigger",
8 | "type": "timer",
9 | "config": "0 0 0 1 * * *"
10 | }
11 | ],
12 | "path": ""
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/open-api/openApi.param.json:
--------------------------------------------------------------------------------
1 | // 本文件中的json内容将在云函数【运行】时作为参数传给云函数。
2 | // 配置教程参考:https://uniapp.dcloud.net.cn/uniCloud/quickstart?id=runparam
3 | {
4 | "path": "/",
5 | "httpMethod": "GET",
6 | "queryStringParameters": {
7 | "token": "",
8 | "apiID": ""
9 | },
10 | "body": {
11 | "state": "pass"
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/doc/business/userBind.puml:
--------------------------------------------------------------------------------
1 | @startuml
2 | (*) --> "是否已微信登录"
3 | if "已经微信登录" then
4 | if "绑定手机号" then
5 | --> (*)
6 | else
7 | -> "登录(绑定)成功"
8 | endif
9 | --> (*)
10 | else
11 | -right-> "没有登录"
12 | endif
13 | if "如果选择手机号登录" then
14 | --> "登录(绑定)成功"
15 | else
16 | -right-> "第三方登录"
17 | endif
18 | --> "检查是否绑定了手机号"
19 | --> "登录(绑定)成功"
20 | --> (*)
21 | @enduml
--------------------------------------------------------------------------------
/src/api/questionArea.ts:
--------------------------------------------------------------------------------
1 | const db = uniCloud.database();
2 |
3 | /**
4 | * @name 获取专区列表
5 | * @returns
6 | */
7 | export async function getQuestionAreaList(): Promise {
8 | // 获取题目专区列表
9 | const res = await db.collection('questionArea').where("deleteDate == ''").get();
10 | return {
11 | ...res,
12 | data: res.result.data
13 | };
14 | }
15 |
--------------------------------------------------------------------------------
/src/uni_modules/uni-popup/components/uni-popup/share.js:
--------------------------------------------------------------------------------
1 | export default {
2 | created() {
3 | if (this.type === 'share') {
4 | // 关闭点击
5 | this.mkclick = false;
6 | }
7 | },
8 | methods: {
9 | customOpen() {
10 | console.log('share 打开了');
11 | },
12 | customClose() {
13 | console.log('share 关闭了');
14 | }
15 | }
16 | };
17 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/open-api/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "openApi",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "author": "",
10 | "license": "ISC",
11 | "dependencies": {
12 | "uni-id": "file:../common/uni-id"
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/api/certificationApplyOrder.ts:
--------------------------------------------------------------------------------
1 | import request from '../common/request';
2 |
3 | export async function addCertificationApplyOrder(params: { content: Record }): Promise {
4 | return await request({
5 | route: `api/certificationApplyOrder`,
6 | method: 'POST',
7 | data: {
8 | content: params.content
9 | }
10 | });
11 | }
12 |
--------------------------------------------------------------------------------
/doc/business/pushQuestion.puml:
--------------------------------------------------------------------------------
1 | @startuml
2 | (*) --> "获取题目"
3 | if "主动服务号推送" then
4 | --> "用户设置的推送专区(专区爱好)进行范围推送"
5 | --> "获取规则:\n 用户关注的用户最新发布的题优先\n > 当日浏览详情人数最多的优先\n > 当日答题人数最多的题优先"
6 | else
7 | --> [程序中用户进入题目页面获取] "根据用户进入的专区获取题目"
8 | --> "获取规则:\n 用户关注的用户最新发布的题优先\n > 当日浏览详情人数最多的优先\n > 当日答题人数最多的题优先"
9 | Endif
10 | --> "version1: 第三方开源题库 > 自建题库"
11 | --> "越晚时间发布的题目优先"
12 | --> (*)
13 | @enduml
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/common/explain/abstracts/filter.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * 过滤器抽象基类
5 | */
6 | module.exports = class filter {
7 | constructor({ event, context, explain }) {
8 | this.event = event;
9 | this.context = context;
10 | this.explain = explain;
11 | }
12 | onActionExecuting() {}
13 | onActionExecuted() {}
14 | onException() {}
15 | };
16 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/pull/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "pull",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "author": "",
10 | "license": "ISC",
11 | "dependencies": {
12 | "uni-config-center": "file:../common/uni-config-center"
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/v1/proto/questionTag.ts:
--------------------------------------------------------------------------------
1 | export interface GetTagList {
2 | limit: number;
3 | page: number;
4 | }
5 | export interface AddQuestionTag {
6 | areaID: string;
7 | name: string;
8 | }
9 | export interface UpdateQuestionTag {
10 | _id: string;
11 | areaID: string;
12 | name: string;
13 | }
14 | export interface DeleteQuestionTag {
15 | _id: string;
16 | }
17 |
--------------------------------------------------------------------------------
/src/pages/common/noRelease.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
14 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/send-template-msg/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "send-template-msg",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "author": "",
10 | "license": "ISC",
11 | "dependencies": {
12 | "we-chat-api": "file:../common/we-chat-api"
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/common/explain-cache/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "explain-cache",
3 | "version": "1.0.1",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "keywords": [],
10 | "author": "",
11 | "license": "ISC",
12 | "dependencies": {
13 | "explain": "file:../explain"
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/content-security/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "content-security",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "author": "",
10 | "license": "ISC",
11 | "dependencies": {
12 | "get-accesstoken": "file:../common/get-accesstoken"
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/common/uni-captcha/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "uni-captcha",
3 | "version": "0.0.3",
4 | "description": "uni-captcha",
5 | "main": "index.js",
6 | "homepage": "https://ext.dcloud.net.cn/plugin?id=4048",
7 | "repository": {
8 | "type": "git",
9 | "url": "git+https://gitee.com/dcloud/uni-captcha"
10 | },
11 | "author": "DCloud",
12 | "license": "Apache-2.0"
13 | }
14 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/v1/src/router/article.ts:
--------------------------------------------------------------------------------
1 | const router: CloudRouter = {
2 | route: 'api/article',
3 | service: 'article',
4 | routes: [
5 | {
6 | action: 'addArticle'
7 | },
8 | {
9 | action: 'updateArticle'
10 | },
11 | {
12 | route: 'auditArticle',
13 | action: 'auditArticle',
14 | httpMethod: 'POST'
15 | }
16 | ]
17 | };
18 |
19 | export = router;
20 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/uni-analyse-searchhot/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "uni-analyse-searchhot",
3 | "version": "1.0.0",
4 | "description": "定时归纳热搜",
5 | "main": "index.js",
6 | "dependencies": {},
7 | "cloudfunction-config": {
8 | "triggers": [
9 | {
10 | "name": "analyse-searchHot",
11 | "type": "timer",
12 | "config": "0 0 */2 * * * *"
13 | }
14 | ]
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/v1/proto/article.ts:
--------------------------------------------------------------------------------
1 | export interface AddArticle {
2 | title: string;
3 | content: string;
4 | tagID: string[];
5 | desc: string;
6 | }
7 |
8 | export interface UpdateArticle {
9 | id: string;
10 | title: string;
11 | content: string;
12 | tagID: string[];
13 | }
14 |
15 | export interface AuditArticle {
16 | id: string;
17 | state: string;
18 | rejectReason?: string;
19 | }
20 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/v1/src/router/questionTag.ts:
--------------------------------------------------------------------------------
1 | const router: CloudRouter = {
2 | route: 'api/questionTag',
3 | service: 'questionTag',
4 | routes: [
5 | {
6 | action: 'getTagList'
7 | },
8 | {
9 | action: 'addQuestionTag'
10 | },
11 | {
12 | action: 'updateQuestionTag'
13 | },
14 | {
15 | action: 'deleteQuestionTag'
16 | }
17 | ]
18 | };
19 |
20 | export = router;
21 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/common/explain/utils/object.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = class object {
4 | /**
5 | * 对象属性根据键排序
6 | * @param {Object} obj
7 | */
8 | static sort(obj) {
9 | let keys = Object.keys(obj).sort();
10 | let newObj = {};
11 | for (var i = 0; i < keys.length; i++) {
12 | var key = keys[i];
13 | newObj[key] = obj[key];
14 | }
15 | return newObj;
16 | }
17 | };
18 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/v1/src/router/questionArea.ts:
--------------------------------------------------------------------------------
1 | const router: CloudRouter = {
2 | route: 'api/questionArea',
3 | service: 'questionArea',
4 | routes: [
5 | {
6 | action: 'getAreaList'
7 | },
8 | {
9 | action: 'addQuestionArea'
10 | },
11 | {
12 | action: 'updateQuestionArea'
13 | },
14 | {
15 | action: 'deleteQuestionArea'
16 | }
17 | ]
18 | };
19 |
20 | export = router;
21 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/common/tsbuffer-params-validate/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "tsbuffer-params-validate",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "dev": "nodemon",
8 | "test": "echo \"Error: no test specified\" && exit 1"
9 | },
10 | "keywords": [],
11 | "author": "",
12 | "license": "ISC",
13 | "dependencies": {
14 | "tsbuffer-validator": "^2.0.4"
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/open-api-reset-request-number/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const db = uniCloud.database();
4 | const collection = db.collection('uni-id-users');
5 | // 每个月重置的次数
6 | const RESET_NUMBER = 200;
7 |
8 | exports.main = async (event, context) => {
9 | // 重置
10 | return await collection
11 | .where({
12 | mobile_confirmed: 1
13 | })
14 | .update({
15 | openApiRequestNumber: RESET_NUMBER
16 | });
17 | };
18 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/v1/proto/questionArea.ts:
--------------------------------------------------------------------------------
1 | export interface AddQuestionArea {
2 | name: string;
3 | iconPath: string;
4 | }
5 |
6 | export interface GetAreaList {
7 | limit: number;
8 | page: number;
9 | name: string;
10 | iconPath: string;
11 | }
12 |
13 | export interface UpdateQuestionArea {
14 | _id: string;
15 | name: string;
16 | iconPath: string;
17 | }
18 |
19 | export interface DeleteQuestionArea {
20 | _id: string;
21 | }
22 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "singleQuote": true,
3 | "trailingComma": "none",
4 | "printWidth": 160,
5 | "tabWidth": 2,
6 | "tabs": false,
7 | "semi": true,
8 | "quoteProps": "as-needed",
9 | "bracketSpacing": true,
10 | "jsxBracketSameLine": true,
11 | "htmlWhitespaceSensitivity": "ignore",
12 | "useTabs": false,
13 | "jsxSingleQuote": false,
14 | "arrowParens": "always",
15 | "rangeStart": 0,
16 | "proseWrap": "always",
17 | "endOfLine": "lf"
18 | }
19 |
--------------------------------------------------------------------------------
/src/uni_modules/uni-search-bar/changelog.md:
--------------------------------------------------------------------------------
1 | ## 1.0.9(2021-05-12)
2 | - 新增 项目示例地址
3 | ## 1.0.8(2021-04-21)
4 | - 优化 添加依赖 uni-icons, 导入后自动下载依赖
5 | ## 1.0.7(2021-04-15)
6 | - uni-ui 新增 uni-search-bar 的 focus 事件
7 |
8 | ## 1.0.6(2021-02-05)
9 | - 优化 组件引用关系,通过uni_modules引用组件
10 |
11 | ## 1.0.5(2021-02-05)
12 | - 调整为uni_modules目录规范
13 | - 新增 支持双向绑定
14 | - 更改 input 事件的返回值,e={value:Number} --> e=value
15 | - 新增 支持图标插槽
16 | - 新增 支持 clear、blur 事件
17 | - 新增 支持 focus 属性
18 | - 去掉组件背景色
19 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/dingtalk-robot/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "dingtalk-robot",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "keywords": [],
10 | "author": "",
11 | "license": "ISC",
12 | "dependencies": {
13 | "dingtalk-robot-sender": "^1.2.0",
14 | "uni-config-center": "file:../common/uni-config-center"
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules/
3 | unpackage/
4 | dist/
5 | # local env files
6 | .env.local
7 | .env.*.local
8 | .hbuilderx
9 |
10 | # Log files
11 | npm-debug.log*
12 | yarn-debug.log*
13 | yarn-error.log*
14 |
15 | # Editor directories and files
16 | .project
17 | .idea
18 | *.suo
19 | *.ntvs*
20 | *.njsproj
21 | *.sln
22 | *.sw*
23 | uniCloud-aliyun/cloudfunctions/common/uni-config-center/*
24 | # 屏蔽所有云函数的本地开发测试json
25 | uniCloud-aliyun/cloudfunctions/*/*.param.json
26 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/v1/proto/openapi.ts:
--------------------------------------------------------------------------------
1 | export interface AddOpenApi {
2 | name: string;
3 | remark: string;
4 | info: string;
5 | }
6 |
7 | export interface UpdateOpenApi {
8 | _id: string;
9 | name: string;
10 | remark: string;
11 | info: any;
12 | }
13 |
14 | export interface ToggleOpenApiState {
15 | id: string;
16 | state: 'close' | 'open';
17 | }
18 |
19 | export interface GetQuestionList {
20 | page: number;
21 | areaID?: string;
22 | }
23 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/v1/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "v1",
3 | "version": "1.0.0",
4 | "lockfileVersion": 1,
5 | "requires": true,
6 | "dependencies": {
7 | "@types/node": {
8 | "version": "16.11.6",
9 | "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.6.tgz",
10 | "integrity": "sha512-ua7PgUoeQFjmWPcoo9khiPum3Pd60k4/2ZGXt18sm2Slk0W0xZTqt5Y0Ny1NyBiN1EVQ/+FaF9NcY4Qe6rwk5w==",
11 | "dev": true
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # Editor configuration, see http://editorconfig.org
2 |
3 | # 表示是最顶层的 EditorConfig 配置文件
4 | root = true
5 |
6 | [*] # 表示所有文件适用
7 | charset = utf-8 # 设置文件字符集为 utf-8
8 | indent_style = space # 缩进风格(tab | space)
9 | indent_size = 2 # 缩进大小
10 | end_of_line = lf # 控制换行类型(lf | cr | crlf)
11 | trim_trailing_whitespace = true # 去除行首的任意空白字符
12 | insert_final_newline = true # 始终在文件末尾插入一个新行
13 |
14 | [*.md] # 表示仅 md 文件适用以下规则
15 | max_line_length = off
16 | trim_trailing_whitespace = false
17 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/explain-cache-clear-timeout/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "explain-cache-clear-timeout",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "keywords": [],
10 | "author": "",
11 | "license": "ISC",
12 | "dependencies": {
13 | "explain": "file:../common/explain",
14 | "explain-cache": "file:../common/explain-cache"
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/uni-id-cf/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "uni-id-cf",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "author": "",
10 | "license": "ISC",
11 | "dependencies": {
12 | "uni-captcha": "file:../common/uni-captcha",
13 | "uni-config-center": "file:../common/uni-config-center",
14 | "uni-id": "file:../common/uni-id"
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/pages/common/webview.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
22 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | env: { browser: true, node: true },
4 | parser: '@typescript-eslint/parser',
5 | parserOptions: {
6 | ecmaVersion: 2020,
7 | sourceType: 'module'
8 | },
9 | plugins: ['@typescript-eslint'],
10 | extends: ['plugin:@typescript-eslint/recommended', 'plugin:prettier/recommended'],
11 | rules: {
12 | // 支持ts-ignore
13 | '@typescript-eslint/ban-ts-ignore': 'off',
14 | '@typescript-eslint/no-var-requires': 0
15 | }
16 | };
17 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/common/uni-id/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "uni-id",
3 | "version": "3.3.5",
4 | "description": "uni-id for uniCloud",
5 | "main": "index.js",
6 | "homepage": "https://uniapp.dcloud.io/uniCloud/uni-id",
7 | "repository": {
8 | "type": "git",
9 | "url": "git+https://gitee.com/dcloud/uni-id.git"
10 | },
11 | "author": "",
12 | "license": "Apache-2.0",
13 | "dependencies": {
14 | "uni-config-center": "file:../uni-config-center"
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | globalTeardown: '@dcloudio/uni-automator/dist/teardown.js',
3 | testEnvironment: '@dcloudio/uni-automator/dist/environment.js',
4 | testEnvironmentOptions: {},
5 | testTimeout: 15000,
6 | reporters: ['default'],
7 | watchPathIgnorePatterns: ['/node_modules/', '/dist/', '/.git/'],
8 | moduleFileExtensions: ['js', 'json'],
9 | rootDir: __dirname,
10 | testMatch: ['/src/**/*test.[jt]s?(x)'],
11 | testPathIgnorePatterns: ['/node_modules/']
12 | };
13 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/pull/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | const HaizilinFeInterviewPlugin = require('./Haizilin-FeInterview');
3 | exports.main = () => {
4 | // 作为拉取核心函数,需要一时间执行多个TASK,而且每一个题源都不一定有API提供,所以需要我们进行捕获或者是以其他办法来获取题源。
5 | // 每一个题源可以作为一个plugin,注册到全局中即可在对的时间去执行,以这个思路去开发拉取函数,可以保证能公共利用的地方(模板,入库等操作)可以很方便,同时也保留了不同题源不同的获取方法。
6 | return HaizilinFeInterviewPlugin.main()
7 | .then((res) => {
8 | return res;
9 | })
10 | .catch((err) => {
11 | return err;
12 | });
13 | };
14 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/common/get-accesstoken/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "get-accesstoken",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "keywords": [],
10 | "author": "",
11 | "license": "ISC",
12 | "dependencies": {
13 | "explain": "file:../explain",
14 | "explain-cache": "file:../explain-cache",
15 | "uni-config-center": "file:../uni-config-center"
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/v1/proto/questionExplanation.ts:
--------------------------------------------------------------------------------
1 | export interface AddQuestionExplanation {
2 | _id: string;
3 | content: string;
4 | }
5 |
6 | export interface UpdateQuestionExplanation {
7 | _id: string;
8 | content: string;
9 | }
10 |
11 | export interface AdoptionQuestionExplanation {
12 | _id: string;
13 | }
14 |
15 | export interface CollectQuestionExplanation {
16 | _id: string;
17 | }
18 |
19 | export type GetExplanationCountByUser = string;
20 | export type GetLikeCountByUser = string;
21 |
--------------------------------------------------------------------------------
/src/uni_modules/uni-popup/components/uni-popup/message.js:
--------------------------------------------------------------------------------
1 | export default {
2 | created() {
3 | if (this.type === 'message') {
4 | // 不显示遮罩
5 | this.maskShow = false;
6 | // 获取子组件对象
7 | this.childrenMsg = null;
8 | }
9 | },
10 | methods: {
11 | customOpen() {
12 | if (this.childrenMsg) {
13 | this.childrenMsg.open();
14 | }
15 | },
16 | customClose() {
17 | if (this.childrenMsg) {
18 | this.childrenMsg.close();
19 | }
20 | }
21 | }
22 | };
23 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/common/tsbuffer-params-validate/index.js:
--------------------------------------------------------------------------------
1 | const { TSBufferValidator } = require('tsbuffer-validator');
2 |
3 | module.exports = function (event) {
4 | // schemas 由ts的proto生成的schemas
5 | // params 参数
6 | // service 路由url中的service
7 | // action 具体的方法
8 | const { schemas, params, service, action } = event;
9 | const validator = new TSBufferValidator(schemas);
10 | let vRes = validator.validate(params, `${service}/${action.replace(/^\S/, (s) => s.toUpperCase())}`);
11 | return vRes;
12 | };
13 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/v1/src/router/certificationApplyOrder.ts:
--------------------------------------------------------------------------------
1 | const router: CloudRouter = {
2 | route: 'api/certificationApplyOrder',
3 | service: 'certificationApplyOrder',
4 | routes: [
5 | {
6 | action: 'addCertificationApplyOrder'
7 | },
8 | {
9 | action: 'updateCertificationApplyOrder'
10 | },
11 | {
12 | route: 'updateCertificationApplyOrderState',
13 | action: 'updateCertificationApplyOrderState',
14 | httpMethod: 'PUT'
15 | }
16 | ]
17 | };
18 |
19 | export = router;
20 |
--------------------------------------------------------------------------------
/src/util/notLogin.ts:
--------------------------------------------------------------------------------
1 | export default (callback?: (userID?: string) => void): void => {
2 | // 获取ID,判断是否有登录
3 | const userID = uni.getStorageSync('uni_id') as string;
4 | if (userID === '') {
5 | uni.showModal({
6 | title: '提示',
7 | content: '您暂未登录,请登陆后再试试',
8 | confirmText: '登录',
9 | success: (res) => {
10 | if (res.confirm) {
11 | uni.navigateTo({
12 | url: '/pages/user/login?from=1'
13 | });
14 | }
15 | }
16 | });
17 | } else {
18 | callback && callback(userID);
19 | }
20 | };
21 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/v1/proto/certificationApplyOrder.ts:
--------------------------------------------------------------------------------
1 | export interface AddCertificationApplyOrder {
2 | content: {
3 | contactDetails: string;
4 | filed: string;
5 | identity: string;
6 | socialHomepage: string;
7 | };
8 | }
9 |
10 | export interface UpdateCertificationApplyOrder {
11 | _id: string;
12 | content: string;
13 | }
14 |
15 | export interface UpdateCertificationApplyOrderState {
16 | _id: string;
17 | state: string;
18 | }
19 |
20 | export interface GetCertificationApplyOrder {
21 | state: string;
22 | limit: number;
23 | page: number;
24 | }
25 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/explain-cache-clear-timeout/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "explain-cache-clear-timeout",
3 | "version": "1.0.0",
4 | "lockfileVersion": 1,
5 | "requires": true,
6 | "dependencies": {
7 | "explain": {
8 | "version": "file:../common/explain"
9 | },
10 | "explain-cache": {
11 | "version": "file:../common/explain-cache",
12 | "requires": {
13 | "explain": "file:../common/explain"
14 | },
15 | "dependencies": {
16 | "explain": {
17 | "version": "file:../common/explain"
18 | }
19 | }
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/common/explain/index.js:
--------------------------------------------------------------------------------
1 | //---------------------------------------------------------------------
2 | // github https://github.com/explaincloud/explain-unicloud
3 | // organization Explain Cloud
4 | // author Sansnn
5 | // license MIT
6 | //---------------------------------------------------------------------
7 |
8 | 'use strict';
9 |
10 | module.exports = {
11 | run: require('./program/run'),
12 | service: require('./abstracts/service'),
13 | filter: require('./abstracts/filter'),
14 | dateTime: require('./utils/datetime'),
15 | object: require('./utils/object')
16 | };
17 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/qq-robot/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "qq-robot",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1",
8 | "dev": "nodemon"
9 | },
10 | "author": "",
11 | "license": "ISC",
12 | "dependencies": {
13 | "explain": "file:../common/explain",
14 | "uni-config-center": "file:../common/uni-config-center"
15 | },
16 | "devDependencies": [],
17 | "cloudfunction-config": {
18 | "memorySize": 128,
19 | "timeout": 5,
20 | "triggers": [],
21 | "path": "/http/qqrobot"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/database/opendb-search-hot.schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "bsonType": "object",
3 | "required": ["content", "count"],
4 | "permission": {
5 | "read": true,
6 | "create": false,
7 | "update": false,
8 | "delete": false
9 | },
10 | "properties": {
11 | "_id": {
12 | "description": "ID,系统自动生成"
13 | },
14 | "content": {
15 | "bsonType": "string",
16 | "description": "搜索内容"
17 | },
18 | "count": {
19 | "bsonType": "long",
20 | "description": "搜索次数"
21 | },
22 | "create_date": {
23 | "bsonType": "timestamp",
24 | "description": "统计时间"
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/v1/src/router/questionExplanation.ts:
--------------------------------------------------------------------------------
1 | const router: CloudRouter = {
2 | route: 'api/questionExplanation',
3 | service: 'questionExplanation',
4 | routes: [
5 | {
6 | action: 'addQuestionExplanation'
7 | },
8 | {
9 | action: 'updateQuestionExplanation'
10 | },
11 | {
12 | route: 'adoptionQuestionExplanation',
13 | action: 'adoptionQuestionExplanation',
14 | httpMethod: 'POST'
15 | },
16 | {
17 | route: 'collectQuestionExplanation',
18 | action: 'collectQuestionExplanation',
19 | httpMethod: 'POST'
20 | }
21 | ]
22 | };
23 |
24 | export = router;
25 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/common/explain/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "explain",
3 | "version": "2.0.6",
4 | "description": "uniCloud云函数框架",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "repository": {
10 | "type": "git",
11 | "url": "git+https://github.com/explaincloud/explain-unicloud.git"
12 | },
13 | "keywords": [
14 | "unicloud"
15 | ],
16 | "author": "Sansnn",
17 | "license": "MIT",
18 | "bugs": {
19 | "url": "https://github.com/explaincloud/explain-unicloud/issues"
20 | },
21 | "homepage": "https://github.com/explaincloud/explain-unicloud#readme"
22 | }
23 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/common/get-accesstoken/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "get-accesstoken",
3 | "version": "1.0.0",
4 | "lockfileVersion": 1,
5 | "requires": true,
6 | "dependencies": {
7 | "explain": {
8 | "version": "file:../explain"
9 | },
10 | "explain-cache": {
11 | "version": "file:../explain-cache",
12 | "requires": {
13 | "explain": "file:../explain"
14 | },
15 | "dependencies": {
16 | "explain": {
17 | "version": "file:../explain"
18 | }
19 | }
20 | },
21 | "uni-config-center": {
22 | "version": "file:../uni-config-center"
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/send-template-msg/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const { sendTemplate } = require('we-chat-api');
4 |
5 | // 这里是测试内容,具体OPEN-ID需要从数据库查询
6 | const TEMPLATE_ID = 'n2YpgvpUaCYtqR5qT-cK9pHDemmvGbc8_G-6jXHGpwc';
7 | const OPEN_ID = 'obBvS4jZKSh7WJSOTcLbPq2FYtz8';
8 |
9 | exports.main = async () => {
10 | // 组装模板数据
11 | let data = {
12 | touser: OPEN_ID,
13 | template_id: TEMPLATE_ID,
14 | url: 'https://baidu.com',
15 | topcolor: '#FF0000',
16 | data: {
17 | name: {
18 | value: 'mrc',
19 | color: '#173177'
20 | }
21 | }
22 | };
23 | const desc = await sendTemplate(data);
24 |
25 | return desc;
26 | };
27 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/v1/schemas/genSchemas.js:
--------------------------------------------------------------------------------
1 | const { TSBufferProtoGenerator } = require('tsbuffer-proto-generator');
2 | const glob = require('glob');
3 | const path = require('path');
4 | const fs = require('fs');
5 |
6 | async function main() {
7 | let generator = new TSBufferProtoGenerator({
8 | baseDir: path.resolve(__dirname, '..', 'proto')
9 | });
10 |
11 | let files = glob.sync('**/*.ts', {
12 | cwd: path.resolve(__dirname, '..', 'proto')
13 | });
14 | console.log('Files: ', files);
15 |
16 | let result = await generator.generate(files);
17 |
18 | fs.writeFileSync(path.resolve(__dirname, 'schemas.json'), JSON.stringify(result, null, 2));
19 | }
20 | main();
21 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/v1/src/service/search.ts:
--------------------------------------------------------------------------------
1 | import * as ISearch from '../../proto/search';
2 | const db = uniCloud.database();
3 | const collection = db.collection('opendb-search-log');
4 | export default class SearchService {
5 | public userID: string;
6 | public nowDate: string;
7 | constructor(data: CloudData) {
8 | this.userID = data.context.userID;
9 | this.nowDate = new Date().toISOString();
10 | }
11 | async addSeachLog(params: ISearch.AddSeachLog): Promise {
12 | return await collection.add({
13 | content: params.content,
14 | [params.device_id ? 'device_id' : 'user_id']: params.device_id ? params.device_id : params.user_id,
15 | create_date: Date.now()
16 | });
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/components/i-uniapp/i-form/i-form.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
29 |
30 |
38 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/v1/src/controller/search.ts:
--------------------------------------------------------------------------------
1 | import * as explain from 'explain';
2 | import searchService from '../service/search';
3 | import * as ISearch from '../../proto/search';
4 | export = class SearchController extends explain.service {
5 | private service: searchService;
6 | constructor(e: CloudData) {
7 | super(e);
8 | this.service = new searchService(this);
9 | }
10 | /**
11 | * @name 增加搜索记录
12 | * @param ISearch.AddSeachLog
13 | * @return {*} {Promise}
14 | * @link https://www.yuque.com/mlgrgm/lmm8g4/fblw8z#g13V0
15 | * @memberof SearchController
16 | */
17 | addSeachLog(): Promise {
18 | return this.service.addSeachLog(this.event.data as ISearch.AddSeachLog);
19 | }
20 | };
21 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/database/opendb-search-log.schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "bsonType": "object",
3 | "permission": {
4 | "create": true,
5 | "delete": false,
6 | "read": false,
7 | "update": false
8 | },
9 | "properties": {
10 | "_id": {
11 | "description": "ID,系统自动生成"
12 | },
13 | "content": {
14 | "bsonType": "string",
15 | "description": "搜索内容"
16 | },
17 | "create_date": {
18 | "bsonType": "timestamp",
19 | "description": "统计时间"
20 | },
21 | "device_id": {
22 | "bsonType": "string",
23 | "description": "设备id"
24 | },
25 | "user_id": {
26 | "bsonType": "string",
27 | "description": "收藏者id,参考uni-id-users表"
28 | }
29 | },
30 | "required": ["content"]
31 | }
32 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/v1/src/router/question.ts:
--------------------------------------------------------------------------------
1 | const router: CloudRouter = {
2 | route: 'api/question',
3 | service: 'question',
4 | routes: [
5 | {
6 | action: 'addQuestion'
7 | },
8 | {
9 | action: 'updateQuestion'
10 | },
11 | {
12 | action: 'deleteQuestion'
13 | },
14 | {
15 | route: 'examineQuestion',
16 | action: 'examineQuestion',
17 | httpMethod: 'PUT'
18 | },
19 | {
20 | route: 'addPageView',
21 | action: 'addPageView',
22 | httpMethod: 'POST'
23 | },
24 | {
25 | action: 'getQuestionList'
26 | },
27 | {
28 | route: 'getSampleQuestionList',
29 | action: 'getSampleQuestionList',
30 | httpMethod: 'GET'
31 | }
32 | ]
33 | };
34 |
35 | export = router;
36 |
--------------------------------------------------------------------------------
/postcss.config.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 | module.exports = {
3 | parser: require('postcss-comment'),
4 | plugins: [
5 | require('postcss-import')({
6 | resolve(id) {
7 | if (id.startsWith('~@/')) {
8 | return path.resolve(process.env.UNI_INPUT_DIR, id.substr(3));
9 | } else if (id.startsWith('@/')) {
10 | return path.resolve(process.env.UNI_INPUT_DIR, id.substr(2));
11 | } else if (id.startsWith('/') && !id.startsWith('//')) {
12 | return path.resolve(process.env.UNI_INPUT_DIR, id.substr(1));
13 | }
14 | return id;
15 | }
16 | }),
17 | require('autoprefixer')({
18 | remove: process.env.UNI_PLATFORM !== 'h5'
19 | }),
20 | require('@dcloudio/vue-cli-plugin-uni/packages/postcss')
21 | ]
22 | };
23 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/v1/src/router/openApi.ts:
--------------------------------------------------------------------------------
1 | const router: CloudRouter = {
2 | route: 'api/openApi',
3 | service: 'openApi',
4 | routes: [
5 | {
6 | action: 'addOpenApi'
7 | },
8 | {
9 | action: 'updateOpenApi'
10 | },
11 | {
12 | route: 'toggleOpenApiState',
13 | action: 'toggleOpenApiState',
14 | httpMethod: 'POST'
15 | },
16 | {
17 | route: 'getQuestionList',
18 | action: 'getQuestionList',
19 | httpMethod: 'GET'
20 | },
21 | {
22 | route: 'getQuestionAreaList',
23 | action: 'getQuestionAreaList',
24 | httpMethod: 'GET'
25 | },
26 | {
27 | route: 'getQuestionTag',
28 | action: 'getQuestionTag',
29 | httpMethod: 'GET'
30 | }
31 | ]
32 | };
33 |
34 | export = router;
35 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/dingtalk-robot/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | const ChatBot = require('dingtalk-robot-sender');
3 | const createConfig = require('uni-config-center');
4 |
5 | const robotConfig = createConfig({
6 | pluginId: 'dingtalk-robot'
7 | });
8 |
9 | exports.main = (event) => {
10 | return new Promise(async (resolve) => {
11 | let config = robotConfig.config();
12 | //event为客户端上传的参数
13 | const robot = new ChatBot({
14 | webhook: `https://oapi.dingtalk.com/robot/send?access_token=${config.access_token}`
15 | });
16 | let textContent = {
17 | msgtype: 'text',
18 | text: {
19 | content: event.content
20 | },
21 | at: config.at
22 | };
23 | robot.send(textContent).then((res) => {
24 | // TODO
25 | resolve(res);
26 | });
27 | });
28 | };
29 |
--------------------------------------------------------------------------------
/src/api/article.ts:
--------------------------------------------------------------------------------
1 | const db = uniCloud.database();
2 | const collection = db.collection('article,uni-id-users');
3 |
4 | /**
5 | * @name 获取文章列表
6 | */
7 | export async function getArticleList(): Promise {
8 | const res = await collection
9 | .where({
10 | state: 'pass'
11 | })
12 | .field(`userID{avatar,nickname,sign,_id},title,content,createDate`)
13 | .orderBy('createDate', 'desc')
14 | .get();
15 | return {
16 | ...res,
17 | data: res.result.data
18 | };
19 | }
20 |
21 | /**
22 | * @name 获取文章详情根据ID
23 | */
24 | export async function getArticleByID(params: { id: string }): Promise {
25 | const res = await collection.doc(params.id).field(`userID{avatar,nickname,sign,_id},title,content`).get();
26 | return {
27 | ...res,
28 | data: res.result.data
29 | };
30 | }
31 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/common/explain/program/middleware.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const invoke = require('./invoke');
4 |
5 | module.exports.use = async ({ event, context, explain }) => {
6 | let middlewares = explain.middlewares;
7 | if (middlewares.length > 0) {
8 | let next = async (i) => {
9 | if (middlewares.length > i) {
10 | await middlewares[i]({
11 | event,
12 | context,
13 | explain,
14 | next: async () => {
15 | i++;
16 | await next(i);
17 | }
18 | });
19 | } else {
20 | await invoke({
21 | event,
22 | context,
23 | explain
24 | });
25 | }
26 | };
27 | await next(0);
28 | } else {
29 | await invoke({
30 | event,
31 | context,
32 | explain
33 | });
34 | }
35 | };
36 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/v1/proto/question.ts:
--------------------------------------------------------------------------------
1 | type _state = 'pass' | 'reject';
2 | export interface AddQuestion {
3 | title: string;
4 | areaID: string;
5 | content: string;
6 | tagID: string[];
7 | }
8 |
9 | export interface UpdateQuestion {
10 | _id: string;
11 | title: string;
12 | areaID: string;
13 | content?: string;
14 | tagID?: string[];
15 | }
16 |
17 | export interface DeleteQuestion {
18 | _id: string;
19 | }
20 |
21 | export interface ExamineQuestion {
22 | _id: string;
23 | state: _state;
24 | examineInfo?: {
25 | reason: string;
26 | };
27 | }
28 |
29 | export interface GetQuestionList {
30 | state: _state;
31 | limit: number;
32 | page: number;
33 | }
34 |
35 | export interface AddPageView {
36 | _id: string;
37 | }
38 | export interface GetSampleQuestionList {
39 | areaID?: string;
40 | size?: number;
41 | }
42 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/database/questionTag.schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "bsonType": "object",
3 | "required": [],
4 | "permission": {
5 | "read": true,
6 | "create": false,
7 | "update": false,
8 | "delete": false
9 | },
10 | "properties": {
11 | "_id": {
12 | "description": "ID,系统自动生成"
13 | },
14 | "name": {
15 | "bsonType": "string",
16 | "description": "标签名称"
17 | },
18 | "areaID": {
19 | "bsonType": "object",
20 | "description": "专区id",
21 | "foreignKey": "questionArea._id"
22 | },
23 | "createDate": {
24 | "bsonType": "timestamp",
25 | "description": "创建时间"
26 | },
27 | "updateDate": {
28 | "bsonType": "timestamp",
29 | "description": "修改时间"
30 | },
31 | "deleteDate": {
32 | "bsonType": "timestamp",
33 | "description": "删除时间"
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/database/questionArea.schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "bsonType": "object",
3 | "required": [],
4 | "permission": {
5 | "read": true,
6 | "create": false,
7 | "update": false,
8 | "delete": false
9 | },
10 | "properties": {
11 | "_id": {
12 | "description": "ID,系统自动生成"
13 | },
14 | "name": {
15 | "bsonType": "string",
16 | "description": "专区名称"
17 | },
18 | "iconPath": {
19 | "bsonType": "string",
20 | "description": "图标url"
21 | },
22 | "state": {
23 | "bsonType": "string",
24 | "description": "状态"
25 | },
26 | "createDate": {
27 | "bsonType": "timestamp",
28 | "description": "创建时间"
29 | },
30 | "updateDate": {
31 | "bsonType": "timestamp",
32 | "description": "修改时间"
33 | },
34 | "deleteDate": {
35 | "bsonType": "timestamp",
36 | "description": "删除时间"
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/v1/filters/tokenFilter.js:
--------------------------------------------------------------------------------
1 | const explain = require('explain');
2 | const uniID = require('uni-id');
3 | module.exports = class tokenFilter extends explain.filter {
4 | async onActionExecuting() {
5 | const token_name = 'uni-id-token';
6 | let { event: _event, explain: _explain, context: _context } = this;
7 | // 判断headers中是否存在token
8 | if (!_event.headers[token_name]) {
9 | _explain.response.body = {
10 | code: 401,
11 | message: 'token不存在'
12 | };
13 | return;
14 | } else {
15 | // 检查token合法性和过期时间
16 | const checkData = await uniID.getUserInfoByToken(_event.headers[token_name]);
17 | // token校验不合法
18 | if (!checkData.uid) {
19 | _explain.response.body = {
20 | ...checkData
21 | };
22 | return;
23 | } else {
24 | _context.userID = checkData.uid;
25 | }
26 | }
27 | }
28 | };
29 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/database/certificationApplyOrder.schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "bsonType": "object",
3 | "required": [],
4 | "permission": {
5 | "read": true,
6 | "create": false,
7 | "update": false,
8 | "delete": false
9 | },
10 | "properties": {
11 | "_id": {
12 | "description": "ID,系统自动生成"
13 | },
14 | "state": {
15 | "bsonType": "string",
16 | "description": "状态"
17 | },
18 | "userID": {
19 | "bsonType": "string",
20 | "foreignKey": "uni-id-users._id"
21 | },
22 | "content": {
23 | "bsonType": "object",
24 | "description": "审核递交的内容"
25 | },
26 | "createDate": {
27 | "bsonType": "timestamp",
28 | "description": "创建时间"
29 | },
30 | "updateDate": {
31 | "bsonType": "timestamp",
32 | "description": "修改时间"
33 | },
34 | "deleteDate": {
35 | "bsonType": "timestamp",
36 | "description": "删除时间"
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/.github/workflows/sync2gitee.yml:
--------------------------------------------------------------------------------
1 | # 同步仓库信息到gitee
2 | name: sync2gitee
3 |
4 | on:
5 | schedule:
6 | - cron: '30 17 * * *'
7 |
8 | jobs:
9 | run:
10 | name: Sync GitHub to Gitee
11 | runs-on: ubuntu-latest
12 | steps:
13 | - name: Get current repository name
14 | id: info
15 | uses: actions/github-script@v3.1
16 | with:
17 | github-token: ${{secrets.GITHUB_TOKEN}}
18 | result-encoding: string
19 | script: |
20 | return context.repo.repo;
21 | - name: Mirror the GitHub repos to Gitee
22 | uses: Yikun/hub-mirror-action@master
23 | with:
24 | src: github/swordCodePractice
25 | dst: gitee/sword-code-practice
26 | dst_key: ${{ secrets.GITEE_PRIVATE_KEY }}
27 | dst_token: ${{ secrets.GITEE_TOKEN }}
28 | static_list: '${{ steps.info.outputs.result }}'
29 | account_type: org
30 | force_update: true
31 | white_list: 'app'
32 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/database/opendb-verify-codes.schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "bsonType": "object",
3 | "required": [],
4 | "properties": {
5 | "_id": {
6 | "description": "ID,系统自动生成"
7 | },
8 | "mobile": {
9 | "bsonType": "string",
10 | "description": "手机号码"
11 | },
12 | "email": {
13 | "bsonType": "string",
14 | "description": "邮箱"
15 | },
16 | "code": {
17 | "bsonType": "string",
18 | "description": "验证码"
19 | },
20 | "type": {
21 | "bsonType": "string",
22 | "description": "验证类型:login, bind, unbind, pay"
23 | },
24 | "state": {
25 | "bsonType": "int",
26 | "description": "验证状态:0 未验证、1 已验证、2 已作废"
27 | },
28 | "ip": {
29 | "bsonType": "string",
30 | "description": "请求时客户端IP地址"
31 | },
32 | "created_at": {
33 | "bsonType": "timestamp",
34 | "description": "创建时间"
35 | },
36 | "expired_at": {
37 | "bsonType": "timestamp",
38 | "description": "过期时间"
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/api/collect.ts:
--------------------------------------------------------------------------------
1 | const db = uniCloud.database();
2 |
3 | /**
4 | * @name 检查自己是否已收藏题解
5 | * @param params
6 | * @returns
7 | */
8 | export async function checkIDInCollect(params: { id: string }): Promise {
9 | const res = await db
10 | .collection('userCollect')
11 | .where({
12 | userID: uni.getStorageSync('uni_id')
13 | })
14 | .get<{
15 | collectData: unknown[];
16 | }>();
17 |
18 | const { success, result } = res;
19 | // 根据返回的多个收藏夹去循环
20 | for (const collectKey in result.data) {
21 | // 查询当前收藏夹中的收藏内容
22 | const isCollect = result.data[collectKey].collectData.some((c: { id: string }) => c.id === params.id);
23 | // 如果找到收藏
24 | if (isCollect) {
25 | // 已收藏, 这里要么使用return去终止for循环,同理还可以使用延时器以及breaK跳出循环
26 | // 如果Promise没有立即调用then,那么for会依旧执行,resolve第二次调用是无效的,会取第一个。
27 | return {
28 | success,
29 | data: true
30 | };
31 | }
32 | }
33 | // 默认返回未收藏
34 | return {
35 | success,
36 | data: false
37 | };
38 | }
39 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/database/uni-id-log.schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "bsonType": "object",
3 | "required": ["user_id"],
4 | "properties": {
5 | "_id": {
6 | "description": "ID,系统自动生成"
7 | },
8 | "user_id": {
9 | "bsonType": "string",
10 | "description": "用户id,参考uni-id-users表"
11 | },
12 | "ua": {
13 | "bsonType": "string",
14 | "description": "userAgent"
15 | },
16 | "device_uuid": {
17 | "bsonType": "string",
18 | "description": "设备唯一标识(需要加密存储)"
19 | },
20 | "type": {
21 | "bsonType": "string",
22 | "enum": ["login", "logout"],
23 | "description": "登录类型"
24 | },
25 | "state": {
26 | "bsonType": "int",
27 | "description": "结果:0 失败、1 成功"
28 | },
29 | "ip": {
30 | "bsonType": "string",
31 | "description": "ip地址"
32 | },
33 | "create_date": {
34 | "bsonType": "timestamp",
35 | "description": "创建时间",
36 | "forceDefaultValue": {
37 | "$env": "now"
38 | }
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/database/openApi.schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "bsonType": "object",
3 | "required": [],
4 | "permission": {
5 | "read": true,
6 | "create": false,
7 | "update": false,
8 | "delete": false
9 | },
10 | "properties": {
11 | "_id": {
12 | "description": "ID,系统自动生成"
13 | },
14 | "name": {
15 | "bsonType": "string",
16 | "description": "api名称"
17 | },
18 | "remark": {
19 | "bsonType": "string",
20 | "description": "备注"
21 | },
22 | "state": {
23 | "bsonType": "string",
24 | "description": "类型,close不开放,open开放"
25 | },
26 | "info": {
27 | "bsonType": "object",
28 | "description": "openapi的信息,其中包括url等等"
29 | },
30 | "createDate": {
31 | "bsonType": "timestamp",
32 | "description": "创建时间"
33 | },
34 | "updateDate": {
35 | "bsonType": "timestamp",
36 | "description": "修改时间"
37 | },
38 | "deleteDate": {
39 | "bsonType": "timestamp",
40 | "description": "删除时间"
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/uni_modules/uni-icons/readme.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | ## Icons 图标
4 | > **组件名:uni-icons**
5 | > 代码块: `uIcons`
6 |
7 |
8 | 用于展示 icons 图标 。
9 |
10 | ### 安装方式
11 |
12 | 本组件符合[easycom](https://uniapp.dcloud.io/collocation/pages?id=easycom)规范,`HBuilderX 2.5.5`起,只需将本组件导入项目,在页面`template`中即可直接使用,无需在页面中`import`和注册`components`。
13 |
14 | 如需通过`npm`方式使用`uni-ui`组件,另见文档:[https://ext.dcloud.net.cn/plugin?id=55](https://ext.dcloud.net.cn/plugin?id=55)
15 |
16 | ### 基本用法
17 |
18 | 在 ``template`` 中使用组件
19 |
20 | ```html
21 |
22 | ```
23 |
24 |
25 |
26 | ## API
27 |
28 | ### Icons Props
29 |
30 | |属性名 |类型 |默认值 |说明 |
31 | |:-: |:-: |:-: |:-: |
32 | |size |Number |24 |图标大小 |
33 | |type |String |- |图标图案,参考示例 |
34 | |color |String |- |图标颜色 |
35 |
36 |
37 | ### Icons Events
38 | |事件名 |说明 |返回值|
39 | |:-: |:-: |:-: |
40 | |@click|点击 Icon 触发事件|- |
41 |
42 |
43 |
44 | ## 组件示例
45 |
46 | 点击查看:[https://hellouniapp.dcloud.net.cn/pages/extUI/icons/icons](https://hellouniapp.dcloud.net.cn/pages/extUI/icons/icons)
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/v1/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "v1",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "dev": "npm run etsc & npm run proto",
8 | "test": "echo \"Error: no test specified\" && exit 1",
9 | "proto": "nodemon --config nodemon.proto.json",
10 | "etsc": "nodemon --config nodemon.etsc.json"
11 | },
12 | "keywords": [],
13 | "author": "",
14 | "license": "ISC",
15 | "dependencies": {
16 | "explain": "file:../common/explain",
17 | "form-data-utils": "file:../common/form-data-utils",
18 | "ts-validate": "file:../common/tsbuffer-params-validate",
19 | "tsbuffer-params-validate": "file:../common/tsbuffer-params-validate",
20 | "uni-config-center": "file:../common/uni-config-center",
21 | "uni-id": "file:../common/uni-id"
22 | },
23 | "devDependencies": {
24 | "@types/node": "^16.9.2"
25 | },
26 | "cloudfunction-config": {
27 | "memorySize": 128,
28 | "timeout": 5,
29 | "triggers": [],
30 | "path": "/http/v1"
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/content-security/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "content-security",
3 | "version": "1.0.0",
4 | "lockfileVersion": 1,
5 | "requires": true,
6 | "dependencies": {
7 | "get-accesstoken": {
8 | "version": "file:../common/get-accesstoken",
9 | "requires": {
10 | "explain": "file:../common/explain",
11 | "explain-cache": "file:../common/explain-cache",
12 | "uni-config-center": "file:../common/uni-config-center"
13 | },
14 | "dependencies": {
15 | "explain": {
16 | "version": "file:../common/explain"
17 | },
18 | "explain-cache": {
19 | "version": "file:../common/explain-cache",
20 | "requires": {
21 | "explain": "file:../common/explain"
22 | },
23 | "dependencies": {
24 | "explain": {
25 | "version": "file:../common/explain"
26 | }
27 | }
28 | },
29 | "uni-config-center": {
30 | "version": "file:../common/uni-config-center"
31 | }
32 | }
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/components/i-uniapp/i-icon/readme.md:
--------------------------------------------------------------------------------
1 | #i-icon图标集-最优质且统一风格的图标库,源于remixicon
2 |
3 | - [访问remixicon官网](https://remixicon.com/)
4 | - [特点](## 特点)
5 | - [使用说明](## 使用说明)
6 |
7 | ## 特点
8 | - remixicon提倡全部开源,免费商用。
9 | - 每一个图标都由remixicon成员绘制,设计统一。
10 | - i-icon组件隶属于i-uniapp组件库,i-icon组件单独维护。
11 | - CDN引入,无需引入繁琐的字体等文件。
12 | - 支持NVue, Vue, 小程序,H5
13 |
14 | ## 使用说明
15 | 安装之后会在components目录下多一个i-uniapp的文件夹,文件夹结构如下:
16 |
17 | ```
18 | -i-icon
19 | -js
20 | -- icon.js
21 | - i-icon.vue
22 | - readme.md
23 | ```
24 |
25 | 为了保证icon引入方便,我们可以利用easycom来自动引入:
26 | page.json:
27 |
28 | ```json
29 | "easycom": {
30 | "autoscan": true,
31 | "custom": {
32 | "^i-icon": "@/components/i-icon/i-icon.vue"
33 | }
34 | },
35 | ```
36 |
37 | 组件提供如下props参数:
38 |
39 | | props | 类型 | 说明 |
40 | | :-----| ----: | :----: |
41 | | name | String | 图标名 |
42 | | color | String | 颜色填充/red/#fff |
43 | | size | String | 大小:px/rpx/upx |
44 |
45 | 示例:
46 |
47 | ```html
48 |
49 | ```
50 |
51 | 图标类名请在[remixicon中搜索](https://remixicon.com/)
52 |
53 | 提示: 不要在name中写入图标库的前缀ri,组件中已经处理好前缀,不用担心类名冲突的问题
--------------------------------------------------------------------------------
/src/components/i-uniapp/i-input/i-input.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
13 |
14 |
15 |
16 |
35 |
36 |
48 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/content-security/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | const accessToken = require('get-accesstoken');
3 |
4 | // 封装检查的请求
5 | const handleCheck = async (url, data) => {
6 | const result = await uniCloud.httpclient.request(url, {
7 | method: 'POST',
8 | data,
9 | contentType: 'json',
10 | dataType: 'json'
11 | });
12 | if (result.status === 200) {
13 | return result.data;
14 | }
15 | };
16 | exports.main = async (event) => {
17 | // 默认值,默认平台微信,类型默认是文字段落
18 | // 其实云函数是可以直接获取运行平台的,但是此函数业务中不仅仅是要在小程序中用,会把云函数url化之后暴露给其他业务用,所以我们直接使用指定传参platform来进行处理
19 | const { platform = 'mp-weixin', content } = event;
20 | let requestUrl = '';
21 | let token = '';
22 | switch (platform) {
23 | case 'mp-weixin':
24 | token = await accessToken('wechat-miniprogram');
25 | requestUrl = `https://api.weixin.qq.com/wxa/msg_sec_check?access_token=${token}`;
26 | case 'mp-qq':
27 | token = await accessToken('qq-miniprogram');
28 | requestUrl = `https://api.q.qq.com/api/json/security/MsgSecCheck?access_token=${token}`;
29 | }
30 | return await handleCheck(requestUrl, {
31 | content
32 | });
33 | };
34 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/qq-robot/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const explain = require('explain');
4 | const path = require('path');
5 |
6 | exports.main = async (event, context) =>
7 | explain.run({
8 | event,
9 | context,
10 | startup: (app) => {
11 | app.init({
12 | baseDir: path.resolve(__dirname, 'dist'),
13 | serviceDir: '/services/'
14 | });
15 | app.route.add([
16 | {
17 | route: 'api/group',
18 | service: 'group',
19 | routes: [
20 | {
21 | route: 'postMessage',
22 | action: 'postMessage'
23 | },
24 | {
25 | route: 'getSampleQuestionList',
26 | action: 'getSampleQuestionList',
27 | httpMethod: 'GET'
28 | }
29 | ]
30 | },
31 | {
32 | route: 'api/callback',
33 | service: 'callback',
34 | routes: [
35 | {
36 | route: 'main',
37 | action: 'main',
38 | httpMethod: 'POST'
39 | }
40 | ]
41 | }
42 | ]);
43 | }
44 | });
45 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/database/uni-id-roles.schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "bsonType": "object",
3 | "required": ["role_id"],
4 | "permission": {
5 | "read": false,
6 | "create": false,
7 | "update": false,
8 | "delete": false
9 | },
10 | "properties": {
11 | "_id": {
12 | "description": "存储文档 ID,系统自动生成"
13 | },
14 | "role_id": {
15 | "title": "唯一ID",
16 | "bsonType": "string",
17 | "description": "角色唯一标识,不可修改,不允许重复",
18 | "trim": "both"
19 | },
20 | "role_name": {
21 | "title": "名称",
22 | "bsonType": "string",
23 | "description": "角色名称",
24 | "trim": "both"
25 | },
26 | "permission": {
27 | "title": "权限",
28 | "bsonType": "array",
29 | "foreignKey": "uni-id-permissions.permission_id",
30 | "description": "角色拥有的权限列表"
31 | },
32 | "comment": {
33 | "title": "备注",
34 | "bsonType": "string",
35 | "description": "备注",
36 | "trim": "both"
37 | },
38 | "create_date": {
39 | "bsonType": "timestamp",
40 | "description": "创建时间",
41 | "forceDefaultValue": {
42 | "$env": "now"
43 | }
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/uni_modules/uni-popup/components/uni-popup/popup.js:
--------------------------------------------------------------------------------
1 | import message from './message.js';
2 | // 定义 type 类型:弹出类型:top/bottom/center
3 | const config = {
4 | // 顶部弹出
5 | top: 'top',
6 | // 底部弹出
7 | bottom: 'bottom',
8 | // 居中弹出
9 | center: 'center',
10 | // 消息提示
11 | message: 'top',
12 | // 对话框
13 | dialog: 'center',
14 | // 分享
15 | share: 'bottom'
16 | };
17 |
18 | export default {
19 | data() {
20 | return {
21 | config: config,
22 | popupWidth: 0,
23 | popupHeight: 0
24 | };
25 | },
26 | mixins: [message],
27 | computed: {
28 | isDesktop() {
29 | return this.popupWidth >= 500 && this.popupHeight >= 500;
30 | }
31 | },
32 | mounted() {
33 | const fixSize = () => {
34 | const { windowWidth, windowHeight, windowTop } = uni.getSystemInfoSync();
35 | this.popupWidth = windowWidth;
36 | this.popupHeight = windowHeight + windowTop;
37 | };
38 | fixSize();
39 | // #ifdef H5
40 | window.addEventListener('resize', fixSize);
41 | this.$once('hook:beforeDestroy', () => {
42 | window.removeEventListener('resize', fixSize);
43 | });
44 | // #endif
45 | }
46 | };
47 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/database/uni-id-permissions.schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "bsonType": "object",
3 | "required": ["permission_id", "permission_name"],
4 | "properties": {
5 | "_id": {
6 | "description": "存储文档 ID,系统自动生成"
7 | },
8 | "permission_id": {
9 | "bsonType": "string",
10 | "description": "权限唯一标识,不可修改,不允许重复",
11 | "label": "权限标识",
12 | "trim": "both",
13 | "title": "权限ID",
14 | "component": {
15 | "name": "input"
16 | }
17 | },
18 | "permission_name": {
19 | "bsonType": "string",
20 | "description": "权限名称",
21 | "label": "权限名称",
22 | "title": "权限名称",
23 | "trim": "both",
24 | "component": {
25 | "name": "input"
26 | }
27 | },
28 | "comment": {
29 | "bsonType": "string",
30 | "description": "备注",
31 | "label": "备注",
32 | "title": "备注",
33 | "trim": "both",
34 | "component": {
35 | "name": "textarea"
36 | }
37 | },
38 | "create_date": {
39 | "bsonType": "timestamp",
40 | "description": "创建时间",
41 | "forceDefaultValue": {
42 | "$env": "now"
43 | }
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/common/explain/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 explain-unicloud
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | <%= htmlWebpackPlugin.options.title %>
8 |
9 |
16 |
17 |
18 |
19 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/database/questionExplanation.schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "bsonType": "object",
3 | "required": [],
4 | "permission": {
5 | "read": true,
6 | "create": false,
7 | "update": false,
8 | "delete": false
9 | },
10 | "properties": {
11 | "_id": {
12 | "description": "ID,系统自动生成"
13 | },
14 | "questionID": {
15 | "bsonType": "object",
16 | "foreignKey": "question._id"
17 | },
18 | "questionID.publishUserID": {
19 | "bsonType": "object",
20 | "foreignKey": "uni-id-users._id"
21 | },
22 | "userID": {
23 | "bsonType": "object",
24 | "foreignKey": "uni-id-users._id"
25 | },
26 | "content": {
27 | "bsonType": "string",
28 | "description": "解答内容"
29 | },
30 | "userAgreed": {
31 | "bsonType": "array",
32 | "description": "用户赞同"
33 | },
34 | "userDisagreed": {
35 | "bsonType": "array",
36 | "description": "用户不赞同"
37 | },
38 | "createDate": {
39 | "bsonType": "timestamp",
40 | "description": "创建时间"
41 | },
42 | "updateDate": {
43 | "bsonType": "timestamp",
44 | "description": "修改时间"
45 | },
46 | "deleteDate": {
47 | "bsonType": "timestamp",
48 | "description": "删除时间"
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/v1/proto/user.ts:
--------------------------------------------------------------------------------
1 | type _OtherLoginPlatformParams = {
2 | code: string;
3 | nickname: string;
4 | avatar: string;
5 | gender: number;
6 | };
7 |
8 | export type LoginByWechat = _OtherLoginPlatformParams;
9 | export type LoginByQQ = _OtherLoginPlatformParams;
10 |
11 | type _OtherBindPlatformParams = {
12 | code: string;
13 | uid: string;
14 | };
15 |
16 | export type BindWechat = _OtherBindPlatformParams;
17 | export type BindQQ = _OtherBindPlatformParams;
18 | export type BindMobile = _OtherBindPlatformParams & {
19 | mobile: string;
20 | };
21 |
22 | export interface LoginBySms {
23 | phone: string;
24 | code: string;
25 | }
26 |
27 | export interface UserLogout {
28 | token: string;
29 | }
30 |
31 | export interface UpdateUserInfo {
32 | nickname: string;
33 | avatar: string;
34 | gender: number;
35 | uid: string;
36 | sign: string;
37 | }
38 |
39 | export interface ResetPassword {
40 | id: string;
41 | password: string;
42 | }
43 |
44 | export interface CheckFollowers {
45 | uid: string;
46 | follower: string;
47 | }
48 |
49 | export interface SendSms {
50 | type: string;
51 | phone: string;
52 | }
53 |
54 | export interface CheckToken {
55 | token: string;
56 | }
57 |
58 | export interface GetUserContentByID {
59 | id: string;
60 | }
61 |
--------------------------------------------------------------------------------
/src/uni_modules/uni-popup/components/uni-popup/keypress.js:
--------------------------------------------------------------------------------
1 | // #ifdef H5
2 | export default {
3 | name: 'Keypress',
4 | props: {
5 | disable: {
6 | type: Boolean,
7 | default: false
8 | }
9 | },
10 | mounted() {
11 | const keyNames = {
12 | esc: ['Esc', 'Escape'],
13 | tab: 'Tab',
14 | enter: 'Enter',
15 | space: [' ', 'Spacebar'],
16 | up: ['Up', 'ArrowUp'],
17 | left: ['Left', 'ArrowLeft'],
18 | right: ['Right', 'ArrowRight'],
19 | down: ['Down', 'ArrowDown'],
20 | delete: ['Backspace', 'Delete', 'Del']
21 | };
22 | const listener = ($event) => {
23 | if (this.disable) {
24 | return;
25 | }
26 | const keyName = Object.keys(keyNames).find((key) => {
27 | const keyName = $event.key;
28 | const value = keyNames[key];
29 | return value === keyName || (Array.isArray(value) && value.includes(keyName));
30 | });
31 | if (keyName) {
32 | // 避免和其他按键事件冲突
33 | setTimeout(() => {
34 | this.$emit(keyName, {});
35 | }, 0);
36 | }
37 | };
38 | document.addEventListener('keyup', listener);
39 | this.$once('hook:beforeDestroy', () => {
40 | document.removeEventListener('keyup', listener);
41 | });
42 | },
43 | render: () => {}
44 | };
45 | // #endif
46 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/database/question.schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "bsonType": "object",
3 | "required": [],
4 | "permission": {
5 | "read": true,
6 | "create": false,
7 | "update": false,
8 | "delete": false
9 | },
10 | "properties": {
11 | "_id": {
12 | "description": "ID,系统自动生成"
13 | },
14 | "publishUserID": {
15 | "bsonType": "string",
16 | "foreignKey": "uni-id-users._id"
17 | },
18 | "tagID": {
19 | "bsonType": "array",
20 | "foreignKey": "questionTag._id"
21 | },
22 | "areaID": {
23 | "bsonType": "array",
24 | "foreignKey": "questionArea._id"
25 | },
26 | "title": {
27 | "bsonType": "string",
28 | "description": "标题"
29 | },
30 | "content": {
31 | "bsonType": "string",
32 | "description": "内容"
33 | },
34 | "state": {
35 | "bsonType": "string",
36 | "description": "状态"
37 | },
38 | "pageView": {
39 | "bsonType": "number",
40 | "description": "预览次数"
41 | },
42 | "createDate": {
43 | "bsonType": "timestamp",
44 | "description": "创建时间"
45 | },
46 | "updateDate": {
47 | "bsonType": "timestamp",
48 | "description": "修改时间"
49 | },
50 | "deleteDate": {
51 | "bsonType": "timestamp",
52 | "description": "删除时间"
53 | }
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/components/common/commonFill.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
11 | {{ title }}
12 | {{ tip }}
13 |
14 |
15 |
46 |
--------------------------------------------------------------------------------
/src/uni_modules/uni-popup/components/uni-popup-dialog/keypress.js:
--------------------------------------------------------------------------------
1 | // #ifdef H5
2 | export default {
3 | name: 'Keypress',
4 | props: {
5 | disable: {
6 | type: Boolean,
7 | default: false
8 | }
9 | },
10 | mounted() {
11 | const keyNames = {
12 | esc: ['Esc', 'Escape'],
13 | tab: 'Tab',
14 | enter: 'Enter',
15 | space: [' ', 'Spacebar'],
16 | up: ['Up', 'ArrowUp'],
17 | left: ['Left', 'ArrowLeft'],
18 | right: ['Right', 'ArrowRight'],
19 | down: ['Down', 'ArrowDown'],
20 | delete: ['Backspace', 'Delete', 'Del']
21 | };
22 | const listener = ($event) => {
23 | if (this.disable) {
24 | return;
25 | }
26 | const keyName = Object.keys(keyNames).find((key) => {
27 | const keyName = $event.key;
28 | const value = keyNames[key];
29 | return value === keyName || (Array.isArray(value) && value.includes(keyName));
30 | });
31 | if (keyName) {
32 | // 避免和其他按键事件冲突
33 | setTimeout(() => {
34 | this.$emit(keyName, {});
35 | }, 0);
36 | }
37 | };
38 | document.addEventListener('keyup', listener);
39 | this.$once('hook:beforeDestroy', () => {
40 | document.removeEventListener('keyup', listener);
41 | });
42 | },
43 | render: () => {}
44 | };
45 | // #endif
46 |
--------------------------------------------------------------------------------
/src/components/i-uniapp/i-icon/i-icon.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | {{icon[name]}}
4 |
5 |
6 |
43 |
59 |
--------------------------------------------------------------------------------
/src/components/i-uniapp/i-field/i-field.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
11 |
12 |
13 |
14 | {{ label }}
15 |
16 |
17 |
18 |
19 |
20 |
21 |
40 |
41 |
62 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/database/article.schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "bsonType": "object",
3 | "required": [],
4 | "permission": {
5 | "read": true,
6 | "create": false,
7 | "update": false,
8 | "delete": false
9 | },
10 | "properties": {
11 | "_id": {
12 | "description": "ID,系统自动生成"
13 | },
14 | "title": {
15 | "bsonType": "string",
16 | "description": "文章标题"
17 | },
18 | "content": {
19 | "bsonType": "string",
20 | "description": "文章内容"
21 | },
22 | "tagID": {
23 | "bsonType": "array",
24 | "description": "标签",
25 | "foreignKey": "questionTag._id"
26 | },
27 | "desc": {
28 | "bsonType": "string",
29 | "description": "描述",
30 | "foreignKey": "uni-id-users._id"
31 | },
32 | "userID": {
33 | "bsonType": "string",
34 | "description": "发布者用户",
35 | "foreignKey": "uni-id-users._id"
36 | },
37 | "state": {
38 | "bsonType": "string",
39 | "description": "状态"
40 | },
41 | "rejectReason": {
42 | "bsonType": "string",
43 | "description": "拒绝原因"
44 | },
45 | "createDate": {
46 | "bsonType": "timestamp",
47 | "description": "创建时间"
48 | },
49 | "updateDate": {
50 | "bsonType": "timestamp",
51 | "description": "修改时间"
52 | },
53 | "deleteDate": {
54 | "bsonType": "timestamp",
55 | "description": "删除时间"
56 | }
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/v1/src/controller/article.ts:
--------------------------------------------------------------------------------
1 | import * as explain from 'explain';
2 | import articleService from '../service/article';
3 | import * as IArticle from '../../proto/article';
4 |
5 | export = class ArticleController extends explain.service {
6 | private service: articleService;
7 | constructor(e: CloudData) {
8 | super(e);
9 | this.service = new articleService(this);
10 | }
11 | /**
12 | * @name 添加/发布文章
13 | * @param IArticle.AddArticle
14 | * @return {*} {Promise}
15 | * @link https://www.yuque.com/mlgrgm/lmm8g4/kif3lf#g13V0
16 | * @memberof ArticleController
17 | */
18 | async addArticle(): Promise {
19 | return await this.service.addArticle(this.event.data as IArticle.AddArticle);
20 | }
21 | /**
22 | * @name 修改文章
23 | * @param IArticle.UpdateArticle
24 | * @return {*} {Promise}
25 | * @memberof ArticleController
26 | */
27 | async updateArticle(): Promise {
28 | return await this.service.updateArticle(this.event.data as IArticle.UpdateArticle);
29 | }
30 | /**
31 | * @name 审核文章
32 | * @param IArticle.AuditArticle
33 | * @return {*} {Promise}
34 | * @link https://www.yuque.com/mlgrgm/lmm8g4/kif3lf#zJelt
35 | * @memberof ArticleController
36 | */
37 | async auditArticle(): Promise {
38 | return await this.service.auditArticle(this.event.data as IArticle.AuditArticle);
39 | }
40 | };
41 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/database/opendb-admin-menus.schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "bsonType": "object",
3 | "permission": {
4 | "read": true,
5 | "create": false,
6 | "update": false,
7 | "delete": false
8 | },
9 | "required": ["name", "menu_id"],
10 | "properties": {
11 | "_id": {
12 | "description": "存储文档 ID,系统自动生成"
13 | },
14 | "menu_id": {
15 | "bsonType": "string",
16 | "description": "菜单项的ID,不可重复",
17 | "trim": "both"
18 | },
19 | "name": {
20 | "bsonType": "string",
21 | "description": "菜单名称",
22 | "trim": "both"
23 | },
24 | "icon": {
25 | "bsonType": "string",
26 | "description": "菜单图标",
27 | "trim": "both"
28 | },
29 | "url": {
30 | "bsonType": "string",
31 | "description": "菜单url",
32 | "trim": "both"
33 | },
34 | "sort": {
35 | "bsonType": "int",
36 | "description": "菜单序号(越大越靠后)"
37 | },
38 | "parent_id": {
39 | "bsonType": "string",
40 | "description": "父级菜单Id",
41 | "parentKey": "menu_id"
42 | },
43 | "permission": {
44 | "bsonType": "array",
45 | "description": "菜单权限列表"
46 | },
47 | "enable": {
48 | "bsonType": "bool",
49 | "description": "是否启用菜单,true启用、false禁用"
50 | },
51 | "create_date": {
52 | "bsonType": "timestamp",
53 | "description": "菜单创建时间",
54 | "forceDefaultValue": {
55 | "$env": "now"
56 | }
57 | }
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/common/explain-cache/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | const explain = require('explain'),
3 | db = uniCloud.database(),
4 | dbCmd = db.command,
5 | dbColl = db.collection('explain-cache');
6 | module.exports = class e {
7 | static async set({ key: e, value: t, expire: a = 7200 }) {
8 | if (!e) throw new Error('key无效');
9 | let i = explain.dateTime.now(),
10 | l = explain.dateTime.addSeconds(i, a),
11 | r = await dbColl.where({ key: e }).update({ value: t, set_time: i, expire_time: l });
12 | if (!r.updated)
13 | try {
14 | await dbColl.add({ key: e, value: t, set_time: i, expire_time: l });
15 | } catch (e) {
16 | if (!e.message.includes('E11000 duplicate key error')) return !1;
17 | }
18 | return !0;
19 | }
20 | static async get(t) {
21 | let a = await dbColl.where({ key: t }).get(),
22 | i = a.data[0];
23 | return i ? (i.expire_time > explain.dateTime.now() ? i.value : (await e.remove(t), null)) : null;
24 | }
25 | static async remove(e) {
26 | if (!e) throw new Error('key无效');
27 | let t = await dbColl.where({ key: e }).remove();
28 | return t.deleted > 0;
29 | }
30 | static async clearAll() {
31 | var e = await dbColl.where({ _id: dbCmd.exists(!0) }).remove();
32 | return e.deleted;
33 | }
34 | static async clearTimeout() {
35 | var e = await dbColl.where({ expire_time: dbCmd.lte(explain.dateTime.now()) }).remove();
36 | return e.deleted;
37 | }
38 | };
39 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/common/get-accesstoken/index.js:
--------------------------------------------------------------------------------
1 | const createConfig = require('uni-config-center');
2 |
3 | const uniIDConfig = createConfig({
4 | pluginId: 'uni-id'
5 | });
6 |
7 | const explain = require('explain');
8 | explain.cache = require('explain-cache');
9 |
10 | // 封装交换accesstoken的逻辑
11 | const getAccessToken = async (url, type) => {
12 | const result = await uniCloud.httpclient.request(url, {
13 | method: 'GET',
14 | dataType: 'json'
15 | });
16 | if (result.status === 200) {
17 | // 请求成功之后存储accesstoken
18 | await explain.cache.set({
19 | key: type + '-accesstoken',
20 | value: result.data.access_token,
21 | expire: result.data.expires_in
22 | });
23 | return result.data.access_token;
24 | }
25 | };
26 | module.exports = async function (type) {
27 | const config = uniIDConfig.config();
28 | // 判断缓存中是否存在
29 | const res = await explain.cache.get(type + '-accesstoken');
30 | if (res) {
31 | return res;
32 | }
33 | const requestUrlRoles = {
34 | 'wechat-miniprogram': `https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${config['mp-weixin']['oauth']['weixin'].appid}&secret=${config['mp-weixin']['oauth']['weixin'].appsecret}`,
35 | 'qq-miniprogram': `https://api.q.qq.com/api/getToken?grant_type=client_credential&appid=${config['mp-qq']['oauth']['qq'].appid}&secret=${config['mp-qq']['oauth']['qq'].appsecret}`
36 | };
37 | return await getAccessToken(requestUrlRoles[type], type);
38 | };
39 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/uni-analyse-searchhot/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | exports.main = async () => {
3 | /**
4 | * 根据搜索记录,设定时间间隔来归纳出热搜数据并存储在热搜表中
5 | */
6 | const SEARCHHOT = 'opendb-search-hot'; // 热搜数据库名称
7 | const SEARCHLOG = 'opendb-search-log'; // 搜索记录数据库名称
8 | const SEARCHLOG_timeZone = 604800000; // 归纳搜索记录时间间隔,毫秒数,默认为最近7天
9 | const SEARCHHOT_size = 10; // 热搜条数
10 |
11 | const DB = uniCloud.database();
12 | const DBCmd = DB.command;
13 | const $ = DB.command.aggregate;
14 | const SEARCHHOT_db = DB.collection(SEARCHHOT);
15 | const SEARCHLOG_db = DB.collection(SEARCHLOG);
16 | const timeEnd = Date.now() - SEARCHLOG_timeZone;
17 |
18 | let { data: searchHotData } = await SEARCHLOG_db.aggregate()
19 | .match({
20 | create_date: DBCmd.gt(timeEnd)
21 | })
22 | .group({
23 | _id: {
24 | content: '$content'
25 | },
26 | count: $.sum(1)
27 | })
28 | .replaceRoot({
29 | newRoot: $.mergeObjects(['$_id', '$$ROOT'])
30 | })
31 | .project({
32 | _id: false
33 | })
34 | .sort({
35 | count: -1
36 | })
37 | .end();
38 |
39 | let now = Date.now();
40 | searchHotData
41 | .map((item) => {
42 | item.create_date = now;
43 | return item;
44 | })
45 | .slice(0, SEARCHHOT_size);
46 | await SEARCHHOT_db.remove();
47 | // searchHotData = searchHotData.sort((a, b) => b.count - a.count).slice(0, SEARCHHOT_size);
48 | return searchHotData.length ? await SEARCHHOT_db.add(searchHotData) : '';
49 | };
50 |
--------------------------------------------------------------------------------
/src/uni_modules/robin-editor/components/robin-editor-header/robin-editor-header.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | {{ labelCancel }}
4 | {{ labelConfirm }}
5 |
6 |
7 |
8 |
31 |
32 |
59 |
--------------------------------------------------------------------------------
/src/api/search.ts:
--------------------------------------------------------------------------------
1 | import request from '../common/request';
2 | import { arrObjectUnique } from '../util/common';
3 | const db = uniCloud.database();
4 |
5 | /**
6 | * 搜索功能
7 | * @param params
8 | * @returns
9 | */
10 | export async function search(params: { searchText: string; limit: number; page: number }): Promise {
11 | const { limit, page } = params;
12 | const res = await db
13 | .collection('question')
14 | .aggregate()
15 | .match({
16 | title: new RegExp(params.searchText, 'gi')
17 | })
18 | .sort({
19 | createDate: -1
20 | })
21 | .skip(limit * (page - 1))
22 | .limit(limit)
23 | .end();
24 | return {
25 | ...res,
26 | data: res.result.data
27 | };
28 | }
29 |
30 | /**
31 | * @name 增加搜索结果,后端需要拿到搜索结果去生成热搜词
32 | * @param params
33 | * @returns
34 | */
35 | export async function addSearchLog(params: { content: string; user_id?: string; device_id?: string }): Promise {
36 | return await request({
37 | route: `api/search/addSeachLog`,
38 | method: 'POST',
39 | data: params
40 | });
41 | }
42 |
43 | /**
44 | * @name 获取热搜词
45 | * @param params
46 | */
47 | export async function getHotSearchWordList(): Promise {
48 | const res = await db
49 | .collection('opendb-search-hot')
50 | .aggregate()
51 | .sort({
52 | create_date: -1,
53 | count: -1
54 | })
55 | .skip(0)
56 | .limit(50)
57 | .end();
58 | return {
59 | ...res,
60 | data: arrObjectUnique(res.result.data, 'content').slice(0, 15)
61 | };
62 | }
63 |
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | const plugins = [];
2 |
3 | if (process.env.UNI_OPT_TREESHAKINGNG) {
4 | plugins.push(require('@dcloudio/vue-cli-plugin-uni-optimize/packages/babel-plugin-uni-api/index.js'));
5 | }
6 |
7 | if ((process.env.UNI_PLATFORM === 'app-plus' && process.env.UNI_USING_V8) || (process.env.UNI_PLATFORM === 'h5' && process.env.UNI_H5_BROWSER === 'builtin')) {
8 | const path = require('path');
9 |
10 | const isWin = /^win/.test(process.platform);
11 |
12 | const normalizePath = (path) => (isWin ? path.replace(/\\/g, '/') : path);
13 |
14 | const input = normalizePath(process.env.UNI_INPUT_DIR);
15 | try {
16 | plugins.push([
17 | require('@dcloudio/vue-cli-plugin-hbuilderx/packages/babel-plugin-console'),
18 | {
19 | file(file) {
20 | file = normalizePath(file);
21 | if (file.indexOf(input) === 0) {
22 | return path.relative(input, file);
23 | }
24 | return false;
25 | }
26 | }
27 | ]);
28 | } catch (e) {}
29 | }
30 |
31 | process.UNI_LIBRARIES = process.UNI_LIBRARIES || ['@dcloudio/uni-ui'];
32 | process.UNI_LIBRARIES.forEach((libraryName) => {
33 | plugins.push([
34 | 'import',
35 | {
36 | libraryName: libraryName,
37 | customName: (name) => {
38 | return `${libraryName}/lib/${name}/${name}`;
39 | }
40 | }
41 | ]);
42 | });
43 | module.exports = {
44 | presets: [
45 | [
46 | '@vue/app',
47 | {
48 | useBuiltIns: process.env.UNI_PLATFORM === 'h5' ? 'usage' : 'entry'
49 | }
50 | ]
51 | ],
52 | plugins
53 | };
54 |
--------------------------------------------------------------------------------
/src/util/common.ts:
--------------------------------------------------------------------------------
1 | export const removeHtmlTag = (htmlStr: string): string => {
2 | return htmlStr.replace(/<[^>]+>/gi, '');
3 | };
4 |
5 | // 对象数组去重
6 | export const arrObjectUnique = (arr: unknown[], key: string): unknown[] => {
7 | const temp = {};
8 | for (const k in arr) {
9 | if (arr[k][key] && !temp[arr[k][key]]) {
10 | temp[arr[k][key]] = arr[k];
11 | }
12 | }
13 | return Object.values(temp);
14 | };
15 |
16 | // 数组去重
17 | export const arrUnique = (arr: unknown[]): unknown[] => {
18 | for (let i = arr.length - 1; i >= 0; i--) {
19 | const curIndex = arr.indexOf(arr[i]);
20 | const lastIndex = arr.lastIndexOf(arr[i]);
21 | curIndex != lastIndex && arr.splice(lastIndex, 1);
22 | }
23 | return arr;
24 | };
25 |
26 | // 节流
27 | // 防抖
28 | /**
29 | *
30 | * @param {要执行的函数} fn
31 | * @param {在操作多长时间后可再执行,第一次立即执行} interval
32 | */
33 | export function debounce(fn: () => void, interval: number): () => void {
34 | const _self = fn;
35 | let timer = null;
36 | let first = true;
37 |
38 | return function () {
39 | // eslint-disable-next-line prefer-rest-params
40 | const args = arguments;
41 | // eslint-disable-next-line @typescript-eslint/no-this-alias
42 | const _me = this;
43 | if (first) {
44 | first = false;
45 | _self.apply(_me, args);
46 | }
47 |
48 | if (timer) {
49 | clearTimeout(timer);
50 | // return false;
51 | }
52 |
53 | timer = setTimeout(function () {
54 | clearTimeout(timer);
55 | timer = null;
56 | _self.apply(_me, args);
57 | }, interval);
58 | };
59 | }
60 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/common/we-chat-api/index.js:
--------------------------------------------------------------------------------
1 | let httpclient = uniCloud.httpclient;
2 |
3 | // 微信测试号配置
4 | let APPID = 'wx08adc1165170fb39';
5 | let APPSECRET = 'c6f17c25e4b6ff3d92e8af902c4f2f8d';
6 |
7 | /**
8 | * 获取微信服务器token,这里需要进行缓存机制,因为不能每个请求都要调用一次API,次数有限,缓存两个小时
9 | * https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Get_access_token.html
10 | */
11 | async function getAccessToken() {
12 | let url = `https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${APPID}&secret=${APPSECRET}`;
13 |
14 | const response = await httpclient.request(url, {
15 | method: 'GET',
16 | dataType: 'json'
17 | });
18 | const data = response.data;
19 |
20 | return data.access_token;
21 | }
22 |
23 | /**
24 | * 发送一个模板消息
25 | * @alias https://mp.weixin.qq.com/debug/cgi-bin/readtmpl?t=tmplmsg/faq_tmpl
26 | * @param {Object} data 需要发送的数据,格式如下,自行组装
27 | {
28 | "touser":"OPENID",
29 | "template_id":"ngqIpbwh8bUfcSsECmogfXcV14J0tQlEpBO27izEYtY",
30 | "url":"http://weixin.qq.com/download",
31 | "topcolor":"#FF0000",
32 | "data":Object{...}
33 | }
34 | *
35 | */
36 | async function sendTemplate(data) {
37 | let access_token = await getAccessToken();
38 | let url = `https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=${access_token}`;
39 |
40 | const response = await httpclient.request(url, {
41 | method: 'POST',
42 | dataType: 'json',
43 | contentType: 'json',
44 | data: data
45 | });
46 | return response.data;
47 | }
48 |
49 | module.exports = {
50 | getAccessToken,
51 | sendTemplate
52 | };
53 |
--------------------------------------------------------------------------------
/src/api/common.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * @name 客户端直传云存储(阿里云)
3 | * @param params
4 | * @doc https://uniapp.dcloud.io/uniCloud/storage?id=uploadfile
5 | */
6 | export function uploadFileToCloudStorage(params: { filePath: string; cloudPath: string }): Promise {
7 | return new Promise((resolve) => {
8 | const { filePath, cloudPath } = params;
9 | // 获取当前时间戳
10 | const timestamp: number = new Date().getTime();
11 | // 获取file的后缀文件类型名
12 | const typeName = filePath.substr(filePath.lastIndexOf('.'));
13 | uniCloud
14 | .uploadFile({
15 | filePath,
16 | cloudPath: cloudPath + `.${timestamp}${typeName}`
17 | })
18 | .then((res) =>
19 | resolve({
20 | success: true,
21 | data: res
22 | })
23 | )
24 | .catch((err) => {
25 | resolve({
26 | success: false,
27 | data: err
28 | });
29 | });
30 | });
31 | }
32 |
33 | /**
34 | * @name 内容安全函数,调用即可检测内容是否有违规字段
35 | * @param params
36 | * @returns
37 | */
38 | export async function checkContentSecurity(params: { content: string }): Promise<
39 | ActionResult<{
40 | errCode: number;
41 | errMsg: string;
42 | }>
43 | > {
44 | let platform = '';
45 | // #ifdef MP-WEIXIN
46 | platform = 'mp-weixin';
47 | // #endif
48 | // #ifdef MP-QQ
49 | platform = 'mp-qq';
50 | // #endif
51 | const res = await uniCloud.callFunction<{
52 | errCode: number;
53 | errMsg: string;
54 | }>({
55 | name: 'content-security',
56 | data: {
57 | content: params.content,
58 | platform
59 | }
60 | });
61 | return {
62 | ...res,
63 | data: res.result
64 | };
65 | }
66 |
--------------------------------------------------------------------------------
/src/uni_modules/menu-drawer/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "id": "menu-drawer",
3 | "displayName": "menu-drawer",
4 | "version": "1.0.0",
5 | "description": "menu-drawer",
6 | "keywords": [
7 | "menu-drawer"
8 | ],
9 | "repository": "",
10 | "engines": {
11 | "HBuilderX": "^3.1.0"
12 | },
13 | "dcloudext": {
14 | "category": [
15 | "前端组件",
16 | "通用组件"
17 | ],
18 | "sale": {
19 | "regular": {
20 | "price": "0.00"
21 | },
22 | "sourcecode": {
23 | "price": "0.00"
24 | }
25 | },
26 | "contact": {
27 | "qq": ""
28 | },
29 | "declaration": {
30 | "ads": "",
31 | "data": "",
32 | "permissions": ""
33 | },
34 | "npmurl": ""
35 | },
36 | "uni_modules": {
37 | "dependencies": [],
38 | "encrypt": [],
39 | "platforms": {
40 | "cloud": {
41 | "tcb": "u",
42 | "aliyun": "u"
43 | },
44 | "client": {
45 | "App": {
46 | "app-vue": "u",
47 | "app-nvue": "u"
48 | },
49 | "H5-mobile": {
50 | "Safari": "u",
51 | "Android Browser": "u",
52 | "微信浏览器(Android)": "u",
53 | "QQ浏览器(Android)": "u"
54 | },
55 | "H5-pc": {
56 | "Chrome": "u",
57 | "IE": "u",
58 | "Edge": "u",
59 | "Firefox": "u",
60 | "Safari": "u"
61 | },
62 | "小程序": {
63 | "微信": "u",
64 | "阿里": "u",
65 | "百度": "u",
66 | "字节跳动": "u",
67 | "QQ": "u"
68 | },
69 | "快应用": {
70 | "华为": "u",
71 | "联盟": "u"
72 | }
73 | }
74 | }
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/v1/src/service/article.ts:
--------------------------------------------------------------------------------
1 | import * as IArticle from '../../proto/article';
2 | const db = uniCloud.database();
3 | const collection = db.collection('article');
4 |
5 | export default class ArticleService {
6 | public userID: string;
7 | public nowDate: string;
8 | constructor(data: CloudData) {
9 | this.userID = data.context.userID;
10 | this.nowDate = new Date().toISOString();
11 | }
12 | async addArticle(params: IArticle.AddArticle): Promise {
13 | // 调用钉钉通知函数
14 | uniCloud.callFunction({
15 | name: 'dingtalk-robot',
16 | data: {
17 | content: `有一篇新的文章待审核:《${params.title}》`
18 | }
19 | });
20 | // 入库
21 | return await collection.add({
22 | title: params.title,
23 | content: params.content,
24 | tagID: params.tagID,
25 | desc: params.desc,
26 | userID: this.userID,
27 | state: 'onlist',
28 | createDate: this.nowDate,
29 | updateDate: this.nowDate,
30 | deleteDate: ''
31 | });
32 | }
33 | async updateArticle(params: IArticle.UpdateArticle): Promise {
34 | return await collection.doc(params.id).update({
35 | title: params.title,
36 | content: params.content,
37 | tagID: params.tagID,
38 | updateDate: this.nowDate
39 | });
40 | }
41 | async auditArticle(params: IArticle.AuditArticle): Promise {
42 | const updateParams: Omit = {
43 | state: params.state
44 | };
45 | // 判断state如果是拒绝,就入库填写原因
46 | if (params.state === 'reject') {
47 | updateParams['rejectReason'] = params.rejectReason || '原因暂无';
48 | }
49 | return collection.doc(params.id).update(updateParams);
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/uni-id-cf/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "uni-id-cf",
3 | "version": "1.0.0",
4 | "lockfileVersion": 2,
5 | "requires": true,
6 | "packages": {
7 | "": {
8 | "name": "uni-id-cf",
9 | "version": "1.0.0",
10 | "license": "ISC",
11 | "dependencies": {
12 | "uni-captcha": "file:../common/uni-captcha",
13 | "uni-config-center": "file:../common/uni-config-center",
14 | "uni-id": "file:../common/uni-id"
15 | }
16 | },
17 | "../common/uni-captcha": {
18 | "version": "0.0.3",
19 | "license": "Apache-2.0"
20 | },
21 | "../common/uni-config-center": {
22 | "version": "0.0.2",
23 | "engines": {
24 | "HBuilderX": "^3.1.0"
25 | }
26 | },
27 | "../common/uni-id": {
28 | "version": "3.3.5",
29 | "license": "Apache-2.0",
30 | "dependencies": {
31 | "uni-config-center": "file:../uni-config-center"
32 | }
33 | },
34 | "node_modules/uni-captcha": {
35 | "resolved": "../common/uni-captcha",
36 | "link": true
37 | },
38 | "node_modules/uni-config-center": {
39 | "resolved": "../common/uni-config-center",
40 | "link": true
41 | },
42 | "node_modules/uni-id": {
43 | "resolved": "../common/uni-id",
44 | "link": true
45 | }
46 | },
47 | "dependencies": {
48 | "uni-captcha": {
49 | "version": "file:../common/uni-captcha"
50 | },
51 | "uni-config-center": {
52 | "version": "file:../common/uni-config-center"
53 | },
54 | "uni-id": {
55 | "version": "file:../common/uni-id",
56 | "requires": {
57 | "uni-config-center": "file:../uni-config-center"
58 | }
59 | }
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/v1/src/service/questionArea.ts:
--------------------------------------------------------------------------------
1 | const db = uniCloud.database();
2 | const collection = db.collection('questionArea');
3 | import * as IQuestionArea from '../../proto/questionArea';
4 | export default class QuestionArea {
5 | public userID: string;
6 | public nowDate: string;
7 | constructor(data: CloudData) {
8 | this.userID = data.context.userID;
9 | this.nowDate = new Date().toISOString();
10 | }
11 | async getAreaList(params: IQuestionArea.GetAreaList): Promise {
12 | const { limit, page } = params;
13 | const whereParams = {
14 | deleteDate: ''
15 | };
16 | const data = await collection
17 | .aggregate()
18 | .match(whereParams)
19 | .skip(limit * (page - 1))
20 | .limit(limit)
21 | .end();
22 | // 获取数量
23 | const countResult = await collection.where(whereParams).count();
24 | return {
25 | list: data.data,
26 | count: countResult.total
27 | };
28 | }
29 | async addQuestionArea(params: IQuestionArea.AddQuestionArea): Promise {
30 | const { name, iconPath } = params;
31 | return await collection.add({
32 | name,
33 | iconPath,
34 | createDate: this.nowDate,
35 | updateDate: this.nowDate,
36 | deleteDate: ''
37 | });
38 | }
39 | async updateQuestionArea(params: IQuestionArea.UpdateQuestionArea): Promise {
40 | const { name, iconPath } = params;
41 | return await collection.doc(params._id).update({
42 | name,
43 | iconPath,
44 | updateDate: this.nowDate
45 | });
46 | }
47 | async deleteQuestionArea(params: IQuestionArea.DeleteQuestionArea): Promise {
48 | return await collection.doc(params._id).update({
49 | updateDate: this.nowDate,
50 | deleteDate: this.nowDate
51 | });
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/uni_modules/robin-editor/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "id": "robin-editor",
3 | "displayName": "robin-editor",
4 | "version": "2.0.0",
5 | "description": "基于原生editor组件的富文本编辑器组件,支持颜色选择,插入图片",
6 | "keywords": [
7 | "robin-editor",
8 | "编辑器",
9 | "富文本",
10 | "小程序"
11 | ],
12 | "repository": "https://github.com/health901/uniapp-editor",
13 | "engines": {
14 | "HBuilderX": "^3.1.0"
15 | },
16 | "dcloudext": {
17 | "category": [
18 | "前端组件",
19 | "通用组件"
20 | ],
21 | "sale": {
22 | "regular": {
23 | "price": "0.00"
24 | },
25 | "sourcecode": {
26 | "price": "0.00"
27 | }
28 | },
29 | "contact": {
30 | "qq": ""
31 | },
32 | "declaration": {
33 | "ads": "无",
34 | "data": "无",
35 | "permissions": "无"
36 | },
37 | "npmurl": ""
38 | },
39 | "uni_modules": {
40 | "dependencies": [
41 | "uni-popup"
42 | ],
43 | "encrypt": [],
44 | "platforms": {
45 | "cloud": {
46 | "tcb": "y",
47 | "aliyun": "y"
48 | },
49 | "client": {
50 | "App": {
51 | "app-vue": "u",
52 | "app-nvue": "u"
53 | },
54 | "H5-mobile": {
55 | "Safari": "y",
56 | "Android Browser": "y",
57 | "微信浏览器(Android)": "y",
58 | "QQ浏览器(Android)": "y"
59 | },
60 | "H5-pc": {
61 | "Chrome": "y",
62 | "IE": "y",
63 | "Edge": "y",
64 | "Firefox": "y",
65 | "Safari": "u"
66 | },
67 | "小程序": {
68 | "微信": "y",
69 | "阿里": "u",
70 | "百度": "u",
71 | "字节跳动": "u",
72 | "QQ": "u"
73 | },
74 | "快应用": {
75 | "华为": "u",
76 | "联盟": "u"
77 | }
78 | }
79 | }
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/common/uni-config-center/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "id": "uni-config-center",
3 | "name": "uni-config-center",
4 | "displayName": "uni-config-center",
5 | "version": "0.0.2",
6 | "description": "uniCloud 配置中心",
7 | "keywords": [
8 | "配置",
9 | "配置中心"
10 | ],
11 | "repository": "",
12 | "engines": {
13 | "HBuilderX": "^3.1.0"
14 | },
15 | "dcloudext": {
16 | "category": [
17 | "uniCloud",
18 | "云函数模板"
19 | ],
20 | "sale": {
21 | "regular": {
22 | "price": "0.00"
23 | },
24 | "sourcecode": {
25 | "price": "0.00"
26 | }
27 | },
28 | "contact": {
29 | "qq": ""
30 | },
31 | "declaration": {
32 | "ads": "无",
33 | "data": "无",
34 | "permissions": "无"
35 | },
36 | "npmurl": ""
37 | },
38 | "directories": {
39 | "example": "../../../scripts/dist"
40 | },
41 | "uni_modules": {
42 | "dependencies": [],
43 | "encrypt": [],
44 | "platforms": {
45 | "cloud": {
46 | "tcb": "y",
47 | "aliyun": "y"
48 | },
49 | "client": {
50 | "App": {
51 | "app-vue": "u",
52 | "app-nvue": "u"
53 | },
54 | "H5-mobile": {
55 | "Safari": "u",
56 | "Android Browser": "u",
57 | "微信浏览器(Android)": "u",
58 | "QQ浏览器(Android)": "u"
59 | },
60 | "H5-pc": {
61 | "Chrome": "u",
62 | "IE": "u",
63 | "Edge": "u",
64 | "Firefox": "u",
65 | "Safari": "u"
66 | },
67 | "小程序": {
68 | "微信": "u",
69 | "阿里": "u",
70 | "百度": "u",
71 | "字节跳动": "u",
72 | "QQ": "u"
73 | },
74 | "快应用": {
75 | "华为": "u",
76 | "联盟": "u"
77 | }
78 | }
79 | }
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/dingtalk-robot/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "dingtalk-robot",
3 | "version": "1.0.0",
4 | "lockfileVersion": 1,
5 | "requires": true,
6 | "dependencies": {
7 | "axios": {
8 | "version": "0.19.2",
9 | "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz",
10 | "integrity": "sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==",
11 | "requires": {
12 | "follow-redirects": "1.5.10"
13 | }
14 | },
15 | "debug": {
16 | "version": "3.1.0",
17 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
18 | "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
19 | "requires": {
20 | "ms": "2.0.0"
21 | }
22 | },
23 | "dingtalk-robot-sender": {
24 | "version": "1.2.0",
25 | "resolved": "https://registry.npmjs.org/dingtalk-robot-sender/-/dingtalk-robot-sender-1.2.0.tgz",
26 | "integrity": "sha512-sLSZpjXYz+VpWvuCoOnhPTnIFcVYBdNEGSEQqjYwb09YUmiNUtvhT/VftOxAkfhNykOjmQ4lSY+90lVWErThbw==",
27 | "requires": {
28 | "axios": "^0.19.0"
29 | }
30 | },
31 | "follow-redirects": {
32 | "version": "1.5.10",
33 | "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz",
34 | "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==",
35 | "requires": {
36 | "debug": "=3.1.0"
37 | }
38 | },
39 | "ms": {
40 | "version": "2.0.0",
41 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
42 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
43 | },
44 | "uni-config-center": {
45 | "version": "file:../common/uni-config-center"
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/v1/src/router/user.ts:
--------------------------------------------------------------------------------
1 | const router: CloudRouter = {
2 | route: 'api/user',
3 | service: 'user',
4 | routes: [
5 | {
6 | route: 'loginBySms',
7 | httpMethod: 'POST',
8 | action: 'loginBySms'
9 | },
10 | {
11 | route: 'sendSms',
12 | httpMethod: 'POST',
13 | action: 'sendSms'
14 | },
15 | {
16 | route: 'loginByWechat',
17 | httpMethod: 'POST',
18 | action: 'loginByWechat'
19 | },
20 | {
21 | route: 'bindWechat',
22 | httpMethod: 'POST',
23 | action: 'bindWechat'
24 | },
25 | {
26 | route: 'loginByQQ',
27 | httpMethod: 'POST',
28 | action: 'loginByQQ'
29 | },
30 | {
31 | route: 'bindQQ',
32 | httpMethod: 'POST',
33 | action: 'bindQQ'
34 | },
35 | {
36 | route: 'bindMobile',
37 | httpMethod: 'POST',
38 | action: 'bindMobile'
39 | },
40 | {
41 | route: 'userLogout',
42 | httpMethod: 'GET',
43 | action: 'userLogout'
44 | },
45 | {
46 | route: 'resetPassword',
47 | httpMethod: 'POST',
48 | action: 'resetPassword'
49 | },
50 | {
51 | route: 'checkToken',
52 | httpMethod: 'GET',
53 | action: 'checkToken'
54 | },
55 | {
56 | route: 'getUserContentByToken',
57 | httpMethod: 'GET',
58 | action: 'getUserContentByToken'
59 | },
60 | {
61 | route: 'getUserContentByID',
62 | httpMethod: 'GET',
63 | action: 'getUserContentByID'
64 | },
65 | {
66 | action: 'updateUserInfo'
67 | },
68 | {
69 | route: 'checkFollowers',
70 | action: 'checkFollowers',
71 | httpMethod: 'PUT'
72 | },
73 | {
74 | route: 'resetRequestNumber',
75 | action: 'resetRequestNumber',
76 | httpMethod: 'POST'
77 | }
78 | ]
79 | };
80 |
81 | export = router;
82 |
--------------------------------------------------------------------------------
/src/uni_modules/uni-icons/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "id": "uni-icons",
3 | "displayName": "uni-icons 图标",
4 | "version": "1.1.5",
5 | "description": "图标组件,用于展示移动端常见的图标,可自定义颜色、大小。",
6 | "keywords": [
7 | "uni-ui",
8 | "uniui",
9 | "icon",
10 | "图标"
11 | ],
12 | "repository": "https://github.com/dcloudio/uni-ui",
13 | "engines": {
14 | "HBuilderX": ""
15 | },
16 | "directories": {
17 | "example": "../../temps/example_temps"
18 | },
19 | "dcloudext": {
20 | "category": [
21 | "前端组件",
22 | "通用组件"
23 | ],
24 | "sale": {
25 | "regular": {
26 | "price": "0.00"
27 | },
28 | "sourcecode": {
29 | "price": "0.00"
30 | }
31 | },
32 | "contact": {
33 | "qq": ""
34 | },
35 | "declaration": {
36 | "ads": "无",
37 | "data": "无",
38 | "permissions": "无"
39 | },
40 | "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
41 | },
42 | "uni_modules": {
43 | "dependencies": [],
44 | "encrypt": [],
45 | "platforms": {
46 | "cloud": {
47 | "tcb": "y",
48 | "aliyun": "y"
49 | },
50 | "client": {
51 | "App": {
52 | "app-vue": "y",
53 | "app-nvue": "y"
54 | },
55 | "H5-mobile": {
56 | "Safari": "y",
57 | "Android Browser": "y",
58 | "微信浏览器(Android)": "y",
59 | "QQ浏览器(Android)": "y"
60 | },
61 | "H5-pc": {
62 | "Chrome": "y",
63 | "IE": "y",
64 | "Edge": "y",
65 | "Firefox": "y",
66 | "Safari": "y"
67 | },
68 | "小程序": {
69 | "微信": "y",
70 | "阿里": "y",
71 | "百度": "y",
72 | "字节跳动": "y",
73 | "QQ": "y"
74 | },
75 | "快应用": {
76 | "华为": "u",
77 | "联盟": "u"
78 | }
79 | }
80 | }
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/src/uni_modules/uni-transition/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "id": "uni-transition",
3 | "displayName": "Transition 过渡动画",
4 | "version": "1.0.2",
5 | "description": "元素的简单过渡动画",
6 | "keywords": [
7 | "动画",
8 | "过渡",
9 | "uni-transition",
10 | "过渡动画"
11 | ],
12 | "repository": "https://github.com/dcloudio/uni-ui",
13 | "engines": {
14 | "HBuilderX": ""
15 | },
16 | "directories": {
17 | "example": "../../temps/example_temps"
18 | },
19 | "dcloudext": {
20 | "category": [
21 | "前端组件",
22 | "通用组件"
23 | ],
24 | "sale": {
25 | "regular": {
26 | "price": "0.00"
27 | },
28 | "sourcecode": {
29 | "price": "0.00"
30 | }
31 | },
32 | "contact": {
33 | "qq": ""
34 | },
35 | "declaration": {
36 | "ads": "无",
37 | "data": "无",
38 | "permissions": "无"
39 | },
40 | "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
41 | },
42 | "uni_modules": {
43 | "dependencies": [],
44 | "encrypt": [],
45 | "platforms": {
46 | "cloud": {
47 | "tcb": "y",
48 | "aliyun": "y"
49 | },
50 | "client": {
51 | "App": {
52 | "app-vue": "y",
53 | "app-nvue": "y"
54 | },
55 | "H5-mobile": {
56 | "Safari": "y",
57 | "Android Browser": "y",
58 | "微信浏览器(Android)": "y",
59 | "QQ浏览器(Android)": "y"
60 | },
61 | "H5-pc": {
62 | "Chrome": "y",
63 | "IE": "y",
64 | "Edge": "y",
65 | "Firefox": "y",
66 | "Safari": "y"
67 | },
68 | "小程序": {
69 | "微信": "y",
70 | "阿里": "y",
71 | "百度": "y",
72 | "字节跳动": "y",
73 | "QQ": "y"
74 | },
75 | "快应用": {
76 | "华为": "u",
77 | "联盟": "u"
78 | }
79 | }
80 | }
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/doc/db/microfunction.puml:
--------------------------------------------------------------------------------
1 | @startuml
2 | 'Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 | 'SPDX-License-Identifier: MIT (For details, see https://github.com/awslabs/aws-icons-for-plantuml/blob/master/LICENSE)
4 |
5 | !include
6 |
7 | ' Uncomment the following line to create simplified view
8 | ' !include
9 |
10 | !include
11 | !include
12 | !include
13 | !include
14 | !include
15 |
16 |
17 | top to bottom direction
18 |
19 | DynamoDB(coreDB, "文档数据库", "线上环境")
20 |
21 | Client(client, "客户端", "browser / qq / wechat")
22 |
23 | Cloud(v1, "core-v1", "核心接口")
24 | Cloud(contentSecurity, "内容安全", "wechat / qq")
25 | Cloud(pull, "拉取服务", "主要数据来源")
26 | Cloud(searchHot, "热搜", "产生热搜")
27 | Cloud(openApi, "开放API", "免费对外服务")
28 | Cloud(qqrobotApi, "QQ机器人", "作用于qq机器人的api服务")
29 | Cloud(dingrobot, "钉钉机器人", '运营')
30 |
31 | Bottlerocket(service, '服务器', "aws / aliyun")
32 | Bottlerocket(otherService, '第三方服务器/源', "unknown")
33 | Bottlerocket(HangUp, '挂机服务', "other service")
34 | RoboMaker(qqrobot, "QQ机器人", '运营')
35 |
36 | ' 客户端调用
37 | client -> "https" v1
38 |
39 | ' 核心api指向核心数据库
40 | v1 --> "call" coreDB
41 | v1 --> "https" contentSecurity
42 | ' 开放api调用v1
43 | openApi --> "https" v1
44 | ' 开放api返回给客户端
45 | openApi --> "view" client
46 | ' 热搜指向核心数据库,从而产生热搜
47 | searchHot --> "call" coreDB
48 | ' 产生之后返回给客户端
49 | searchHot --> "view" client
50 |
51 | ' 钉钉机器人内部运营,直接从库中获取数据并且展示
52 | dingrobot --> "call" coreDB
53 |
54 | ' 挂机服务托管了qq运营机器人
55 | HangUp --> "托管" qqrobot
56 | ' qq api 和 机器人互相作用,用于回调/主动调用
57 | qqrobot "call" <--> "callback" qqrobotApi
58 | ' 第三方服务器定时执行http请求,作用于qq运营机器人(发布题目等等)
59 | service --> "https" qqrobotApi
60 |
61 | ' 拉取服务从第三方服务器进行拉取
62 | pull --> "https" otherService
63 | ' 拉取之后入库
64 | pull --> "call" coreDB
65 |
66 | @enduml
67 |
--------------------------------------------------------------------------------
/src/common/request.ts:
--------------------------------------------------------------------------------
1 | const Fly = require('flyio/dist/npm/wx');
2 | import notLogin from '../util/notLogin';
3 |
4 | const fly = new Fly();
5 |
6 | type RequestParams = {
7 | method: 'GET' | 'POST' | 'PUT' | 'DELETE';
8 | route: `api/${string}`;
9 | data: Record;
10 | checkLogin?: boolean;
11 | };
12 |
13 | // 添加请求拦截器
14 | fly.interceptors.request.use((request) => {
15 | // 如果命令登录检查
16 | if (request.body.checkLogin) {
17 | notLogin();
18 | }
19 | // uni-id-token
20 | const token = uni.getStorageSync('uni_id_token');
21 | const id = uni.getStorageSync('uni_id');
22 | if (token) {
23 | request.headers['uni-id-token'] = token;
24 | request.headers['uni-id'] = id;
25 | }
26 | request.headers['sword-platform'] = process.env.UNI_PLATFORM;
27 | return request;
28 | });
29 |
30 | //添加响应拦截器,响应拦截器会在then/catch处理之前执行
31 | fly.interceptors.response.use((response) => {
32 | return response.data;
33 | });
34 |
35 | export default (params: RequestParams): Promise> => {
36 | return new Promise((resolve, reject) => {
37 | fly
38 | .request(`${process.env.NODE_ENV ? process.env.VUE_APP_V1_RELEASE_API_HTTP_URL : process.env.VUE_APP_V1_API_HTTP_URL}${params.route}`, params.data, {
39 | method: params?.method || 'POST',
40 | timeout: 5000
41 | })
42 | .then((res) => {
43 | let response: ActionResult = {
44 | success: true,
45 | data: res
46 | };
47 | if (res.code) {
48 | // 判断code是否存在于errorMessage对象中
49 | if (res.code !== 0) {
50 | response = {
51 | success: false
52 | };
53 | uni.hideLoading();
54 | uni.showToast({
55 | title: res.message,
56 | icon: 'none'
57 | });
58 | }
59 | }
60 | resolve(response);
61 | });
62 | });
63 | };
64 |
--------------------------------------------------------------------------------
/src/uni_modules/uni-popup/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "id": "uni-popup",
3 | "displayName": "PopUp 弹出层",
4 | "version": "1.2.9",
5 | "description": " Popup 组件,提供常用的弹层",
6 | "keywords": [
7 | "popup",
8 | "uni-ui",
9 | "弹出层",
10 | "uni-popup"
11 | ],
12 | "repository": "https://github.com/dcloudio/uni-ui",
13 | "engines": {
14 | "HBuilderX": ""
15 | },
16 | "directories": {
17 | "example": "../../temps/example_temps"
18 | },
19 | "dcloudext": {
20 | "category": [
21 | "前端组件",
22 | "通用组件"
23 | ],
24 | "sale": {
25 | "regular": {
26 | "price": "0.00"
27 | },
28 | "sourcecode": {
29 | "price": "0.00"
30 | }
31 | },
32 | "contact": {
33 | "qq": ""
34 | },
35 | "declaration": {
36 | "ads": "无",
37 | "data": "无",
38 | "permissions": "无"
39 | },
40 | "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
41 | },
42 | "uni_modules": {
43 | "dependencies": [
44 | "uni-transition"
45 | ],
46 | "encrypt": [],
47 | "platforms": {
48 | "cloud": {
49 | "tcb": "y",
50 | "aliyun": "y"
51 | },
52 | "client": {
53 | "App": {
54 | "app-vue": "y",
55 | "app-nvue": "y"
56 | },
57 | "H5-mobile": {
58 | "Safari": "y",
59 | "Android Browser": "y",
60 | "微信浏览器(Android)": "y",
61 | "QQ浏览器(Android)": "y"
62 | },
63 | "H5-pc": {
64 | "Chrome": "y",
65 | "IE": "y",
66 | "Edge": "y",
67 | "Firefox": "y",
68 | "Safari": "y"
69 | },
70 | "小程序": {
71 | "微信": "y",
72 | "阿里": "y",
73 | "百度": "y",
74 | "字节跳动": "y",
75 | "QQ": "y"
76 | },
77 | "快应用": {
78 | "华为": "u",
79 | "联盟": "u"
80 | }
81 | }
82 | }
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/v1/src/controller/questionTag.ts:
--------------------------------------------------------------------------------
1 | import * as explain from 'explain';
2 | import questionTagService from '../service/questionTag';
3 | import * as IQuestionTag from '../../proto/questionTag';
4 |
5 | export = class QuestionTagController extends explain.service {
6 | private service: questionTagService;
7 | constructor(e: CloudData) {
8 | super(e);
9 | this.service = new questionTagService(this);
10 | }
11 | /**
12 | * @name 获取专区列表(HTTP调用)
13 | * @param IQuestionTag.GetTagList
14 | * @return {*} {Promise}
15 | * @memberof QuestionTagController
16 | */
17 | async getTagList(): Promise {
18 | return await this.service.getTagList(this.event.data as IQuestionTag.GetTagList);
19 | }
20 | /**
21 | * @name 添加Tag
22 | * @param IQuestionTag.AddQuestionTag
23 | * @return {*} {Promise}
24 | * @link https://www.yuque.com/mlgrgm/lmm8g4/vxylvr#g13V0
25 | * @memberof QuestionTagController
26 | */
27 | async addQuestionTag(): Promise {
28 | return await this.service.addQuestionTag(this.event.data as IQuestionTag.AddQuestionTag);
29 | }
30 | /**
31 | * @name 修改Tag
32 | * @param IQuestionTag.UpdateQuestionTag
33 | * @return {*} {Promise}
34 | * @link https://www.yuque.com/mlgrgm/lmm8g4/vxylvr#qLNHs
35 | * @memberof QuestionTagController
36 | */
37 | async updateQuestionTag(): Promise {
38 | return await this.service.updateQuestionTag(this.event.data as IQuestionTag.UpdateQuestionTag);
39 | }
40 | /**
41 | * @name 删除tag
42 | * @param IQuestionTag.DeleteQuestionTag
43 | * @return {*} {Promise}
44 | * @link https://www.yuque.com/mlgrgm/lmm8g4/vxylvr#VYwM2
45 | * @memberof QuestionTagController
46 | */
47 | async deleteQuestionTag(): Promise {
48 | return await this.service.deleteQuestionTag(this.event.data as IQuestionTag.DeleteQuestionTag);
49 | }
50 | };
51 |
--------------------------------------------------------------------------------
/src/uni_modules/uni-search-bar/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "id": "uni-search-bar",
3 | "displayName": "uni-search-bar 搜索栏",
4 | "version": "1.0.9",
5 | "description": "搜索栏组件,通常用于搜索商品、文章等",
6 | "keywords": [
7 | "uni-ui",
8 | "uniui",
9 | "搜索框",
10 | "搜索栏"
11 | ],
12 | "repository": "https://github.com/dcloudio/uni-ui",
13 | "engines": {
14 | "HBuilderX": ""
15 | },
16 | "directories": {
17 | "example": "../../temps/example_temps"
18 | },
19 | "dcloudext": {
20 | "category": [
21 | "前端组件",
22 | "通用组件"
23 | ],
24 | "sale": {
25 | "regular": {
26 | "price": "0.00"
27 | },
28 | "sourcecode": {
29 | "price": "0.00"
30 | }
31 | },
32 | "contact": {
33 | "qq": ""
34 | },
35 | "declaration": {
36 | "ads": "无",
37 | "data": "无",
38 | "permissions": "无"
39 | },
40 | "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
41 | },
42 | "uni_modules": {
43 | "dependencies": [
44 | "uni-icons"
45 | ],
46 | "encrypt": [],
47 | "platforms": {
48 | "cloud": {
49 | "tcb": "y",
50 | "aliyun": "y"
51 | },
52 | "client": {
53 | "App": {
54 | "app-vue": "y",
55 | "app-nvue": "y"
56 | },
57 | "H5-mobile": {
58 | "Safari": "y",
59 | "Android Browser": "y",
60 | "微信浏览器(Android)": "y",
61 | "QQ浏览器(Android)": "y"
62 | },
63 | "H5-pc": {
64 | "Chrome": "y",
65 | "IE": "y",
66 | "Edge": "y",
67 | "Firefox": "y",
68 | "Safari": "y"
69 | },
70 | "小程序": {
71 | "微信": "y",
72 | "阿里": "y",
73 | "百度": "y",
74 | "字节跳动": "y",
75 | "QQ": "y"
76 | },
77 | "快应用": {
78 | "华为": "u",
79 | "联盟": "u"
80 | }
81 | }
82 | }
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/src/pages/question/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {{ item.name }}
6 |
7 |
8 |
9 |
10 |
42 |
43 |
48 |
75 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/v1/src/controller/questionArea.ts:
--------------------------------------------------------------------------------
1 | import * as explain from 'explain';
2 | import questionAreaService from '../service/questionArea';
3 | import * as IQuestionArea from '../../proto/questionArea';
4 | export = class QuestionAreaController extends explain.service {
5 | private service: questionAreaService;
6 | constructor(e: CloudData) {
7 | super(e);
8 | this.service = new questionAreaService(this);
9 | }
10 | /**
11 | * @name 获取专区列表(HTTP调用)
12 | * @param IQuestionArea.GetAreaList
13 | * @return {*} {Promise}
14 | * @memberof QuestionAreaController
15 | */
16 | async getAreaList(): Promise {
17 | return await this.service.getAreaList(this.event.data as IQuestionArea.GetAreaList);
18 | }
19 | /**
20 | * @name 添加题目专区
21 | * @param IQuestionArea.AddQuestionArea
22 | * @return {*} {Promise}
23 | * @link https://www.yuque.com/mlgrgm/lmm8g4/xdytvh#g13V0
24 | * @memberof QuestionAreaController
25 | */
26 | async addQuestionArea(): Promise {
27 | return await this.service.addQuestionArea(this.event.data as IQuestionArea.AddQuestionArea);
28 | }
29 | /**
30 | * @name 修改题目专区
31 | * @param IQuestionArea.UpdateQuestionArea
32 | * @return {*} {Promise}
33 | * @link https://www.yuque.com/mlgrgm/lmm8g4/xdytvh#HDXsW
34 | * @memberof QuestionAreaController
35 | */
36 | async updateQuestionArea(): Promise {
37 | return await this.service.updateQuestionArea(this.event.data as IQuestionArea.UpdateQuestionArea);
38 | }
39 | /**
40 | * @name 删除题目专区
41 | * @param IQuestionArea.DeleteQuestionArea
42 | * @return {*} {Promise}
43 | * @link https://www.yuque.com/mlgrgm/lmm8g4/xdytvh#tOjkO
44 | * @memberof QuestionAreaController
45 | */
46 | async deleteQuestionArea(): Promise {
47 | return await this.service.deleteQuestionArea(this.event.data as IQuestionArea.DeleteQuestionArea);
48 | }
49 | };
50 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/day-satistics/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | const db = uniCloud.database();
3 | const userCollection = db.collection('uni-id-users');
4 | const questionCollection = db.collection('question');
5 | const explanationCollection = db.collection('questionExplanation');
6 | const areaCollection = db.collection('questionArea');
7 | const hotCollection = db.collection('opendb-search-hot');
8 | const certificationApplyOrderCollection = db.collection('certificationApplyOrder');
9 | const $ = db.command.aggregate;
10 | exports.main = async (event) => {
11 | // 用户表数量
12 | const { total: userTotal } = await userCollection.count();
13 | // 问题数量
14 | const questionInfo = await questionCollection
15 | .aggregate()
16 | .match({
17 | state: 'pass'
18 | })
19 | .group({
20 | _id: '$areaID',
21 | num: $.sum(1)
22 | })
23 | .end();
24 | // 解答数量
25 | const { total: explanationTotal } = await explanationCollection.count();
26 | // 专区信息
27 | const { data: areaInfo } = await areaCollection.get();
28 | // 今日热搜词
29 | const { data: hotInfo } = await hotCollection
30 | .field({
31 | content: true
32 | })
33 | .get();
34 | // 出题官认证申请(只展示未处理)
35 | const { data: certificationInfo } = await certificationApplyOrderCollection
36 | .where({
37 | state: 'pending'
38 | })
39 | .skip(0)
40 | .limit(10)
41 | .orderBy('createTime', 'desc')
42 | .get();
43 | // 构成统计数据
44 | const mainStr = `今日用户数量: ${userTotal}个
45 | 题目数据概览: ${questionInfo.data.map((q) => {
46 | return areaInfo.find((a) => a._id === q._id).name + `(${q.num}道)`;
47 | })}
48 | 题解数量: ${explanationTotal}个
49 | 今日热搜词: ${hotInfo.map((h) => h.content).join(',')}
50 | 最近的认证申请(未处理): \n${certificationInfo.map((c) => `-- 联系方式: ${c.content.contactDetails}, 擅长: ${c.content.filed}`).join('\n')}
51 | `;
52 | // 发送钉钉通知
53 | await uniCloud.callFunction({
54 | name: 'dingtalk-robot',
55 | data: { content: `${mainStr}` }
56 | });
57 | //返回数据给客户端
58 | return event;
59 | };
60 |
--------------------------------------------------------------------------------
/src/uni_modules/uni-transition/readme.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | ## Transition 过渡动画
4 | > 代码块: `uTransition`
5 |
6 |
7 | 元素的简单过渡动画,组件名:`uni-transition`
8 |
9 | ### 安装方式
10 |
11 | 本组件符合[easycom](https://uniapp.dcloud.io/collocation/pages?id=easycom)规范,`HBuilderX 2.5.5`起,只需将本组件导入项目,在页面`template`中即可直接使用,无需在页面中`import`和注册`components`。
12 |
13 | 如需通过`npm`方式使用`uni-ui`组件,另见文档:[https://ext.dcloud.net.cn/plugin?id=55](https://ext.dcloud.net.cn/plugin?id=55)
14 |
15 | ### 基本用法
16 |
17 | 在 ``template`` 中使用组件
18 |
19 | ```html
20 |
21 |
22 |
23 |
24 |
25 |
26 | ```
27 | ``` javascript
28 |
29 | import uniTransition from '@/components/uni-transition/uni-transition.vue'
30 | export default {
31 | components: {
32 | uniTransition
33 | },
34 | data() {
35 | return {
36 | show: false,
37 | }
38 | },
39 | onLoad() {},
40 | methods: {
41 | open(mode) {
42 | this.show = !this.show
43 | },
44 | change() {
45 | console.log('触发动画')
46 | }
47 | }
48 | }
49 | ```
50 |
51 | ## API
52 |
53 | ### Transition Props
54 |
55 | |属性名 |类型 |默认值 |说明 |
56 | |:-: |:-: |:-: |:-:|
57 | |show |Boolean|false |控制组件显示或隐藏, |
58 | |modeClass |Array |- |过渡动画类型 |
59 | |duration |Number |300 |过渡动画持续时间 |
60 | |styles |Object |- |组件样式,同 css 样式,注意带’-‘连接符的属性需要使用小驼峰写法如:`backgroundColor:red` |
61 |
62 | #### modeClass 类型说明
63 | **格式为** :`['fade','slide-top']`
64 |
65 | |属性名 |说明 |
66 | |:-: |:-: |
67 | |fade |渐隐渐出过渡 |
68 | |slide-top |由上至下过渡 |
69 | |slide-right |由右至左过渡 |
70 | |slide-bottom |由下至上过渡 |
71 | |slide-left |由左至右过渡 |
72 | |zoom-in |由小到大过渡 |
73 | |zoom-out |由大到小过渡 |
74 |
75 | **注意**
76 |
77 | 组合使用时,同一种类型相反的过渡动画如(slide-top、slide-bottom)同时使用时,只有最后一个生效
78 |
79 | ### Transition Events
80 |
81 | |事件称名 |说明 |返回值 |
82 | |:-: |:-: |:-: |
83 | |click |点击组件触发 |- |
84 | |change |过渡动画结束时触发 | e = {detail:true} |
85 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/v1/src/service/questionTag.ts:
--------------------------------------------------------------------------------
1 | const db = uniCloud.database();
2 | const collection = db.collection('questionTag');
3 | import * as IQuestionTag from '../../proto/questionTag';
4 | export default class QuestionTag {
5 | public userID: string;
6 | public nowDate: string;
7 | constructor(data: CloudData) {
8 | this.userID = data.context.userID;
9 | this.nowDate = new Date().toISOString();
10 | }
11 | public async getTagList(params: IQuestionTag.GetTagList): Promise {
12 | const { limit, page } = params;
13 | const whereParams = {
14 | deleteDate: ''
15 | };
16 | const data = await collection
17 | .aggregate()
18 | .match(whereParams)
19 | .sort({
20 | createDate: -1
21 | })
22 | .skip(limit * (page - 1))
23 | .limit(limit)
24 | .lookup({
25 | from: 'questionArea',
26 | localField: 'areaID',
27 | foreignField: '_id',
28 | as: 'areaInfo'
29 | })
30 | .end();
31 | // 获取数量
32 | const countResult = await collection.where(whereParams).count();
33 | return {
34 | list: data.data,
35 | count: countResult.total
36 | };
37 | }
38 | public async addQuestionTag(params: IQuestionTag.AddQuestionTag): Promise {
39 | const { areaID, name } = params;
40 | return await collection.add({
41 | areaID,
42 | name,
43 | createDate: this.nowDate,
44 | updateDate: this.nowDate,
45 | deleteDate: ''
46 | });
47 | }
48 | public async updateQuestionTag(params: IQuestionTag.UpdateQuestionTag): Promise {
49 | const { _id, areaID, name } = params;
50 | return await collection.doc(_id).update({
51 | areaID,
52 | name,
53 | updateDate: this.nowDate,
54 | deleteDate: ''
55 | });
56 | }
57 | public async deleteQuestionTag(params: IQuestionTag.DeleteQuestionTag): Promise {
58 | return await collection.doc(params._id).update({
59 | updateDate: this.nowDate,
60 | deleteDate: this.nowDate
61 | });
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/src/api/user.ts:
--------------------------------------------------------------------------------
1 | import request from '../common/request';
2 | const db = uniCloud.database();
3 |
4 | /**
5 | * @name 关注用户
6 | * @param params
7 | * @returns
8 | */
9 | export async function postFollow(params: { targetID: string }): Promise {
10 | return await request({
11 | route: `api/user/checkFollowers`,
12 | method: 'PUT',
13 | data: {
14 | follower: params.targetID
15 | },
16 | checkLogin: true
17 | });
18 | }
19 |
20 | /**
21 | * @name 获取用户首页的信息(赞同数,解题数等)
22 | * @param params
23 | * @returns
24 | */
25 | export async function getUserContentByID(params: { userID: string }): Promise {
26 | return await request({
27 | route: `api/user/getUserContentByID`,
28 | method: 'GET',
29 | data: {
30 | id: params.userID
31 | }
32 | });
33 | }
34 |
35 | /**
36 | * @name 获取用户基本信息根据UserID
37 | * @param params
38 | */
39 | export async function getUserBaseContentByUserID(params: { userID: string }): Promise {
40 | const res = await db
41 | .collection('uni-id-users')
42 | .where({
43 | _id: params.userID
44 | })
45 | .field('nickname,avatar,followers,sign,gender,wx_openid,qq_openid,mobile,mobile_confirmed')
46 | .get();
47 | return {
48 | ...res,
49 | data: res.result.data
50 | };
51 | }
52 |
53 | /**
54 | * @name 重置已登陆账户的密码
55 | * @param params
56 | */
57 | export async function resetPassword(params: { password: string }): Promise {
58 | return await request({
59 | route: `api/user/resetPassword`,
60 | method: 'POST',
61 | data: {
62 | password: params.password,
63 | id: uni.getStorageSync('uni_id')
64 | },
65 | checkLogin: true
66 | });
67 | }
68 |
69 | export async function updateUserProfile(params: { nickname: string; avatar: string; gender: number; sign: string }): Promise {
70 | return await request({
71 | route: `api/user`,
72 | method: 'PUT',
73 | data: {
74 | ...params,
75 | uid: uni.getStorageSync('uni_id')
76 | },
77 | checkLogin: true
78 | });
79 | }
80 |
--------------------------------------------------------------------------------
/src/pages/user/setPassword.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
11 |
12 |
13 |
14 | 确定重置
15 |
16 |
17 |
18 |
19 |
20 |
70 |
71 |
76 |
85 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/v1/src/controller/openApi.ts:
--------------------------------------------------------------------------------
1 | import * as explain from 'explain';
2 | import openApiService from '../service/openApi';
3 | import * as IOpenApi from '../../proto/openApi';
4 | export = class OpenApiController extends explain.service {
5 | private service: openApiService;
6 | constructor(e: CloudData) {
7 | super(e);
8 | this.service = new openApiService(this);
9 | }
10 | /**
11 | * @name 添加openapi
12 | * @param IOpenApi.AddOpenApi
13 | * @return {*} {Promise}
14 | * @memberof OpenApiController
15 | */
16 | async addOpenApi(): Promise {
17 | return await this.service.addOpenApi(this.event.data as IOpenApi.AddOpenApi);
18 | }
19 | /**
20 | * @name 修改openapi
21 | * @param IOpenApi.AddOpenApi
22 | * @return {*} {Promise}
23 | * @memberof OpenApiController
24 | */
25 | async updateOpenApi(): Promise {
26 | return await this.service.updateOpenApi(this.event.data as IOpenApi.UpdateOpenApi);
27 | }
28 | /**
29 | * @name 开启/关闭openapi的状态
30 | * @param IOpenApi.ToggleOpenApiState
31 | * @return {*} {Promise}
32 | * @memberof OpenApiController
33 | */
34 | async toggleOpenApiState(): Promise {
35 | return await this.service.toggleOpenApiState(this.event.data as IOpenApi.ToggleOpenApiState);
36 | }
37 | /**
38 | * @name 获取题目列表
39 | * @param IOpenApi.GetQuestionList
40 | * @return {*} {Promise}
41 | * @memberof OpenApiController
42 | */
43 | async getQuestionList(): Promise {
44 | return await this.service.getQuestionList(this.event.data as IOpenApi.GetQuestionList);
45 | }
46 | /**
47 | * @name 获取专区列表
48 | * @return {*} {Promise}
49 | * @memberof OpenApiController
50 | */
51 | async getQuestionAreaList(): Promise {
52 | return await this.service.getQuestionAreaList();
53 | }
54 | /**
55 | * @name 获取标签列表
56 | * @return {*} {Promise}
57 | * @memberof OpenApiController
58 | */
59 | async getQuestionTag(): Promise {
60 | return await this.service.getQuestionTag();
61 | }
62 | };
63 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/pull/Dada-interview-answe.js:
--------------------------------------------------------------------------------
1 | let json = [
2 | {
3 | id: 'interview-answe#247',
4 | source: 'interview-answe',
5 | title: '[vue]https://binaryify.github.io/NeteaseCloudMusicApi/#/',
6 | type: 'default',
7 | link: 'https://github.com/webVueBlog/interview-answe/issues/247',
8 | answered: 'no',
9 | status: 'opened',
10 | author: 'webVueBlog',
11 | content: ''
12 | }
13 | ];
14 | const typeAlias = {
15 | vue: [{ $oid: '5fefd5700431ca0001cdeca7' }],
16 | JavaScript: [{ $oid: '5ff5bc70c23632000132f512' }],
17 | html: [{ $oid: '5ff5bc68fce5d000011cd514' }],
18 | html5: [{ $oid: '5ff5bc68fce5d000011cd514' }],
19 | css: [{ $oid: '5ff5bc78fce5d000011cd530' }],
20 | 'HTML&CSS html': [{ $oid: '5ff5bc68fce5d000011cd514' }, { $oid: '5ff5bc78fce5d000011cd530' }],
21 | 小程序: [{ $oid: '5fdfe2df23976b0001d43aa3' }],
22 | 'HTML&CSS': [{ $oid: '5ff5bc68fce5d000011cd514' }, { $oid: '5ff5bc78fce5d000011cd530' }],
23 | jquery: [{ $oid: '5fefd6cb0431ca0001cdeee2' }],
24 | 开发及性能优化: [{ $oid: '607a914096f59a0001add4c8' }],
25 | HTTP: [{ $oid: '607a914febbd8d00015f3057' }],
26 | 性能优化: [{ $oid: '607a914096f59a0001add4c8' }],
27 | 面试: [{ $oid: '607a9158f0faa600017e96b6' }]
28 | };
29 | const date = new Date().toISOString();
30 | let _json = '';
31 | // eslint-disable-next-line @typescript-eslint/no-unused-vars
32 | json = json.map((j) => {
33 | if (typeAlias[j.type]) {
34 | // 查询title中的[]和序号并清除
35 | let i = j.title.indexOf('.');
36 | if (i >= 0) {
37 | j.title = j.title.substr(i + 1);
38 | let y = j.title.indexOf(']');
39 | if (y >= 0) {
40 | j.title = j.title.substr(y + 1);
41 | }
42 | }
43 | _json += JSON.stringify({
44 | title: j.title,
45 | areaID: { $oid: '5fdf56a3e2c1ee0001a52e49' },
46 | publishUserID: { $oid: '607a97c7d3b60a0001c7dd53' },
47 | questionExplanation: [],
48 | content: j.content,
49 | state: 'pass',
50 | tagID: typeAlias[j.type],
51 | createDate: date,
52 | updateDate: date,
53 | deleteDate: ''
54 | });
55 | _json += '\n';
56 | }
57 | });
58 |
59 | console.log(_json);
60 |
--------------------------------------------------------------------------------
/src/api/question.ts:
--------------------------------------------------------------------------------
1 | const db = uniCloud.database();
2 | import request from '../common/request';
3 |
4 | /**
5 | * @name 获取题目列表
6 | * @param params
7 | * @description 需要查询User以及专区和标签的内容
8 | * @docLink https://www.yuque.com/u509950/lmm8g4/wmvcz3
9 | */
10 | export async function getQuestionListData(params: { limit: number; page: number; areaID: string }): Promise {
11 | const { limit, page, areaID } = params;
12 | const res = await db
13 | .collection('question,uni-id-users')
14 | .where(`areaID == '${areaID}' && deleteDate == '' && state == 'pass'`)
15 | .field(`publishUserID{avatar,nickname,_id},title,content,createDate`)
16 | .orderBy('createDate', 'desc')
17 | .skip(limit * (page - 1))
18 | .limit(limit)
19 | .get();
20 | return {
21 | ...res,
22 | data: res.result.data
23 | };
24 | }
25 |
26 | /**
27 | * @name 获取题目详情根据ID
28 | * @param params
29 | */
30 | export async function getQuestionDetailByID(params: { id: string }): Promise {
31 | const res = await db.collection('question,questionTag').where(`_id == '${params.id}'`).field('tagID{name},title,content,pageView').get();
32 | return {
33 | ...res,
34 | data: res.result.data
35 | };
36 | }
37 |
38 | /**
39 | * @name 增加题目浏览量
40 | * @param params
41 | * @returns
42 | */
43 | export async function postAddPageView(params: { _id: string }): Promise {
44 | return await request({
45 | route: `api/question/addPageView`,
46 | method: 'POST',
47 | data: {
48 | _id: params._id
49 | }
50 | });
51 | }
52 |
53 | /**
54 | * @name 获取题目列表根据用户ID
55 | * @param params
56 | * @returns
57 | */
58 | export async function getQuestionListByUser(params: { userID: string; limit: number; page: number }): Promise {
59 | const { limit, page } = params;
60 | const res = await db
61 | .collection('question')
62 | .where(`publishUserID == '${params.userID}' && state == 'pass' && deleteDate == ''`)
63 | .orderBy('createDate', 'desc')
64 | .skip(limit * (page - 1))
65 | .limit(limit)
66 | .get();
67 | return {
68 | ...res,
69 | data: res.result.data
70 | };
71 | }
72 |
--------------------------------------------------------------------------------
/src/uni_modules/robin-editor/readme.md:
--------------------------------------------------------------------------------
1 | # 富文本编辑器插件
2 | uniapp 富文本编辑器插件
3 |
4 | ## 兼容性
5 | |微信小程序|H5|APP|
6 | |:--:|:--:|:--:|
7 | |√|√ |x|
8 |
9 | ## 使用方式
10 | 在 `script` 中引用组件
11 | ```js
12 | import myeditor from "@/components/robin-editor/editor.vue"
13 | export default {
14 | components: {myeditor}
15 | }
16 | ```
17 | 在 `template` 中使用组件
18 | ```html
19 |
25 |
26 | ```
27 |
28 | ## Demo
29 | https://github.com/health901/uniapp-editor-demo
30 |
31 | ## 属性说明
32 | |属性|类型|默认值|说明|
33 | |--|--|--|--|
34 | |v-model|String| |富文本,双向绑定|
35 | |imageUploader|function(img,callback)| |上传图片处理函数 接受参数 img:本地图片地址,callback:上传成功回调传入图片链接|
36 | |muiltImage|Boolean|false|是否支持多图上传|
37 | |compressImage|Boolean|true|图片上传是否压缩|
38 | |previewMode|Boolean|false|预览模式,不可编辑|
39 | |autoHideToolbar|Boolean|false|失去焦点时自动隐藏工具栏|
40 | |tools|Array|['bold', 'italic', 'underline', 'strike', 'align-left', 'align-center', 'align-right', 'remove', 'font', 'color', 'backgroundColor','image', 'clear', 'preview']|工具栏|
41 |
42 | ### 工具栏
43 | |名称|值|
44 | |--|--|
45 | |加粗|`bold`|
46 | |斜体|`italic`|
47 | |下划线|`underline`|
48 | |删除线|`strike`|
49 | |右对齐|`align-left`|
50 | |居中|`align-center`|
51 | |左对齐|`align-right`|
52 | |清除格式|`remove`|
53 | |字体大小|`font`|
54 | |字体颜色|`color`|
55 | |背景色|`backgroundColor`|
56 | |插入图片|`image`|
57 | |清空|`clear`|
58 | |预览|`preview`|
59 | |插入日期|`date`|
60 | |列表|`list-check`,`list-ordered`,`list-bullet`|
61 | |上下标|`sub`,`super`|
62 | |撤销,恢复撤销|`undo`,`redo`|
63 | |缩进|`indent`,`outdent`|
64 | |分割线|`divider`|
65 | |标题|`h1`,`h2`,`h3`,`h4`,`h5`,`h6`|
66 | |书写方向|`rtl`|
67 |
68 | ## 事件说明
69 | |事件|说明|参数|
70 | |--|--|--|
71 | |cancel|点击取消按钮|
72 | |save|点击保存按钮|e={html,text,delta}|
73 |
74 | ## 依赖
75 | |组件|链接|备注|
76 | |---|--|--|
77 | |Popup 弹出层[[1]](#注)|https://ext.dcloud.net.cn/plugin?id=329|uni-ui库|
78 | |Transition动画|https://ext.dcloud.net.cn/plugin?id=1231|uni-ui库,Popup依赖|
79 | |颜色选择器ColorPicker[[2]](#注)|https://ext.dcloud.net.cn/plugin?id=1237|字体颜色,背景色|
80 |
81 |
82 | ## 注
83 |
84 | 1. 修改:新增动画结束事件
85 | 2. 修改:添加按钮,支持预设颜色值
86 |
--------------------------------------------------------------------------------
/src/components/i-uniapp/i-navigation-bar/i-navigation-bar.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/v1/src/controller/questionExplanation.ts:
--------------------------------------------------------------------------------
1 | import * as explain from 'explain';
2 | import questionExplanationService from '../service/questionExplanation';
3 | import * as IQuestionExplanation from '../../proto/questionExplanation';
4 |
5 | export = class QuestionExplanationController extends explain.service {
6 | private service: questionExplanationService;
7 | constructor(e: CloudData) {
8 | super(e);
9 | this.service = new questionExplanationService(this);
10 | }
11 | /**
12 | * @name 添加题解
13 | * @param IQuestionExplanation.AddQuestionExplanation
14 | * @return {*} {Promise}
15 | * @link https://www.yuque.com/mlgrgm/lmm8g4/xsd6wg#g13V0
16 | * @memberof QuestionExplanationController
17 | */
18 | async addQuestionExplanation(): Promise {
19 | return await this.service.addQuestionExplanation(this.event.data as IQuestionExplanation.AddQuestionExplanation);
20 | }
21 | /**
22 | * @name 修改题解
23 | * @param IQuestionExplanation.UpdateQuestionExplanation
24 | * @return {*} {Promise}
25 | * @memberof QuestionExplanationController
26 | */
27 | async updateQuestionExplanation(): Promise {
28 | return await this.service.updateQuestionExplanation(this.event.data as IQuestionExplanation.UpdateQuestionExplanation);
29 | }
30 | /**
31 | * @name 采纳/取消采纳题解
32 | * @param IQuestionExplanation.AdoptionQuestionExplanation
33 | * @return {*} {Promise}
34 | * @link https://www.yuque.com/mlgrgm/lmm8g4/xsd6wg#h2Ix9
35 | * @memberof QuestionExplanationController
36 | */
37 | async adoptionQuestionExplanation(): Promise {
38 | return await this.service.adoptionQuestionExplanation(this.event.data as IQuestionExplanation.AdoptionQuestionExplanation);
39 | }
40 | /**
41 | * @name 收藏/取消收藏题解
42 | * @param IQuestionExplanation.CollectQuestionExplanation
43 | * @return {*} {Promise}
44 | * @link https://www.yuque.com/mlgrgm/lmm8g4/xsd6wg#z7Okn
45 | * @memberof QuestionExplanationController
46 | */
47 | async collectQuestionExplanation(): Promise {
48 | return await this.service.collectQuestionExplanation(this.event.data as IQuestionExplanation.CollectQuestionExplanation);
49 | }
50 | };
51 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/v1/src/service/certificationApplyOrder.ts:
--------------------------------------------------------------------------------
1 | import * as ICertificationApplyOrder from '../../proto/certificationApplyOrder';
2 | const db = uniCloud.database();
3 | const collection = db.collection('certificationApplyOrder');
4 | export default class CertificationApplyOrder {
5 | public userID: string;
6 | public nowDate: string;
7 | constructor(data: CloudData) {
8 | this.userID = data.context.userID;
9 | this.nowDate = new Date().toISOString();
10 | }
11 | async getCertificationApplyOrder(params: ICertificationApplyOrder.GetCertificationApplyOrder): Promise {
12 | const { limit, page, state } = params;
13 | const whereParams = {
14 | state
15 | };
16 | const data = await collection
17 | .where(whereParams)
18 | .skip(limit * (page - 1))
19 | .limit(limit)
20 | .sort({
21 | createDate: -1
22 | })
23 | .filed(`state, userID, content, createDate`)
24 | .get();
25 | const countResult = await collection.where(whereParams).count();
26 | return {
27 | list: data.data,
28 | count: countResult.total
29 | };
30 | }
31 | async addCertificationApplyOrder(params: ICertificationApplyOrder.AddCertificationApplyOrder): Promise {
32 | // 调用钉钉通知函数
33 | uniCloud.callFunction({
34 | name: 'dingtalk-robot',
35 | data: {
36 | content: `有一个新的出题官认证申请,申请时间为${this.nowDate}\n申请内容为: ${JSON.stringify(params.content)}\n请及时查看,尤其是群主,你别忘记了!`
37 | }
38 | });
39 | return await collection.add({
40 | state: 'pending',
41 | userID: this.userID,
42 | content: params.content,
43 | createDate: this.nowDate,
44 | updateDate: this.nowDate,
45 | deleteDate: ''
46 | });
47 | }
48 | async updateCertificationApplyOrder(params: ICertificationApplyOrder.UpdateCertificationApplyOrder): Promise {
49 | return await collection.doc(params._id).update({
50 | content: params.content,
51 | updateDate: this.nowDate
52 | });
53 | }
54 | async updateCertificationApplyOrderState(params: ICertificationApplyOrder.UpdateCertificationApplyOrderState): Promise {
55 | return await collection.doc(params._id).update({
56 | state: params.state,
57 | updateDate: this.nowDate
58 | });
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/v1/src/controller/certificationApplyOrder.ts:
--------------------------------------------------------------------------------
1 | import * as explain from 'explain';
2 | import certificationService from '../service/certificationApplyOrder';
3 | import * as ICertificationApplyOrder from '../../proto/certificationApplyOrder';
4 | export = class CertificationApplyOrderController extends explain.service {
5 | private service: certificationService;
6 | constructor(e: CloudData) {
7 | super(e);
8 | this.service = new certificationService(this);
9 | }
10 | /**
11 | * @name 新增申请认证
12 | * @param ICertificationApplyOrder.AddCertificationApplyOrder
13 | * @return {*} {Promise}
14 | * @link https://www.yuque.com/mlgrgm/lmm8g4/qoght3#g13V0
15 | * @memberof CertificationApplyOrderController
16 | */
17 | async addCertificationApplyOrder(): Promise {
18 | return await this.service.addCertificationApplyOrder(this.event.data as ICertificationApplyOrder.AddCertificationApplyOrder);
19 | }
20 | /**
21 | * @name 修改申请认证
22 | * @param ICertificationApplyOrder.UpdateCertificationApplyOrder
23 | * @return {*} {Promise}
24 | * @link https://www.yuque.com/mlgrgm/lmm8g4/qoght3#Ykwby
25 | * @memberof CertificationApplyOrderController
26 | */
27 | async updateCertificationApplyOrder(): Promise {
28 | return await this.service.updateCertificationApplyOrder(this.event.data as ICertificationApplyOrder.UpdateCertificationApplyOrder);
29 | }
30 | /**
31 | * @name 对认证单进行审核/拒绝等操作
32 | * @param ICertificationApplyOrder.UpdateCertificationApplyOrderState
33 | * @return {*} {Promise}
34 | * @link https://www.yuque.com/mlgrgm/lmm8g4/qoght3#HhUZH
35 | * @memberof CertificationApplyOrderController
36 | */
37 | async updateCertificationApplyOrderState(): Promise {
38 | return await this.service.updateCertificationApplyOrderState(this.event.data as ICertificationApplyOrder.UpdateCertificationApplyOrderState);
39 | }
40 | /**
41 | * @name 申请单列表分页查询
42 | * @param ICertificationApplyOrder.GetCertificationApplyOrder
43 | * @return {*} {Promise}
44 | * @memberof CertificationApplyOrderController
45 | */
46 | async getCertificationApplyOrder(): Promise {
47 | return await this.service.getCertificationApplyOrder(this.event.data as ICertificationApplyOrder.GetCertificationApplyOrder);
48 | }
49 | };
50 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/qq-robot/src/services/group.ts:
--------------------------------------------------------------------------------
1 | const explain = require('explain');
2 | const createConfig = require('uni-config-center');
3 | const robotConfig = createConfig({
4 | pluginId: 'qq-robot'
5 | }) as {
6 | config: () => Record<'myqqApi' | 'myqqRobotUsername' | 'myqqRobotGroup', string>;
7 | };
8 |
9 | const coreConfig = createConfig({
10 | pluginId: 'core'
11 | }) as {
12 | config: () => Record<'CORE_API_TEST_HTTP_URL' | 'CORE_API_RELEASE_HTTP_URL' | 'CORE_API_TEST_ADMIN_TOKEN' | 'CORE_API_RELEASE_ADMIN_TOKEN', string>;
13 | };
14 | module.exports = class group extends explain.service {
15 | constructor(context) {
16 | super(context);
17 | }
18 | async postMessage(msg: string) {
19 | const { myqqApi, myqqRobotUsername, myqqRobotGroup } = robotConfig.config();
20 | const res = await uniCloud.httpclient.request(myqqApi, {
21 | method: 'POST',
22 | data: {
23 | function: 'Api_SendMsg', //要调用的函数英文名(查看右侧API列表)
24 | params: {
25 | c1: myqqRobotUsername, //参数1,要使用的机器人QQ
26 | c2: '2', //参数2,消息类型,2为群,以此类推...
27 | c3: myqqRobotGroup, //参数3,要发送的群号,以此类推...
28 | c4: '', //参数4,要发送的QQ,此处发的是群,所以这个要留空,以此类推...
29 | c5: msg //参数5,要发送的消息内容,以此类推...
30 | }
31 | },
32 | contentType: 'json',
33 | dataType: 'json'
34 | });
35 | return res;
36 | }
37 | // 调用http api 请求数据
38 | async getSampleQuestionList() {
39 | const { CORE_API_RELEASE_HTTP_URL, CORE_API_TEST_ADMIN_TOKEN, CORE_API_RELEASE_ADMIN_TOKEN, CORE_API_TEST_HTTP_URL } = coreConfig.config();
40 | const res = await uniCloud.httpclient.request(CORE_API_TEST_HTTP_URL + `/api/question/getSampleQuestionList`, {
41 | method: 'GET',
42 | data: {},
43 | headers: {
44 | 'uni-id-token': CORE_API_TEST_ADMIN_TOKEN
45 | },
46 | contentType: 'json',
47 | dataType: 'json'
48 | });
49 | // 判断是否请求成功
50 | if (res.status === 200) {
51 | // 循环其中的data
52 | const { data } = res.data as {
53 | data: {
54 | title: string;
55 | }[];
56 | };
57 | let str = '';
58 | if (Array.isArray(data)) {
59 | for (const key in data) {
60 | str += `${Number(key) + 1}: ${data[key].title} \n`;
61 | }
62 | await this.postMessage(str);
63 | }
64 | }
65 | return res;
66 | }
67 | };
68 |
69 | export {};
70 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/qq-robot/src/services/callback.ts:
--------------------------------------------------------------------------------
1 | const explain = require('explain');
2 | const createConfig = require('uni-config-center');
3 | const groupService = require('./group');
4 | const robotConfig = createConfig({
5 | pluginId: 'qq-robot'
6 | }) as {
7 | config: () => Record<'myqqApi' | 'myqqRobotUsername' | 'myqqRobotGroup' | 'myqqTriggerMessage', string | []>;
8 | };
9 |
10 | interface CallBackBody {
11 | MQ_robot: string;
12 | MQ_fromQQ: string;
13 | MQ_type: string;
14 | MQ_msg: string;
15 | }
16 | module.exports = class callBack extends explain.service {
17 | async main() {
18 | const group = new groupService(this);
19 | // 只有消息类型为 群 才会触发
20 | const { myqqRobotUsername } = robotConfig.config();
21 | // 判断请求头是否符合标准
22 | if ('qqrobot-callback' in this.event.headers && this.event.headers['qqrobot-callback']) {
23 | // 判断发送者是否是自身,如果是自身,就不处理
24 | const body: CallBackBody = JSON.parse(this.event.body);
25 | // 判断机器人qq和参数一样 且 fromqq不是机器人qq
26 | if (body.MQ_robot === myqqRobotUsername && body.MQ_fromQQ !== myqqRobotUsername) {
27 | // 解析QQ消息
28 | const messageData = decodeURI(body.MQ_msg);
29 | // 如果消息中含有艾特符号并且艾特是机器人的话,那么就触发
30 | const callData = `[%40${myqqRobotUsername}]+`;
31 | // 是否艾特了机器人
32 | const callSuccessStatus = messageData.indexOf(callData);
33 | if (callSuccessStatus > -1) {
34 | // 确认艾特了
35 | // 调用发送群组消息的api
36 | return await group.postMessage((await this.checkTrigger(messageData)) + `[@${body.MQ_fromQQ}]`); // 拼接一个艾特,意指回复
37 | }
38 | return null;
39 | } else {
40 | return null;
41 | }
42 | }
43 | }
44 | // 判断是否要进行trigger
45 | async checkTrigger(message: string) {
46 | // 将确认艾特之后才会触发checkTrigger这个方法
47 | const { myqqTriggerMessage } = robotConfig.config();
48 | if (Array.isArray(myqqTriggerMessage)) {
49 | // 循环trigger数组
50 | for (const key in myqqTriggerMessage) {
51 | const triggerItem = myqqTriggerMessage[key] as { trigger: string[]; message?: string };
52 | // 判断当前message是否存在在trigger中 (模糊匹配)
53 | for (const triggerIndex in triggerItem.trigger) {
54 | if (message.indexOf(triggerItem.trigger[triggerIndex]) > -1) {
55 | return triggerItem.message;
56 | }
57 | }
58 | }
59 | return '抱歉oh,我没听懂你说的话,请尝试对我说: 群主, 人呢, 有人吗 ';
60 | }
61 | }
62 | };
63 |
64 | export {};
65 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/common/tsbuffer-params-validate/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ts-validate",
3 | "version": "1.0.0",
4 | "lockfileVersion": 1,
5 | "requires": true,
6 | "dependencies": {
7 | "k8w-extend-native": {
8 | "version": "1.4.5",
9 | "resolved": "https://registry.npmjs.org/k8w-extend-native/-/k8w-extend-native-1.4.5.tgz",
10 | "integrity": "sha512-4yeqw4SDXQKwOYAq3DBIBm7L17sRu+vzlnLNRtKm4afsUO2klbIhQuMxdsH3Upsy4jZMdzW+AhEN5d4c5s3PxQ==",
11 | "requires": {
12 | "k8w-linq-array": "*",
13 | "k8w-super-date": "*",
14 | "k8w-super-object": "*"
15 | }
16 | },
17 | "k8w-linq-array": {
18 | "version": "0.2.7",
19 | "resolved": "https://registry.npmjs.org/k8w-linq-array/-/k8w-linq-array-0.2.7.tgz",
20 | "integrity": "sha512-E4hwi6c4lqC4b8zBkLK1IH/jOyLnc2lUDixG+DNAhjQmSWdL4KaXkwWmXmRztrxSPLbWPYU4qnmjgGHIZCC+YQ=="
21 | },
22 | "k8w-super-date": {
23 | "version": "0.1.3",
24 | "resolved": "https://registry.npmjs.org/k8w-super-date/-/k8w-super-date-0.1.3.tgz",
25 | "integrity": "sha512-IBqKOAMAXR/bgzu+rYI30tEMP/Y6Q8HQuqJiTkE2mLJg11yok9guoi8uZTynTahviVBndcfBpOgi1H/zhihv7w=="
26 | },
27 | "k8w-super-object": {
28 | "version": "0.3.0",
29 | "resolved": "https://registry.npmjs.org/k8w-super-object/-/k8w-super-object-0.3.0.tgz",
30 | "integrity": "sha512-u2jfh4goYXKZmSucaLaOTaNbLRatjv0CSRpzE0KU0732+9XtYZFd5vrdw/mzJfK5fPHb/zyikOSHDX5mJrav+g=="
31 | },
32 | "tsbuffer-schema": {
33 | "version": "2.0.2",
34 | "resolved": "https://registry.npmjs.org/tsbuffer-schema/-/tsbuffer-schema-2.0.2.tgz",
35 | "integrity": "sha512-uSlbDKe9u15ZMXakD+Jt2KY8CGjzekGojdJ+BXB6YZGQ2rZyYhYJrAXFXmOH9ocRC7tyeP347g1g8eyZ+s6A1A=="
36 | },
37 | "tsbuffer-validator": {
38 | "version": "2.0.4",
39 | "resolved": "https://registry.npmjs.org/tsbuffer-validator/-/tsbuffer-validator-2.0.4.tgz",
40 | "integrity": "sha512-ajW+/ivbJQtysoQpUXCKRYEKHDBNBemFlwFOUzcYxAbd7SUaOOoakxCdQPE+NPZk0pSHRYgw6U4+zhWxEWQSyg==",
41 | "requires": {
42 | "k8w-extend-native": "^1.4.5",
43 | "tsbuffer-schema": "~2.0.2",
44 | "tslib": "^2.3.0"
45 | }
46 | },
47 | "tslib": {
48 | "version": "2.3.1",
49 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
50 | "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/common/uni-ui.scss:
--------------------------------------------------------------------------------
1 |
2 | .uni-flex {
3 | display: flex;
4 | }
5 |
6 | .uni-flex-row {
7 | @extend .uni-flex;
8 | flex-direction: row;
9 | box-sizing: border-box;
10 | }
11 |
12 | .uni-flex-column {
13 | @extend .uni-flex;
14 | flex-direction: column;
15 | }
16 |
17 | .uni-color-gary {
18 | color: #3b4144;
19 | }
20 |
21 | /* 标题 */
22 | .uni-title {
23 | display: flex;
24 | margin-bottom: $uni-spacing-col-base;
25 | font-size: $uni-font-size-lg;
26 | font-weight: bold;
27 | color: #3b4144;
28 | }
29 |
30 | .uni-title-sub {
31 | display: flex;
32 | // margin-bottom: $uni-spacing-col-base;
33 | font-size: $uni-font-size-base;
34 | font-weight: 500;
35 | color: #3b4144;
36 | }
37 |
38 | /* 描述 额外文本 */
39 | .uni-note {
40 | margin-top: 10px;
41 | color: #999;
42 | font-size: $uni-font-size-sm;
43 | }
44 |
45 | /* 列表内容 */
46 | .uni-list-box {
47 | @extend .uni-flex-row;
48 | flex: 1;
49 | margin-top: 10px;
50 | }
51 |
52 | /* 略缩图 */
53 | .uni-thumb {
54 | flex-shrink: 0;
55 | margin-right: $uni-spacing-row-base;
56 | width: 125px;
57 | height: 75px;
58 | border-radius: $uni-border-radius-lg;
59 | overflow: hidden;
60 | border: 1px #f5f5f5 solid;
61 | image {
62 | width: 100%;
63 | height: 100%;
64 | }
65 | }
66 |
67 | .uni-media-box {
68 | @extend .uni-flex-row;
69 | // margin-bottom: $uni-spacing-col-base;
70 | border-radius: $uni-border-radius-lg;
71 | overflow: hidden;
72 | .uni-thumb {
73 | margin: 0;
74 | margin-left: 4px;
75 | flex-shrink: 1;
76 | width: 33%;
77 | border-radius:0;
78 | &:first-child {
79 | margin: 0;
80 | }
81 | }
82 | }
83 |
84 | /* 内容 */
85 | .uni-content {
86 | @extend .uni-flex-column;
87 | justify-content: space-between;
88 | }
89 |
90 | /* 列表footer */
91 | .uni-footer {
92 | @extend .uni-flex-row;
93 | justify-content: space-between;
94 | margin-top: $uni-spacing-col-lg;
95 | }
96 | .uni-footer-text {
97 | font-size: $uni-font-size-sm;
98 | color: $uni-text-color-grey;
99 | margin-left: 5px;
100 | }
101 |
102 | /* 标签 */
103 |
104 | .uni-tag {
105 | flex-shrink: 0;
106 | padding: 0 5px;
107 | border: 1px $uni-border-color solid;
108 | margin-right: $uni-spacing-row-sm;
109 | border-radius: $uni-border-radius-base;
110 | background: $uni-bg-color-grey;
111 | color: $uni-text-color;
112 | font-size: $uni-font-size-sm;
113 | }
114 |
115 | /* 链接 */
116 | .uni-link {
117 | margin-left: 10px;
118 | color: $uni-text-color;
119 | text-decoration: underline;
120 | }
121 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/common/explain/utils/datetime.js:
--------------------------------------------------------------------------------
1 | /**
2 | * dateTime模块,主要作用为日期时间处理
3 | */
4 | 'use strict';
5 |
6 | module.exports = class dateTime {
7 | static now(formatString, timezone) {
8 | let timestamp = new Date().getTime();
9 | if (formatString) {
10 | timestamp = dateTime.format(timestamp, formatString, timezone);
11 | }
12 | return timestamp;
13 | }
14 |
15 | static format(timestamp, formatString, timezone = 8) {
16 | var d = new Date(timestamp);
17 | let gmt = d.getTimezoneOffset(); // 本地时间和格林威治的时间差,单位为分钟
18 | d.setMinutes(d.getMinutes() + gmt); // 添补时间差至格林威治时间
19 | d.setHours(d.getHours() + timezone); // 加上时区
20 | var o = {
21 | 'M+': d.getMonth() + 1, //月份
22 | 'd+': d.getDate(), //日
23 | 'H+': d.getHours(), //小时
24 | 'm+': d.getMinutes(), //分
25 | 's+': d.getSeconds(), //秒
26 | 'q+': Math.floor((d.getMonth() + 3) / 3) //季度
27 | };
28 | if (/(y+)/.test(formatString)) {
29 | formatString = formatString.replace(RegExp.$1, (d.getFullYear() + '').substr(4 - RegExp.$1.length));
30 | }
31 | for (var k in o) {
32 | if (new RegExp('(' + k + ')').test(formatString)) {
33 | formatString = formatString.replace(RegExp.$1, RegExp.$1.length == 1 ? o[k] : ('00' + o[k]).substr(('' + o[k]).length));
34 | }
35 | }
36 | if (/(f+)/.test(formatString)) {
37 | formatString = formatString.replace(RegExp.$1, (d.getMilliseconds() + '').substr(3 - RegExp.$1.length));
38 | }
39 | return formatString;
40 | }
41 |
42 | static addYears(timestamp, value) {
43 | var date = new Date(timestamp);
44 | date.setFullYear(date.getFullYear() + value);
45 | return date.getTime();
46 | }
47 |
48 | static addMonths(timestamp, value) {
49 | var date = new Date(timestamp);
50 | date.setMonth(date.getMonth() + value);
51 | return date.getTime();
52 | }
53 |
54 | static addDays(timestamp, value) {
55 | var date = new Date(timestamp);
56 | date.setDate(date.getDate() + value);
57 | return date.getTime();
58 | }
59 |
60 | static addHours(timestamp, value) {
61 | var date = new Date(timestamp);
62 | date.setHours(date.getHours() + value);
63 | return date.getTime();
64 | }
65 |
66 | static addMinutes(timestamp, value) {
67 | var date = new Date(timestamp);
68 | date.setMinutes(date.getMinutes() + value);
69 | return date.getTime();
70 | }
71 |
72 | static addSeconds(timestamp, value) {
73 | var date = new Date(timestamp);
74 | date.setSeconds(date.getSeconds() + value);
75 | return date.getTime();
76 | }
77 |
78 | static addMilliseconds(timestamp, value) {
79 | var date = new Date(timestamp);
80 | date.setMilliseconds(date.getMilliseconds() + value);
81 | return date.getTime();
82 | }
83 | };
84 |
--------------------------------------------------------------------------------
/src/components/i-uniapp/i-mask/i-mask.vue:
--------------------------------------------------------------------------------
1 |
2 | {}" :class="{
3 | 'i-mask-zoom': zoom,
4 | 'i-mask-show': show
5 | }">
6 |
7 |
8 |
9 |
10 |
92 |
93 |
121 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/v1/src/controller/question.ts:
--------------------------------------------------------------------------------
1 | import * as explain from 'explain';
2 | import questionService from '../service/question';
3 | import * as IQuestion from '../../proto/question';
4 |
5 | export = class QuestionController extends explain.service {
6 | private service: questionService;
7 | constructor(e: CloudData) {
8 | super(e);
9 | this.service = new questionService(this);
10 | }
11 | /**
12 | * @name 添加题目
13 | * @param IQuestion.AddQuestion
14 | * @return {*} {Promise}
15 | * @link https://www.yuque.com/mlgrgm/lmm8g4/fssf4b#g13V0
16 | * @memberof QuestionController
17 | */
18 | async addQuestion(): Promise {
19 | return await this.service.addQuestion(this.event.data as IQuestion.AddQuestion);
20 | }
21 | /**
22 | * @name 修改题目
23 | * @param IQuestion.UpdateQuestion
24 | * @return {*} {Promise}
25 | * @link https://www.yuque.com/mlgrgm/lmm8g4/fssf4b#sl2QT
26 | * @memberof QuestionController
27 | */
28 | async updateQuestion(): Promise {
29 | return await this.service.updateQuestion(this.event.data as IQuestion.UpdateQuestion);
30 | }
31 | /**
32 | * @name 删除题目
33 | * @param IQuestion.DeleteQuestion
34 | * @return {*} {Promise}
35 | * @link https://www.yuque.com/mlgrgm/lmm8g4/fssf4b#iJ8Hr
36 | * @memberof QuestionController
37 | */
38 | async deleteQuestion(): Promise {
39 | return await this.service.deleteQuestion(this.event.data as IQuestion.DeleteQuestion);
40 | }
41 | /**
42 | * @name 审核题目
43 | * @param IQuestion.ExamineQuestion
44 | * @return {*} {Promise}
45 | * @link https://www.yuque.com/mlgrgm/lmm8g4/fssf4b#hIZhf
46 | * @memberof QuestionController
47 | */
48 | async examineQuestion(): Promise {
49 | return await this.service.examineQuestion(this.event.data as IQuestion.ExamineQuestion);
50 | }
51 | /**
52 | * @name 分页获取题目列表
53 | * @param IQuestion.GetQuestionList
54 | * @return {*} {Promise}
55 | * @memberof QuestionController
56 | */
57 | async getQuestionList(): Promise {
58 | return await this.service.getQuestionList(this.event.data as IQuestion.GetQuestionList);
59 | }
60 | /**
61 | * @name 浏览题目详情
62 | * @description(如果没有pageView就默认设置为1)
63 | * @param IQuestion.AddPageView
64 | * @return {*} {Promise}
65 | * @memberof QuestionController
66 | */
67 | async addPageView(): Promise {
68 | return await this.service.addPageView(this.event.data as IQuestion.AddPageView);
69 | }
70 | /**
71 | * @name 随机获取题目
72 | * @param IQuestion.GetSampleQuestionList
73 | * @return {*} {Promise}
74 | * @memberof QuestionController
75 | */
76 | async getSampleQuestionList(): Promise {
77 | return await this.service.getSampleQuestionList(this.event.data as IQuestion.GetSampleQuestionList);
78 | }
79 | };
80 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/common/form-data-utils/parser.js:
--------------------------------------------------------------------------------
1 | const BOUNDARY_REG = /^multipart\/.+?(?:;\s*boundary=(?:(?:"(.+)")|(?:([^\s]+))))$/i,
2 | LEADING_REG = /Content-Disposition:\sform-data;\sname="(.+?)"(?:;\sfilename="(.+?)")?/i,
3 | TYPE_REG = /Content-Type:\s(.+?)$/i,
4 | lineBreak = '\r\n';
5 |
6 | function split(buf, subBuf) {
7 | let currentIndex = 0,
8 | lastIndex = 0,
9 | bufArr = [];
10 | while ((lastIndex = buf.indexOf(subBuf, currentIndex)) !== -1) {
11 | bufArr.push(buf.slice(currentIndex, lastIndex));
12 | currentIndex = lastIndex + subBuf.length;
13 | lastIndex = buf.indexOf(subBuf, currentIndex);
14 | }
15 | return bufArr;
16 | }
17 |
18 | function readParam(buf) {
19 | let currentIndex = buf.indexOf(lineBreak) + lineBreak.length,
20 | lastIndex = currentIndex,
21 | lastCrlfIndex = buf.lastIndexOf(lineBreak),
22 | bufArr = [];
23 | while ((lastIndex = buf.indexOf(lineBreak, currentIndex)) !== -1) {
24 | bufArr.push(buf.slice(currentIndex, lastIndex));
25 | currentIndex = lastIndex + lineBreak.length;
26 | if (bufArr[bufArr.length - 1].length === 0) {
27 | bufArr.push(buf.slice(currentIndex, lastCrlfIndex));
28 | break;
29 | }
30 | }
31 | return bufArr;
32 | }
33 |
34 | module.exports = (event) => {
35 | const contentType = event.headers['content-type'] || event.headers['Content-Type'];
36 | const matchedBoundary = contentType.match(BOUNDARY_REG);
37 | const boundary = matchedBoundary[1] || matchedBoundary[2];
38 | const body = Buffer.from(event.body, 'base64');
39 |
40 | const paramsArr = split(body, Buffer.from(`--${boundary}`))
41 | .map((item) => {
42 | return readParam(item).filter((bufItem) => {
43 | return bufItem.length > 0;
44 | });
45 | })
46 | .filter((item) => {
47 | return item.length === 2 || item.length === 3 || item.length === 4;
48 | })
49 | .map((item) => {
50 | const result = {};
51 | const leadingMatched = item[0].toString().match(LEADING_REG);
52 | result.name = decodeURIComponent(leadingMatched[1]);
53 | switch (item.length) {
54 | case 2:
55 | result.value = item[1].toString();
56 | break;
57 | case 3:
58 | result.filename = decodeURIComponent(leadingMatched[2]);
59 | result.contentType = item[1].toString().match(TYPE_REG)[1];
60 | result.fileContent = item[2];
61 | break;
62 | case 4:
63 | result.filename = decodeURIComponent(leadingMatched[2]);
64 | result.contentType = item[1].toString().match(TYPE_REG)[1];
65 | result.fileContent = item[3];
66 | break;
67 | default:
68 | break;
69 | }
70 | return result;
71 | });
72 |
73 | const params = {};
74 | paramsArr.forEach((item) => {
75 | const name = item.name;
76 | delete item.name;
77 | params[name] = item.fileContent ? item : item.value;
78 | });
79 |
80 | return params;
81 | };
82 |
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/common/uni-config-center/readme.md:
--------------------------------------------------------------------------------
1 | # 为什么使用uni-config-center
2 |
3 | 实际开发中很多插件需要配置文件才可以正常运行,如果每个插件都单独进行配置的话就会产生下面这样的目录结构
4 |
5 | ```bash
6 | cloudfunctions
7 | └─────common 公共模块
8 | ├─plugin-a // 插件A对应的目录
9 | │ ├─index.js
10 | │ ├─config.json // plugin-a对应的配置文件
11 | │ └─other-file.cert // plugin-a依赖的其他文件
12 | └─plugin-b // plugin-b对应的目录
13 | ├─index.js
14 | └─config.json // plugin-b对应的配置文件
15 | ```
16 |
17 | 假设插件作者要发布一个项目模板,里面使用了很多需要配置的插件,无论是作者发布还是用户使用都是一个大麻烦。
18 |
19 | uni-config-center就是用了统一管理这些配置文件的,使用uni-config-center后的目录结构如下
20 |
21 | ```bash
22 | cloudfunctions
23 | └─────common 公共模块
24 | ├─plugin-a // 插件A对应的目录
25 | │ └─index.js
26 | ├─plugin-b // plugin-b对应的目录
27 | │ └─index.js
28 | └─uni-config-center
29 | ├─index.js // config-center入口文件
30 | ├─plugin-a
31 | │ ├─config.json // plugin-a对应的配置文件
32 | │ └─other-file.cert // plugin-a依赖的其他文件
33 | └─plugin-b
34 | └─config.json // plugin-b对应的配置文件
35 | ```
36 |
37 | 使用uni-config-center后的优势
38 |
39 | - 配置文件统一管理,分离插件主体和配置信息,更新插件更方便
40 | - 支持对config.json设置schema,插件使用者在HBuilderX内编写config.json文件时会有更好的提示(后续HBuilderX会提供支持)
41 |
42 | # 用法
43 |
44 | 在要使用uni-config-center的公共模块或云函数内引入uni-config-center依赖,请参考:[使用公共模块](https://uniapp.dcloud.net.cn/uniCloud/cf-common)
45 |
46 | ```js
47 | const createConfig = require('uni-config-center')
48 |
49 | const uniIdConfig = createConfig({
50 | pluginId: 'uni-id', // 插件id
51 | defaultConfig: { // 默认配置
52 | tokenExpiresIn: 7200,
53 | tokenExpiresThreshold: 600,
54 | },
55 | customMerge: function(defaultConfig, userConfig) { // 自定义默认配置和用户配置的合并规则,不设置的情况侠会对默认配置和用户配置进行深度合并
56 | // defaudltConfig 默认配置
57 | // userConfig 用户配置
58 | return Object.assign(defaultConfig, userConfig)
59 | }
60 | })
61 |
62 |
63 | // 以如下配置为例
64 | // {
65 | // "tokenExpiresIn": 7200,
66 | // "passwordErrorLimit": 6,
67 | // "bindTokenToDevice": false,
68 | // "passwordErrorRetryTime": 3600,
69 | // "app-plus": {
70 | // "tokenExpiresIn": 2592000
71 | // },
72 | // "service": {
73 | // "sms": {
74 | // "codeExpiresIn": 300
75 | // }
76 | // }
77 | // }
78 |
79 | // 获取配置
80 | uniIdConfig.config() // 获取全部配置,注意:uni-config-center内不存在对应插件目录时会返回空对象
81 | uniIdConfig.config('tokenExpiresIn') // 指定键值获取配置,返回:7200
82 | uniIdConfig.config('service.sms.codeExpiresIn') // 指定键值获取配置,返回:300
83 | uniIdConfig.config('tokenExpiresThreshold', 600) // 指定键值获取配置,如果不存在则取传入的默认值,返回:600
84 |
85 | // 获取文件绝对路径
86 | uniIdConfig.resolve('custom-token.js') // 获取uni-config-center/uni-id/custom-token.js文件的路径
87 |
88 | // 引用文件(require)
89 | uniIDConfig.requireFile('custom-token.js') // 使用require方式引用uni-config-center/uni-id/custom-token.js文件。文件不存在时返回undefined,文件内有其他错误导致require失败时会抛出错误。
90 |
91 | // 判断是否包含某文件
92 | uniIDConfig.hasFile('custom-token.js') // 配置目录是否包含某文件,true: 文件存在,false: 文件不存在
93 | ```
--------------------------------------------------------------------------------
/uniCloud-aliyun/cloudfunctions/common/form-data-utils/builder.js:
--------------------------------------------------------------------------------
1 | // 搭配uniCloud.httpclient.request使用
2 | // content: formData.getBuffer()
3 | // header: formData.getHeaders(userHeaders)
4 | module.exports = class FormData {
5 | constructor() {
6 | this._shouldUseCache = false;
7 | this._cachedBuffer = null;
8 | this._lineBreak = '\r\n';
9 | this._boundary = '------FormDataBaseBoundary' + Math.random().toString(36).substring(2);
10 | this.dataList = [];
11 | }
12 |
13 | _addData(data) {
14 | this._shouldUseCache = false;
15 | if (this.dataList.length === 0) {
16 | this.dataList.push(data);
17 | return;
18 | }
19 | const lastData = this.dataList[this.dataList.length - 1],
20 | lastType = Buffer.isBuffer(lastData) ? 'buffer' : 'other',
21 | currentType = Buffer.isBuffer(data) ? 'buffer' : 'other';
22 | switch (`${lastType}_${currentType}`) {
23 | case 'buffer_buffer':
24 | this.dataList.push(this._lineBreak);
25 | this.dataList.push(data);
26 | break;
27 | case 'buffer_other':
28 | this.dataList.push(this._lineBreak + data);
29 | break;
30 | case 'other_buffer':
31 | this.dataList[this.dataList.length - 1] = lastData + '\r\n';
32 | this.dataList.push(data);
33 | break;
34 | case 'other_other':
35 | this.dataList[this.dataList.length - 1] = lastData + '\r\n' + data;
36 | break;
37 | default:
38 | break;
39 | }
40 | }
41 |
42 | append(name, value, options) {
43 | this._addData('--' + this._boundary);
44 | let leading = `Content-Disposition: form-data; name="${encodeURIComponent(name)}"`;
45 | if (Buffer.isBuffer(value)) {
46 | if (!options.filename || !options.contentType) {
47 | throw new Error('filename and contentType required');
48 | }
49 | leading += `; filename="${encodeURIComponent(options.filename)}"`;
50 | this._addData(leading);
51 | this._addData(`Content-Type: ${options.contentType}`);
52 | this._addData('');
53 | this._addData(value);
54 | } else {
55 | this._addData(leading);
56 | this._addData('');
57 | this._addData(value);
58 | }
59 | }
60 |
61 | getHeaders(options) {
62 | const headers = {
63 | 'Content-Type': 'multipart/form-data; boundary=' + this._boundary
64 | // 'Content-Length': this.getBuffer().length
65 | };
66 | return Object.assign(headers, options);
67 | }
68 |
69 | getBuffer() {
70 | if (this._shouldUseCache) {
71 | return this._cachedBuffer;
72 | }
73 | this._shouldUseCache = true;
74 | let dataBuffer = Buffer.alloc(0);
75 | this.dataList.forEach((item) => {
76 | if (Buffer.isBuffer(item)) {
77 | dataBuffer = Buffer.concat([dataBuffer, item]);
78 | } else {
79 | dataBuffer = Buffer.concat([dataBuffer, Buffer.from('' + item)]);
80 | }
81 | });
82 | dataBuffer = Buffer.concat([dataBuffer, Buffer.from(`${this._lineBreak}--${this._boundary}--`)]);
83 | this._cachedBuffer = dataBuffer;
84 | return dataBuffer;
85 | }
86 | };
87 |
--------------------------------------------------------------------------------
/src/uni_modules/uni-search-bar/readme.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | ## SearchBar 搜索栏
4 |
5 | > **组件名:uni-search-bar**
6 | > 代码块: `uSearchBar`
7 |
8 |
9 | 评分组件
10 |
11 | ### 安装方式
12 |
13 | 本组件符合[easycom](https://uniapp.dcloud.io/collocation/pages?id=easycom)规范,`HBuilderX 2.5.5`起,只需将本组件导入项目,在页面`template`中即可直接使用,无需在页面中`import`和注册`components`。
14 |
15 | 如需通过`npm`方式使用`uni-ui`组件,另见文档:[https://ext.dcloud.net.cn/plugin?id=55](https://ext.dcloud.net.cn/plugin?id=55)
16 |
17 | ### 基本用法
18 |
19 | 在 ``template`` 中使用组件
20 |
21 | ```html
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 | ```
34 |
35 |
36 | ## API
37 | ### SearchBar Props
38 |
39 | |属性名 |类型 |默认值 |说明 |
40 | |:-: |:-: |:-: |:-: |
41 | |value/v-model |StringNumber | |搜索栏绑定值 |
42 | |placeholder |String |搜索 |搜索栏Placeholder |
43 | |radius |Number |10 |搜索栏圆角,单位px |
44 | |clearButton |String |auto |是否显示清除按钮,可选值`always`-一直显示、`auto`-输入框不为空时显示、`none`-一直不显示 |
45 | |cancelButton |String |auto |是否显示取消按钮,可选值`always`-一直显示、`auto`-输入框不为空时显示、`none`-一直不显示 |
46 | |cancelText |String |取消 |取消按钮的文字 |
47 | |bgColor |String |#F8F8F8|输入框背景颜色 |
48 | |maxlength |Number |100 |输入最大长度 |
49 | |focus |Boolean |false | |
50 |
51 |
52 | ### SearchBar Events
53 |
54 | |事件称名 |说明 |返回参数 |
55 | |:-: |:-: |:-: |
56 | |@confirm |uniSearchBar 的输入框 confirm 事件,返回参数为uniSearchBar的value |e={value:Number} |
57 | |@input |uniSearchBar 的 value 改变时触发事件,返回参数为uniSearchBar的value|e=value |
58 | |@cancel |点击取消按钮时触发事件,返回参数为uniSearchBar的value |e={value:Number} |
59 | |@clear |点击清除按钮时触发事件,返回参数为uniSearchBar的value |e={value:Number} |
60 | |@focus |input 获取焦点时触发事件,返回参数为uniSearchBar的value |e={value:Number} |
61 | |@blur |input 失去焦点时触发事件,返回参数为uniSearchBar的value |e={value:Number} |
62 |
63 | ### 替换 icon 的 slot 插槽
64 |
65 | |插槽称名 |说明 |
66 | |:-: |:-: |
67 | |searchIcon |替换组件的搜索图标|
68 | |clearIcon |替换组件的清除图标|
69 |
70 | ```html
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 | X
79 |
80 |
81 | ```
82 |
83 |
84 | ## 组件示例
85 |
86 | 点击查看:[https://hellouniapp.dcloud.net.cn/pages/extUI/search-bar/search-bar](https://hellouniapp.dcloud.net.cn/pages/extUI/search-bar/search-bar)
--------------------------------------------------------------------------------
/src/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "剑指题解",
3 | "appid": "__UNI__9FDF0B4",
4 | "description": "",
5 | "versionName": "1.0.0",
6 | "versionCode": "100",
7 | "transformPx": false,
8 | "app-plus": {
9 | /* 5+App特有相关 */
10 | "usingComponents": true,
11 | "splashscreen": {
12 | "alwaysShowBeforeRender": true,
13 | "waiting": true,
14 | "autoclose": true,
15 | "delay": 0
16 | },
17 | "modules": {},
18 | /* 模块配置 */
19 | "distribute": {
20 | /* 应用发布信息 */
21 | "android": {
22 | /* android打包配置 */
23 | "permissions": [
24 | "",
25 | "",
26 | "",
27 | "",
28 | "",
29 | "",
30 | "",
31 | "",
32 | "",
33 | "",
34 | "",
35 | "",
36 | "",
37 | "",
38 | "",
39 | "",
40 | "",
41 | "",
42 | "",
43 | "",
44 | "",
45 | ""
46 | ]
47 | },
48 | "ios": {},
49 | /* ios打包配置 */
50 | "sdkConfigs": {}
51 | }
52 | },
53 | /* SDK配置 */
54 | "quickapp": {},
55 | /* 快应用特有相关 */
56 | "mp-weixin": {
57 | /* 微信小程序特有相关 */
58 | "appid": "wxe3f7d53545e88cb6",
59 | "setting": {
60 | "urlCheck": false
61 | },
62 | "usingComponents": true
63 | },
64 | "mp-alipay": {
65 | "usingComponents": true
66 | },
67 | "mp-baidu": {
68 | "usingComponents": true
69 | },
70 | "mp-toutiao": {
71 | "usingComponents": true
72 | },
73 | "mp-qq": {
74 | "usingComponents": true,
75 | "setting": {
76 | "urlCheck": false
77 | },
78 | "appid": "1111697492"
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "剑指题解",
3 | "appid": "__UNI__9FDF0B4",
4 | "description": "",
5 | "versionName": "1.0.0",
6 | "versionCode": "100",
7 | "transformPx": false,
8 | "app-plus": {
9 | /* 5+App特有相关 */
10 | "usingComponents": true,
11 | "splashscreen": {
12 | "alwaysShowBeforeRender": true,
13 | "waiting": true,
14 | "autoclose": true,
15 | "delay": 0
16 | },
17 | "modules": {},
18 | /* 模块配置 */
19 | "distribute": {
20 | /* 应用发布信息 */
21 | "android": {
22 | /* android打包配置 */
23 | "permissions": [
24 | "",
25 | "",
26 | "",
27 | "",
28 | "",
29 | "",
30 | "",
31 | "",
32 | "",
33 | "",
34 | "",
35 | "",
36 | "",
37 | "",
38 | "",
39 | "",
40 | "",
41 | "",
42 | "",
43 | "",
44 | "",
45 | ""
46 | ]
47 | },
48 | "ios": {},
49 | /* ios打包配置 */
50 | "sdkConfigs": {}
51 | }
52 | },
53 | /* SDK配置 */
54 | "quickapp": {},
55 | /* 快应用特有相关 */
56 | "mp-weixin": {
57 | /* 微信小程序特有相关 */
58 | "appid": "wxe3f7d53545e88cb6",
59 | "setting": {
60 | "urlCheck": false
61 | },
62 | "usingComponents": true
63 | },
64 | "mp-alipay": {
65 | "usingComponents": true
66 | },
67 | "mp-baidu": {
68 | "usingComponents": true
69 | },
70 | "mp-toutiao": {
71 | "usingComponents": true
72 | },
73 | "mp-qq": {
74 | "usingComponents": true,
75 | "setting": {
76 | "urlCheck": false
77 | },
78 | "appid": "1111697492"
79 | },
80 | "vueVersion": "3"
81 | }
82 |
--------------------------------------------------------------------------------
/src/uni_modules/uni-popup/components/uni-popup-message/uni-popup-message.vue:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
69 |
139 |
--------------------------------------------------------------------------------