diff --git a/package.json b/package.json index 6f0e2c0..1b261ec 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,6 @@ "@cool-midway/cache-manager-fs-hash": "^7.0.0", "@cool-midway/cloud": "^7.0.0", "@cool-midway/core": "^7.1.4", - "@cool-midway/file": "^7.0.5", "@cool-midway/iot": "^7.0.0", "@cool-midway/rpc": "^7.0.0", "@cool-midway/task": "^7.0.0", diff --git a/src/configuration.ts b/src/configuration.ts index 5b7eb47..03493ca 100644 --- a/src/configuration.ts +++ b/src/configuration.ts @@ -10,8 +10,8 @@ import * as localTask from '@midwayjs/task'; // import * as crossDomain from '@midwayjs/cross-domain'; import * as cool from '@cool-midway/core'; import * as cloud from '@cool-midway/cloud'; -import * as file from '@cool-midway/file'; import { ILogger } from '@midwayjs/logger'; +import * as upload from '@midwayjs/upload'; import { IMidwayApplication } from '@midwayjs/core'; // import * as swagger from '@midwayjs/swagger'; // import * as rpc from '@cool-midway/rpc'; @@ -34,10 +34,10 @@ import { IMidwayApplication } from '@midwayjs/core'; validate, // 本地任务 http://midwayjs.org/docs/legacy/task localTask, + // 文件上传 + upload, // cool-admin 官方组件 https://cool-js.com cool, - // 文件上传 本地 阿里云存储 腾讯云存储 七牛云存储 - file, // rpc 微服务 远程调用 // rpc, // 任务与队列 diff --git a/src/modules/base/controller/admin/comm.ts b/src/modules/base/controller/admin/comm.ts index 11ef46d..ca0c43d 100644 --- a/src/modules/base/controller/admin/comm.ts +++ b/src/modules/base/controller/admin/comm.ts @@ -5,7 +5,7 @@ import { BaseSysLoginService } from '../../service/sys/login'; import { BaseSysPermsService } from '../../service/sys/perms'; import { BaseSysUserService } from '../../service/sys/user'; import { Context } from '@midwayjs/koa'; -import { CoolFile } from '@cool-midway/file'; +import { PluginService } from '../../../plugin/service/info'; /** * Base 通用接口 一般写不需要权限过滤的接口 @@ -26,7 +26,7 @@ export class BaseCommController extends BaseController { ctx: Context; @Inject() - coolFile: CoolFile; + pluginService: PluginService; /** * 获得个人信息 @@ -60,7 +60,8 @@ export class BaseCommController extends BaseController { */ @Post('/upload', { summary: '文件上传' }) async upload() { - return this.ok(await this.coolFile.upload(this.ctx)); + const file = await this.pluginService.getInstance('upload'); + return this.ok(await file.upload(this.ctx)); } /** @@ -68,7 +69,8 @@ export class BaseCommController extends BaseController { */ @Get('/uploadMode', { summary: '文件上传模式' }) async uploadMode() { - return this.ok(await this.coolFile.getMode()); + const file = await this.pluginService.getInstance('upload'); + return this.ok(await file.getMode()); } /** diff --git a/src/modules/demo/controller/open/plugin.ts b/src/modules/demo/controller/open/plugin.ts index 4c69760..362af90 100644 --- a/src/modules/demo/controller/open/plugin.ts +++ b/src/modules/demo/controller/open/plugin.ts @@ -12,7 +12,58 @@ export class OpenDemoPluginController extends BaseController { @Get('/invoke', { summary: '调用插件' }) async invoke() { - const result = await this.pluginService.invoke('test', 'show', 1, 2); - return this.ok(result); + const plugin = await this.pluginService.getInstance('pay-ali'); + + // 获得插件配置 + const config = await plugin['getConfig'](); + + // 生成订单号 + const orderNum = plugin['createOrderNum'](); + + // 获得支付SDK实例 + const instance = await plugin.getInstance(); + + // 调用支付接口 + const result = instance.pageExec('alipay.trade.page.pay', { + notify_url: config.notifyUrl, + bizContent: { + out_trade_no: orderNum, + total_amount: '0.01', + subject: '测试', + product_code: 'FAST_INSTANT_TRADE_PAY', + body: '测试订单', + qr_pay_mode: '2', + }, + }); + + console.log(result); + + // 获得插件实例 + // const plugin = await this.pluginService.getInstance('pay-wx'); + + // // 获得插件配置 + // const config = await plugin['getConfig'](); + + // // 生成订单号 + // const orderNum = plugin['createOrderNum'](); + + // // 获得微信支付 SDK 实例 + // const instance = await plugin['getInstance'](); + + // // Native,返回的信息可以直接生成二维码,用户扫码支付 + // const params = { + // description: '测试', + // out_trade_no: orderNum, + // notify_url: config.notify_url, + // amount: { + // total: 1, + // }, + // scene_info: { + // payer_client_ip: 'ip', + // }, + // }; + // const result = await instance.transactions_native(params); + // console.log(result); + return this.ok(); } } diff --git a/src/modules/plugin/event/app.ts b/src/modules/plugin/event/app.ts index 1509ad2..cb2a2c5 100644 --- a/src/modules/plugin/event/app.ts +++ b/src/modules/plugin/event/app.ts @@ -1,7 +1,8 @@ import { CoolEvent, Event } from '@cool-midway/core'; -import { App, Config, ILogger, Logger } from '@midwayjs/core'; +import { App, Config, ILogger, Inject, Logger } from '@midwayjs/core'; import { IMidwayKoaApplication } from '@midwayjs/koa'; -import { PluginCenterService } from '../service/center'; +import { PLUGIN_CACHE_KEY, PluginCenterService } from '../service/center'; +import { CacheManager } from '@midwayjs/cache'; /** * 修改jwt.secret @@ -17,8 +18,12 @@ export class BaseAppEvent { @App() app: IMidwayKoaApplication; + @Inject() + cacheManager: CacheManager; + @Event('onServerReady') async onServerReady() { - await this.app.getApplicationContext().getAsync(PluginCenterService); + await this.cacheManager.set(PLUGIN_CACHE_KEY, []); + this.app.getApplicationContext().getAsync(PluginCenterService); } } diff --git a/src/modules/plugin/hooks/upload/interface.ts b/src/modules/plugin/hooks/upload/interface.ts index 965b99d..4f0cdfc 100644 --- a/src/modules/plugin/hooks/upload/interface.ts +++ b/src/modules/plugin/hooks/upload/interface.ts @@ -52,5 +52,5 @@ export interface BaseUpload { * @param ctx * @param key 文件路径 */ - upload(ctx): Promise; + upload(ctx): Promise; } diff --git a/src/modules/plugin/service/center.ts b/src/modules/plugin/service/center.ts index dba4c42..0ebfe22 100644 --- a/src/modules/plugin/service/center.ts +++ b/src/modules/plugin/service/center.ts @@ -3,6 +3,7 @@ import { App, IMidwayApplication, Init, + Inject, Scope, ScopeEnum, } from '@midwayjs/core'; @@ -13,6 +14,9 @@ import { InjectEntityModel } from '@midwayjs/typeorm'; import { Repository } from 'typeorm'; import { PluginInfo } from '../interface'; import * as _ from 'lodash'; +import { CacheManager } from '@midwayjs/cache'; + +export const PLUGIN_CACHE_KEY = 'PLUGIN_INIT'; /** * 插件中心 @@ -32,11 +36,18 @@ export class PluginCenterService { @InjectEntityModel(PluginInfoEntity) pluginInfoEntity: Repository; + @Inject() + cacheManager: CacheManager; + @Init() async init() { + const inits: any[] = (await this.cacheManager.get(PLUGIN_CACHE_KEY)) || []; + const pid = process.pid; + if (inits.includes(pid)) return; this.plugins.clear(); await this.initHooks(); await this.initPlugin(); + await this.cacheManager.set(PLUGIN_CACHE_KEY, inits.concat([process.pid])); } /** @@ -75,17 +86,25 @@ export class PluginCenterService { /** * 初始化插件 */ - async initPlugin() { - const plugins = await this.pluginInfoEntity.findBy({ status: 1 }); + async initPlugin(hook?: string) { + const find: any = { status: 1 }; + if (hook) { + find.hook = hook; + } + const plugins = await this.pluginInfoEntity.findBy(find); for (const plugin of plugins) { const instance = await this.getInstance(plugin.content.data); - this.pluginInfos.set(plugin.keyName, { - ...plugin.pluginJson, - config: this.getConfig(plugin.config), - }); if (plugin.hook) { + this.pluginInfos.set(plugin.hook, { + ...plugin.pluginJson, + config: this.getConfig(plugin.config), + }); await this.register(plugin.hook, instance); } else { + this.pluginInfos.set(plugin.keyName, { + ...plugin.pluginJson, + config: this.getConfig(plugin.config), + }); await this.register(plugin.keyName, instance); } } diff --git a/src/modules/plugin/service/info.ts b/src/modules/plugin/service/info.ts index a4f5f15..27fd8e5 100644 --- a/src/modules/plugin/service/info.ts +++ b/src/modules/plugin/service/info.ts @@ -3,11 +3,12 @@ import { BaseService, CoolCommException } from '@cool-midway/core'; import { InjectEntityModel } from '@midwayjs/typeorm'; import { Equal, Not, Repository } from 'typeorm'; import { PluginInfoEntity } from '../entity/info'; -import { IMidwayApplication, IMidwayContext } from '@midwayjs/core'; +import { Config, IMidwayApplication, IMidwayContext } from '@midwayjs/core'; import * as _ from 'lodash'; import { PluginInfo } from '../interface'; -import { PluginCenterService } from './center'; +import { PLUGIN_CACHE_KEY, PluginCenterService } from './center'; import * as fs from 'fs'; +import { CacheManager } from '@midwayjs/cache'; /** * 插件信息 @@ -26,12 +27,26 @@ export class PluginService extends BaseService { @Inject() pluginCenterService: PluginCenterService; + @Config('module.plugin.hooks') + hooksConfig; + + @Inject() + cacheManager: CacheManager; + /** * 初始化 * @param data * @param type */ async modifyAfter() { + await this.reInit(); + } + + /** + * 需要重新初始化插件 + */ + async reInit() { + await this.cacheManager.set(PLUGIN_CACHE_KEY, []); await this.pluginCenterService.init(); } @@ -79,6 +94,7 @@ export class PluginService extends BaseService { */ async getInstance(key: string) { await this.checkStatus(key); + await this.pluginCenterService.init(); const instance = new (await this.pluginCenterService.plugins.get(key))(); await instance.init( this.pluginCenterService.pluginInfos.get(key), @@ -93,10 +109,13 @@ export class PluginService extends BaseService { * @param key */ async checkStatus(key: string) { - const info = await this.pluginInfoEntity.findOneBy({ - keyName: Equal(key), - status: 1, - }); + if (Object.keys(this.hooksConfig).includes(key)) { + return; + } + const info = await this.pluginInfoEntity + .createQueryBuilder('a') + .where({ status: 1, keyName: Equal(key) }) + .getOne(); if (!info) { throw new CoolCommException('插件不存在或已禁用'); } @@ -232,6 +251,6 @@ export class PluginService extends BaseService { await this.pluginInfoEntity.insert(data); } // 初始化插件 - await this.pluginCenterService.init(); + await this.reInit(); } } diff --git a/src/modules/space/controller/admin/info.ts b/src/modules/space/controller/admin/info.ts index a684b1e..11f3a07 100644 --- a/src/modules/space/controller/admin/info.ts +++ b/src/modules/space/controller/admin/info.ts @@ -1,4 +1,4 @@ -import { Config, Get, Provide } from '@midwayjs/decorator'; +import { Provide } from '@midwayjs/decorator'; import { CoolController, BaseController } from '@cool-midway/core'; import { SpaceInfoEntity } from '../../entity/info'; import { SpaceInfoService } from '../../service/info'; diff --git a/src/modules/space/service/info.ts b/src/modules/space/service/info.ts index 7ceca1e..417588a 100644 --- a/src/modules/space/service/info.ts +++ b/src/modules/space/service/info.ts @@ -1,8 +1,9 @@ import { SpaceInfoEntity } from './../entity/info'; -import { Config, Provide } from '@midwayjs/decorator'; -import { BaseService, CoolFileConfig, MODETYPE } from '@cool-midway/core'; +import { Inject, Provide } from '@midwayjs/decorator'; +import { BaseService, MODETYPE } from '@cool-midway/core'; import { InjectEntityModel } from '@midwayjs/typeorm'; import { Repository } from 'typeorm'; +import { PluginService } from '../../plugin/service/info'; /** * 文件信息 @@ -12,15 +13,17 @@ export class SpaceInfoService extends BaseService { @InjectEntityModel(SpaceInfoEntity) spaceInfoEntity: Repository; - @Config('cool.file') - config: CoolFileConfig; + @Inject() + pluginService: PluginService; /** * 新增 */ async add(param) { - if (this.config.mode == MODETYPE.LOCAL) { - param.key = param.url.replace(this.config.domain, ''); + const result = await this.pluginService.invoke('upload', 'getMode'); + const config = await this.pluginService.getConfig('upload'); + if (result.mode == MODETYPE.LOCAL) { + param.key = param.url.replace(config.domain, ''); } return super.add(param); } diff --git a/src/modules/user/config.ts b/src/modules/user/config.ts index 6e0946b..4b250d2 100644 --- a/src/modules/user/config.ts +++ b/src/modules/user/config.ts @@ -41,7 +41,7 @@ export default () => { // 刷新token 过期时间,单位秒 refreshExpire: 60 * 60 * 24 * 30, // jwt 秘钥 - secret: 'cool-app-xxxxxx', + secret: '98591b81ce3111eebb6f5ba31567ea59', }, } as ModuleConfig; }; diff --git a/src/modules/user/controller/admin/address.ts b/src/modules/user/controller/admin/address.ts new file mode 100644 index 0000000..0a49842 --- /dev/null +++ b/src/modules/user/controller/admin/address.ts @@ -0,0 +1,11 @@ +import { CoolController, BaseController } from '@cool-midway/core'; +import { UserAddressEntity } from '../../entity/address'; + +/** + * 用户-地址 + */ +@CoolController({ + api: ['add', 'delete', 'update', 'info', 'list', 'page'], + entity: UserAddressEntity, +}) +export class AdminUserAddressesController extends BaseController {} diff --git a/src/modules/user/entity/address.ts b/src/modules/user/entity/address.ts new file mode 100644 index 0000000..6b93391 --- /dev/null +++ b/src/modules/user/entity/address.ts @@ -0,0 +1,34 @@ +import { BaseEntity } from '@cool-midway/core'; +import { Entity, Column, Index } from 'typeorm'; + +/** + * 用户模块-收货地址 + */ +@Entity('user_address') +export class UserAddressEntity extends BaseEntity { + @Index() + @Column({ comment: '用户ID' }) + userId: number; + + @Column({ comment: '联系人' }) + contact: string; + + @Index() + @Column({ comment: '手机号', length: 11 }) + phone: string; + + @Column({ comment: '省' }) + province: string; + + @Column({ comment: '市' }) + city: string; + + @Column({ comment: '区' }) + district: string; + + @Column({ comment: '地址' }) + address: string; + + @Column({ comment: '是否默认', default: false }) + isDefault: boolean; +} diff --git a/src/modules/user/service/info.ts b/src/modules/user/service/info.ts index 3a37042..a6c8b2a 100644 --- a/src/modules/user/service/info.ts +++ b/src/modules/user/service/info.ts @@ -3,10 +3,10 @@ import { BaseService, CoolCommException } from '@cool-midway/core'; import { InjectEntityModel } from '@midwayjs/typeorm'; import { Repository } from 'typeorm'; import { UserInfoEntity } from '../entity/info'; -import { CoolFile } from '@cool-midway/file'; import { v1 as uuid } from 'uuid'; import { UserSmsService } from './sms'; import * as md5 from 'md5'; +import { PluginService } from '../../plugin/service/info'; /** * 用户信息 @@ -17,7 +17,7 @@ export class UserInfoService extends BaseService { userInfoEntity: Repository; @Inject() - file: CoolFile; + pluginService: PluginService; @Inject() userSmsService: UserSmsService; @@ -59,7 +59,8 @@ export class UserInfoService extends BaseService { const info = await this.person(id); // 修改了头像要重新处理 if (param.avatarUrl && info.avatarUrl != param.avatarUrl) { - param.avatarUrl = await this.file.downAndUpload( + const file = await this.pluginService.getInstance('upload'); + param.avatarUrl = await file.downAndUpload( param.avatarUrl, uuid() + '.png' ); diff --git a/src/modules/user/service/login.ts b/src/modules/user/service/login.ts index 825f0d9..5570347 100644 --- a/src/modules/user/service/login.ts +++ b/src/modules/user/service/login.ts @@ -6,11 +6,11 @@ import { UserInfoEntity } from '../entity/info'; import { UserWxService } from './wx'; import * as jwt from 'jsonwebtoken'; import { UserWxEntity } from '../entity/wx'; -import { CoolFile } from '@cool-midway/file'; import { BaseSysLoginService } from '../../base/service/sys/login'; import { UserSmsService } from './sms'; import { v1 as uuid } from 'uuid'; import * as md5 from 'md5'; +import { PluginService } from '../../plugin/service/info'; /** * 登录 @@ -33,7 +33,7 @@ export class UserLoginService extends BaseService { baseSysLoginService: BaseSysLoginService; @Inject() - file: CoolFile; + pluginService: PluginService; @Inject() userSmsService: UserSmsService; @@ -152,7 +152,8 @@ export class UserLoginService extends BaseService { const unionid = wxUserInfo.unionid ? wxUserInfo.unionid : wxUserInfo.openid; let userInfo: any = await this.userInfoEntity.findOneBy({ unionid }); if (!userInfo) { - const avatarUrl = await this.file.downAndUpload( + const file = await this.pluginService.getInstance('upload'); + const avatarUrl = await file.downAndUpload( wxUserInfo.avatarUrl, uuid() + '.png' );