├── 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 | 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 | 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 | 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 | 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 | 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 | 6 | 43 | 59 | -------------------------------------------------------------------------------- /src/components/i-uniapp/i-field/i-field.vue: -------------------------------------------------------------------------------- 1 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 8 | 9 | 69 | 139 | --------------------------------------------------------------------------------