q-koa 13.8.56 → 13.8.58
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/core/app.js +246 -256
- package/core/file/plugins/weixin/controller.js +120 -17
- package/package.json +1 -1
package/core/app.js
CHANGED
|
@@ -370,6 +370,16 @@ class APP {
|
|
|
370
370
|
|
|
371
371
|
const version = require('q-koa/package.json').version
|
|
372
372
|
console.log(chalk.green(`version: ${version}`))
|
|
373
|
+
|
|
374
|
+
// 监听完成后,执行各 appConfig 中配置的 startHook,上下文为对应 app
|
|
375
|
+
Object.keys(this.app).forEach((name) => {
|
|
376
|
+
const startHook = _.get(this.app[name], 'appConfig.startHook')
|
|
377
|
+
if (typeof startHook === 'function') {
|
|
378
|
+
Promise.resolve(startHook(this.app[name])).catch((e) => {
|
|
379
|
+
console.log(chalk.red(`${name} startHook执行失败`), e)
|
|
380
|
+
})
|
|
381
|
+
}
|
|
382
|
+
})
|
|
373
383
|
})
|
|
374
384
|
|
|
375
385
|
// keep-alive 超时必须大于负载均衡的空闲连接超时(CLB/ALB 默认 15 秒),
|
|
@@ -662,285 +672,265 @@ class APP {
|
|
|
662
672
|
__dirname,
|
|
663
673
|
`${rootDirectory}/${APP_DIR}/${appName}/${PLUGINS_DIR}`
|
|
664
674
|
)
|
|
665
|
-
|
|
666
|
-
if (!publicExist) await fsPromise.mkdir(pluginDir)
|
|
675
|
+
await fsPromise.mkdir(pluginDir, { recursive: true })
|
|
667
676
|
const excludesModel = _.get(
|
|
668
677
|
this.app[appName],
|
|
669
678
|
'appConfig.excludesModel',
|
|
670
679
|
[]
|
|
671
680
|
)
|
|
672
|
-
|
|
673
|
-
const
|
|
674
|
-
|
|
681
|
+
// withFileTypes 直接带出类型,省掉每个文件夹一次同步 lstatSync
|
|
682
|
+
const pluginEntries = await fsPromise.readdir(pluginDir, {
|
|
683
|
+
withFileTypes: true,
|
|
684
|
+
})
|
|
685
|
+
const folders = pluginEntries
|
|
686
|
+
.filter(
|
|
687
|
+
(item) => item.isDirectory() && !excludesModel.includes(item.name)
|
|
688
|
+
)
|
|
689
|
+
.map((item) => item.name)
|
|
690
|
+
|
|
691
|
+
// 各插件目录的 readdir 互相独立,并行读取
|
|
692
|
+
const folderFileList = await Promise.all(
|
|
693
|
+
folders.map(async (folder) => [
|
|
694
|
+
folder,
|
|
695
|
+
await fsPromise.readdir(path.resolve(pluginDir, folder)),
|
|
696
|
+
])
|
|
675
697
|
)
|
|
676
698
|
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
path.resolve(pluginDir, folder)
|
|
684
|
-
)
|
|
685
|
-
for (const filename of folderResult) {
|
|
686
|
-
const extname = path.extname(filename)
|
|
687
|
-
if (extname === '.js') {
|
|
688
|
-
const n = path.basename(filename, extname)
|
|
689
|
-
if (
|
|
690
|
-
[
|
|
691
|
-
'model',
|
|
692
|
-
'controller',
|
|
693
|
-
'service',
|
|
694
|
-
'validate',
|
|
695
|
-
'config',
|
|
696
|
-
'beforeValidate',
|
|
697
|
-
'afterValidate',
|
|
698
|
-
'afterExecute',
|
|
699
|
-
].includes(n)
|
|
700
|
-
) {
|
|
701
|
-
if (n === 'model') {
|
|
702
|
-
const defaultModelPath = path.resolve(
|
|
703
|
-
__dirname,
|
|
704
|
-
`./file/${PLUGINS_DIR}/${folder}`,
|
|
705
|
-
`${filename}`
|
|
706
|
-
)
|
|
707
|
-
const defaultModelExist = fs.existsSync(defaultModelPath)
|
|
708
|
-
const currentAttributes = require(path.resolve(
|
|
709
|
-
pluginDir,
|
|
710
|
-
folder,
|
|
711
|
-
filename
|
|
712
|
-
))
|
|
713
|
-
const _attributes =
|
|
714
|
-
Object.keys(currentAttributes).length === 0 &&
|
|
715
|
-
defaultModelExist
|
|
716
|
-
? require(defaultModelPath)
|
|
717
|
-
: currentAttributes
|
|
718
|
-
|
|
719
|
-
const belongs = _.get(
|
|
720
|
-
this.app[appName].config[folder],
|
|
721
|
-
'belongs',
|
|
722
|
-
'page'
|
|
723
|
-
)
|
|
699
|
+
// O(1) 直接挂载,替代对整个 app 对象反复 defaultsDeep(O(n²))
|
|
700
|
+
const mount = (n, folder, value) => {
|
|
701
|
+
const target = this.app[appName]
|
|
702
|
+
target[n] = target[n] || {}
|
|
703
|
+
target[n][folder] = value
|
|
704
|
+
}
|
|
724
705
|
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
706
|
+
for (const [folder, folderResult] of folderFileList) {
|
|
707
|
+
for (const filename of folderResult) {
|
|
708
|
+
const extname = path.extname(filename)
|
|
709
|
+
if (extname === '.js') {
|
|
710
|
+
const n = path.basename(filename, extname)
|
|
711
|
+
if (
|
|
712
|
+
[
|
|
713
|
+
'model',
|
|
714
|
+
'controller',
|
|
715
|
+
'service',
|
|
716
|
+
'validate',
|
|
717
|
+
'config',
|
|
718
|
+
'beforeValidate',
|
|
719
|
+
'afterValidate',
|
|
720
|
+
'afterExecute',
|
|
721
|
+
].includes(n)
|
|
722
|
+
) {
|
|
723
|
+
if (n === 'model') {
|
|
724
|
+
const defaultModelPath = path.resolve(
|
|
725
|
+
__dirname,
|
|
726
|
+
`./file/${PLUGINS_DIR}/${folder}`,
|
|
727
|
+
`${filename}`
|
|
728
|
+
)
|
|
729
|
+
const defaultModelExist = fs.existsSync(defaultModelPath)
|
|
730
|
+
const currentAttributes = require(path.resolve(
|
|
731
|
+
pluginDir,
|
|
732
|
+
folder,
|
|
733
|
+
filename
|
|
734
|
+
))
|
|
735
|
+
const _attributes =
|
|
736
|
+
Object.keys(currentAttributes).length === 0 &&
|
|
737
|
+
defaultModelExist
|
|
738
|
+
? require(defaultModelPath)
|
|
739
|
+
: currentAttributes
|
|
740
|
+
|
|
741
|
+
const belongs = _.get(
|
|
742
|
+
this.app[appName].config[folder],
|
|
743
|
+
'belongs',
|
|
744
|
+
'page'
|
|
745
|
+
)
|
|
730
746
|
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
autoIncrement: true,
|
|
737
|
-
},
|
|
738
|
-
}
|
|
747
|
+
const idType = _.get(
|
|
748
|
+
this.app[appName].config[folder],
|
|
749
|
+
'idType',
|
|
750
|
+
belongs === 'setting' ? 'TINYINT' : 'MEDIUMINT'
|
|
751
|
+
)
|
|
739
752
|
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
type: Sequelize.DATE,
|
|
749
|
-
allowNull: false,
|
|
750
|
-
// defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'),
|
|
751
|
-
comment: '生成时间',
|
|
752
|
-
},
|
|
753
|
-
updated_at: {
|
|
754
|
-
type: Sequelize.DATE,
|
|
755
|
-
allowNull: false,
|
|
756
|
-
// defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'),
|
|
757
|
-
comment: '修改时间',
|
|
758
|
-
},
|
|
759
|
-
})
|
|
753
|
+
const _id = {
|
|
754
|
+
id: {
|
|
755
|
+
type: Sequelize[idType].UNSIGNED,
|
|
756
|
+
allowNull: false,
|
|
757
|
+
primaryKey: true,
|
|
758
|
+
autoIncrement: true,
|
|
759
|
+
},
|
|
760
|
+
}
|
|
760
761
|
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
762
|
+
const attributes = _.defaultsDeep(_.cloneDeep(_attributes), {
|
|
763
|
+
..._id,
|
|
764
|
+
createdid: {
|
|
765
|
+
type: Sequelize.MEDIUMINT.UNSIGNED,
|
|
766
|
+
allowNull: false,
|
|
767
|
+
defaultValue: 0,
|
|
768
|
+
},
|
|
769
|
+
created_at: {
|
|
770
|
+
type: Sequelize.DATE,
|
|
771
|
+
allowNull: false,
|
|
772
|
+
// defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'),
|
|
773
|
+
comment: '生成时间',
|
|
774
|
+
},
|
|
775
|
+
updated_at: {
|
|
776
|
+
type: Sequelize.DATE,
|
|
777
|
+
allowNull: false,
|
|
778
|
+
// defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'),
|
|
779
|
+
comment: '修改时间',
|
|
780
|
+
},
|
|
781
|
+
})
|
|
782
|
+
|
|
783
|
+
this.app[appName].attributes = {
|
|
784
|
+
...this.app[appName].attributes,
|
|
785
|
+
[folder]: _attributes,
|
|
786
|
+
}
|
|
787
|
+
const indexes = _.cloneDeep(
|
|
788
|
+
_.get(this.app[appName].config[folder], 'indexList', [])
|
|
789
|
+
)
|
|
790
|
+
let hookList = _.cloneDeep(
|
|
791
|
+
_.get(this.app[appName].config[folder], 'hookList', [])
|
|
792
|
+
)
|
|
793
|
+
if (
|
|
794
|
+
hookList.some((h) =>
|
|
795
|
+
['afterDestroy', 'beforeDestroy'].includes(h)
|
|
796
|
+
) &&
|
|
797
|
+
!hookList.includes('beforeBulkDestroy')
|
|
798
|
+
) {
|
|
799
|
+
hookList = [...hookList, 'beforeBulkDestroy']
|
|
800
|
+
}
|
|
801
|
+
let reduceHook = {}
|
|
802
|
+
for (const hook of hookList) {
|
|
803
|
+
reduceHook = {
|
|
804
|
+
...reduceHook,
|
|
805
|
+
[hook]: (target, t) => {
|
|
806
|
+
if (['beforeBulkDestroy'].includes(hook)) {
|
|
807
|
+
target.individualHooks = true
|
|
808
|
+
}
|
|
809
|
+
try {
|
|
810
|
+
this.app[appName].service &&
|
|
811
|
+
this.app[appName].service[folder] &&
|
|
812
|
+
this.app[appName].service[folder][hook] &&
|
|
813
|
+
this.app[appName].service[folder][hook]({
|
|
814
|
+
app: this.app[appName],
|
|
815
|
+
model: folder,
|
|
816
|
+
hook,
|
|
817
|
+
...(target.toJSON
|
|
818
|
+
? {
|
|
819
|
+
target: target.toJSON(),
|
|
820
|
+
}
|
|
821
|
+
: {
|
|
822
|
+
target,
|
|
823
|
+
}),
|
|
824
|
+
...t,
|
|
825
|
+
})
|
|
826
|
+
} catch (e) {
|
|
827
|
+
console.log(e)
|
|
828
|
+
}
|
|
829
|
+
|
|
830
|
+
if (['beforeBulkDestroy'].includes(hook)) {
|
|
831
|
+
return target
|
|
832
|
+
}
|
|
833
|
+
},
|
|
778
834
|
}
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
835
|
+
}
|
|
836
|
+
const instance = this.app[appName].sequelize.define(
|
|
837
|
+
folder,
|
|
838
|
+
attributes,
|
|
839
|
+
{
|
|
840
|
+
freezeTableName: true,
|
|
841
|
+
comment: folder,
|
|
842
|
+
// timestamps: !modelConfig.belongs === 'setting',
|
|
843
|
+
createdAt: 'created_at',
|
|
844
|
+
updatedAt: 'updated_at',
|
|
845
|
+
name: {
|
|
846
|
+
singular: folder,
|
|
847
|
+
plural: `${folder}s`,
|
|
848
|
+
},
|
|
849
|
+
hooks: {
|
|
782
850
|
...reduceHook,
|
|
783
|
-
|
|
784
|
-
if (['beforeBulkDestroy'].includes(hook)) {
|
|
785
|
-
target.individualHooks = true
|
|
786
|
-
}
|
|
851
|
+
beforeCreate: (res, t) => {
|
|
787
852
|
try {
|
|
788
|
-
|
|
789
|
-
this.app[appName].service
|
|
790
|
-
|
|
791
|
-
this.app[appName].service[folder][hook]({
|
|
792
|
-
app: this.app[appName],
|
|
793
|
-
model: folder,
|
|
794
|
-
hook,
|
|
795
|
-
...(target.toJSON
|
|
796
|
-
? {
|
|
797
|
-
target: target.toJSON(),
|
|
798
|
-
}
|
|
799
|
-
: {
|
|
800
|
-
target,
|
|
801
|
-
}),
|
|
802
|
-
...t,
|
|
803
|
-
})
|
|
804
|
-
} catch (e) {
|
|
805
|
-
console.log(e)
|
|
806
|
-
}
|
|
807
|
-
|
|
808
|
-
if (['beforeBulkDestroy'].includes(hook)) {
|
|
809
|
-
return target
|
|
810
|
-
}
|
|
811
|
-
},
|
|
812
|
-
}
|
|
813
|
-
}
|
|
814
|
-
const instance = this.app[appName].sequelize.define(
|
|
815
|
-
folder,
|
|
816
|
-
attributes,
|
|
817
|
-
{
|
|
818
|
-
freezeTableName: true,
|
|
819
|
-
comment: folder,
|
|
820
|
-
// timestamps: !modelConfig.belongs === 'setting',
|
|
821
|
-
createdAt: 'created_at',
|
|
822
|
-
updatedAt: 'updated_at',
|
|
823
|
-
name: {
|
|
824
|
-
singular: folder,
|
|
825
|
-
plural: `${folder}s`,
|
|
826
|
-
},
|
|
827
|
-
hooks: {
|
|
828
|
-
...reduceHook,
|
|
829
|
-
beforeCreate: (res, t) => {
|
|
830
|
-
try {
|
|
831
|
-
if (folder === 'log') {
|
|
832
|
-
if (this.is_dev && !this.app[appName].service.log) {
|
|
833
|
-
console.error('缺少log/service.js,')
|
|
834
|
-
}
|
|
835
|
-
this.app[appName].service.log &&
|
|
836
|
-
this.app[appName].service.log.push({
|
|
837
|
-
app: this.app[appName],
|
|
838
|
-
appName,
|
|
839
|
-
message: res.toJSON().message,
|
|
840
|
-
url: res.toJSON().url,
|
|
841
|
-
})
|
|
853
|
+
if (folder === 'log') {
|
|
854
|
+
if (this.is_dev && !this.app[appName].service.log) {
|
|
855
|
+
console.error('缺少log/service.js,')
|
|
842
856
|
}
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
857
|
+
this.app[appName].service.log &&
|
|
858
|
+
this.app[appName].service.log.push({
|
|
859
|
+
app: this.app[appName],
|
|
860
|
+
appName,
|
|
861
|
+
message: res.toJSON().message,
|
|
862
|
+
url: res.toJSON().url,
|
|
863
|
+
})
|
|
848
864
|
}
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
...(indexes.length > 0
|
|
852
|
-
? {
|
|
853
|
-
indexes,
|
|
865
|
+
if (res.toJSON().user_id) {
|
|
866
|
+
res.createdid = res.toJSON().user_id
|
|
854
867
|
}
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
instance.getName = function () {
|
|
859
|
-
return folder
|
|
860
|
-
}
|
|
861
|
-
this.app[appName] = _.defaultsDeep(
|
|
862
|
-
{
|
|
863
|
-
[n]: {
|
|
864
|
-
[folder]: instance,
|
|
868
|
+
} catch (e) {
|
|
869
|
+
console.log(e)
|
|
870
|
+
}
|
|
865
871
|
},
|
|
866
872
|
},
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
(item) => item.mock && typeof item.mock === 'function'
|
|
873
|
-
)
|
|
874
|
-
this.app[appName] = _.defaultsDeep(
|
|
875
|
-
{
|
|
876
|
-
mock: {
|
|
877
|
-
[folder]: () =>
|
|
878
|
-
_.zipObject(
|
|
879
|
-
Object.keys(mockObj),
|
|
880
|
-
Object.keys(mockObj).map((key) =>
|
|
881
|
-
_.result(mockObj, `${key}.mock`)
|
|
882
|
-
)
|
|
883
|
-
),
|
|
884
|
-
},
|
|
885
|
-
},
|
|
886
|
-
this.app[appName]
|
|
887
|
-
)
|
|
873
|
+
...(indexes.length > 0
|
|
874
|
+
? {
|
|
875
|
+
indexes,
|
|
876
|
+
}
|
|
877
|
+
: {}),
|
|
888
878
|
}
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
const defaultPath = path.resolve(
|
|
899
|
-
__dirname,
|
|
900
|
-
`./file/${PLUGINS_DIR}/${folder}`,
|
|
901
|
-
`${filename}`
|
|
902
|
-
)
|
|
903
|
-
const defaultExist = fs.existsSync(defaultPath)
|
|
904
|
-
const defaultN = !defaultExist
|
|
905
|
-
? Object.create(null)
|
|
906
|
-
: {
|
|
907
|
-
[n]: {
|
|
908
|
-
[folder]: defaultExist
|
|
909
|
-
? require(path.resolve(
|
|
910
|
-
__dirname,
|
|
911
|
-
`./file/${PLUGINS_DIR}/${folder}`,
|
|
912
|
-
`${filename}`
|
|
913
|
-
))
|
|
914
|
-
: null,
|
|
915
|
-
},
|
|
916
|
-
}
|
|
917
|
-
this.app[appName] = _.defaultsDeep(
|
|
918
|
-
{
|
|
919
|
-
[n]: {
|
|
920
|
-
[folder]: require(path.resolve(
|
|
921
|
-
pluginDir,
|
|
922
|
-
`${folder}`,
|
|
923
|
-
`${filename}`
|
|
924
|
-
)),
|
|
925
|
-
},
|
|
926
|
-
},
|
|
927
|
-
defaultN,
|
|
928
|
-
this.app[appName]
|
|
879
|
+
)
|
|
880
|
+
instance.getName = function () {
|
|
881
|
+
return folder
|
|
882
|
+
}
|
|
883
|
+
mount(n, folder, instance)
|
|
884
|
+
if (is_dev) {
|
|
885
|
+
const mockObj = _.pickBy(
|
|
886
|
+
_attributes,
|
|
887
|
+
(item) => item.mock && typeof item.mock === 'function'
|
|
929
888
|
)
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
`${
|
|
938
|
-
)
|
|
939
|
-
|
|
940
|
-
},
|
|
941
|
-
this.app[appName]
|
|
889
|
+
mount(
|
|
890
|
+
'mock',
|
|
891
|
+
folder,
|
|
892
|
+
() =>
|
|
893
|
+
_.zipObject(
|
|
894
|
+
Object.keys(mockObj),
|
|
895
|
+
Object.keys(mockObj).map((key) =>
|
|
896
|
+
_.result(mockObj, `${key}.mock`)
|
|
897
|
+
)
|
|
898
|
+
)
|
|
942
899
|
)
|
|
943
900
|
}
|
|
901
|
+
} else if (
|
|
902
|
+
[
|
|
903
|
+
'config',
|
|
904
|
+
'controller',
|
|
905
|
+
'validate',
|
|
906
|
+
'afterExecute',
|
|
907
|
+
'service',
|
|
908
|
+
].includes(n)
|
|
909
|
+
) {
|
|
910
|
+
const defaultPath = path.resolve(
|
|
911
|
+
__dirname,
|
|
912
|
+
`./file/${PLUGINS_DIR}/${folder}`,
|
|
913
|
+
`${filename}`
|
|
914
|
+
)
|
|
915
|
+
const userModule = require(path.resolve(
|
|
916
|
+
pluginDir,
|
|
917
|
+
`${folder}`,
|
|
918
|
+
`${filename}`
|
|
919
|
+
))
|
|
920
|
+
// 用户模块缺失的方法/配置由框架内置同名模块补齐(仅合并当前模块,不波及整个 app)
|
|
921
|
+
if (
|
|
922
|
+
fs.existsSync(defaultPath) &&
|
|
923
|
+
_.isPlainObject(userModule)
|
|
924
|
+
) {
|
|
925
|
+
_.defaultsDeep(userModule, require(defaultPath))
|
|
926
|
+
}
|
|
927
|
+
mount(n, folder, userModule)
|
|
928
|
+
} else {
|
|
929
|
+
mount(
|
|
930
|
+
n,
|
|
931
|
+
folder,
|
|
932
|
+
require(path.resolve(pluginDir, `${folder}`, `${filename}`))
|
|
933
|
+
)
|
|
944
934
|
}
|
|
945
935
|
}
|
|
946
936
|
}
|
|
@@ -452,6 +452,112 @@ exports.mp_getPhoneNew = async (ctx) => {
|
|
|
452
452
|
})
|
|
453
453
|
}
|
|
454
454
|
|
|
455
|
+
/**
|
|
456
|
+
* 小程序手机号实时认证组件(getRealtimePhoneNumber)
|
|
457
|
+
* 后端换取接口与普通手机号一致,code 来自实时认证组件回调
|
|
458
|
+
*/
|
|
459
|
+
exports.mp_getRealPhone = async (ctx) => {
|
|
460
|
+
const { app, appName } = getAppByCtx(ctx)
|
|
461
|
+
|
|
462
|
+
const { code, config = 'weixin_mp' } = ctx.request.body
|
|
463
|
+
|
|
464
|
+
const user_id = ctx.request[appName + '-user'].id
|
|
465
|
+
const appConfig = getConfig(app)
|
|
466
|
+
const { app_id, app_secrect } = await appConfig.getObject(config)
|
|
467
|
+
|
|
468
|
+
const weixinMp = new WeixinMp({
|
|
469
|
+
appid: app_id,
|
|
470
|
+
secrect: app_secrect,
|
|
471
|
+
})
|
|
472
|
+
weixinMp.init()
|
|
473
|
+
|
|
474
|
+
const { phoneNumber } = await weixinMp.getPhoneNumber(code)
|
|
475
|
+
|
|
476
|
+
if (!phoneNumber) throw new Error('微信获取手机失败,请重试')
|
|
477
|
+
|
|
478
|
+
const exist = await app.model.user.findOne({
|
|
479
|
+
where: {
|
|
480
|
+
mobile: phoneNumber,
|
|
481
|
+
},
|
|
482
|
+
include: [
|
|
483
|
+
{
|
|
484
|
+
model: app.model.mp_user,
|
|
485
|
+
},
|
|
486
|
+
],
|
|
487
|
+
})
|
|
488
|
+
|
|
489
|
+
const mobileExist =
|
|
490
|
+
exist &&
|
|
491
|
+
exist.mp_user &&
|
|
492
|
+
(!exist.mp_user.appid || exist.mp_user.appid === app_id)
|
|
493
|
+
|
|
494
|
+
if (mobileExist) {
|
|
495
|
+
return ctx.ERROR('系统已存在该手机号')
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
await app.model.user.upsert({
|
|
499
|
+
id: user_id,
|
|
500
|
+
mobile: phoneNumber,
|
|
501
|
+
})
|
|
502
|
+
|
|
503
|
+
const result = await app.model.user.findOne({
|
|
504
|
+
where: {
|
|
505
|
+
id: user_id,
|
|
506
|
+
},
|
|
507
|
+
include: [
|
|
508
|
+
{
|
|
509
|
+
model: app.model.h5_user,
|
|
510
|
+
},
|
|
511
|
+
{
|
|
512
|
+
model: app.model.mp_user,
|
|
513
|
+
},
|
|
514
|
+
{
|
|
515
|
+
model: app.model.toutiao_user,
|
|
516
|
+
},
|
|
517
|
+
...app.include.user,
|
|
518
|
+
].filter((item) => item.model),
|
|
519
|
+
})
|
|
520
|
+
|
|
521
|
+
const is_token_name = app.appConfig.is_token_name
|
|
522
|
+
|
|
523
|
+
const tokenResult = {
|
|
524
|
+
id: result.id,
|
|
525
|
+
...(is_token_name
|
|
526
|
+
? {
|
|
527
|
+
name: result.name,
|
|
528
|
+
}
|
|
529
|
+
: {}),
|
|
530
|
+
mp_user: result.mp_user
|
|
531
|
+
? {
|
|
532
|
+
openid: result.mp_user && result.mp_user.openid,
|
|
533
|
+
}
|
|
534
|
+
: null,
|
|
535
|
+
...(result.h5_user
|
|
536
|
+
? {
|
|
537
|
+
h5_user: {
|
|
538
|
+
openid: result.h5_user && result.h5_user.openid,
|
|
539
|
+
},
|
|
540
|
+
}
|
|
541
|
+
: {}),
|
|
542
|
+
...(result.toutiao_user
|
|
543
|
+
? {
|
|
544
|
+
toutiao_user: {
|
|
545
|
+
openid: result.toutiao_user && result.toutiao_user.openid,
|
|
546
|
+
},
|
|
547
|
+
}
|
|
548
|
+
: {}),
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
const token = await app.sign({
|
|
552
|
+
user: tokenResult,
|
|
553
|
+
})
|
|
554
|
+
|
|
555
|
+
return ctx.SUCCESS({
|
|
556
|
+
token,
|
|
557
|
+
user: result,
|
|
558
|
+
})
|
|
559
|
+
}
|
|
560
|
+
|
|
455
561
|
/**
|
|
456
562
|
* 微信小程序登录
|
|
457
563
|
*/
|
|
@@ -1567,7 +1673,12 @@ exports.union_notify = async (ctx) => {
|
|
|
1567
1673
|
}
|
|
1568
1674
|
|
|
1569
1675
|
// 通联回调报文字段为全小写 signtype;兼容大小写两种 + 配置 union_signType;末位回退 RSA
|
|
1570
|
-
const rawSignType = (
|
|
1676
|
+
const rawSignType = (
|
|
1677
|
+
notifyData.signtype ||
|
|
1678
|
+
notifyData.signType ||
|
|
1679
|
+
union_signType ||
|
|
1680
|
+
'RSA'
|
|
1681
|
+
).toUpperCase()
|
|
1571
1682
|
const hasSign = notifyData.sign !== undefined && notifyData.sign !== ''
|
|
1572
1683
|
const trxstatus = notifyData.trxstatus
|
|
1573
1684
|
|
|
@@ -1592,22 +1703,17 @@ exports.union_notify = async (ctx) => {
|
|
|
1592
1703
|
if (!signOk) {
|
|
1593
1704
|
app.service.log.push({
|
|
1594
1705
|
app,
|
|
1595
|
-
message: `通联回调验签失败(type=${rawSignType}): ${JSON.stringify(
|
|
1706
|
+
message: `通联回调验签失败(type=${rawSignType}): ${JSON.stringify(
|
|
1707
|
+
notifyData
|
|
1708
|
+
)}`,
|
|
1596
1709
|
})
|
|
1597
1710
|
ctx.body = 'FAIL'
|
|
1598
1711
|
return
|
|
1599
1712
|
}
|
|
1600
1713
|
}
|
|
1601
1714
|
|
|
1602
|
-
const {
|
|
1603
|
-
|
|
1604
|
-
cusorderid,
|
|
1605
|
-
acct,
|
|
1606
|
-
trxid,
|
|
1607
|
-
trxamt,
|
|
1608
|
-
srctrxid,
|
|
1609
|
-
trxreserved,
|
|
1610
|
-
} = notifyData
|
|
1715
|
+
const { trxcode, cusorderid, acct, trxid, trxamt, srctrxid, trxreserved } =
|
|
1716
|
+
notifyData
|
|
1611
1717
|
|
|
1612
1718
|
if (trxstatus === '0000') {
|
|
1613
1719
|
if (['VSP501', 'VSP681'].includes(trxcode)) {
|
|
@@ -2333,6 +2439,7 @@ exports.union_checkPay = async (ctx) => {
|
|
|
2333
2439
|
const payResult = await allinpay.checkOrder(out_trade_no)
|
|
2334
2440
|
|
|
2335
2441
|
if (payResult) {
|
|
2442
|
+
console.log(payResult)
|
|
2336
2443
|
if (payResult.trxstatus === '0000' && payResult.trxcode === 'VSP501') {
|
|
2337
2444
|
const order_price = Number(payResult.trxamt) / 100
|
|
2338
2445
|
|
|
@@ -2371,12 +2478,8 @@ exports.union_check_balance = async (ctx) => {
|
|
|
2371
2478
|
} = ctx.request.body
|
|
2372
2479
|
|
|
2373
2480
|
const appConfig = getConfig(app)
|
|
2374
|
-
const {
|
|
2375
|
-
|
|
2376
|
-
union_appid,
|
|
2377
|
-
union_privateKey,
|
|
2378
|
-
union_publicKey,
|
|
2379
|
-
} = await appConfig.getObject(pay_config)
|
|
2481
|
+
const { union_mchId, union_appid, union_privateKey, union_publicKey } =
|
|
2482
|
+
await appConfig.getObject(pay_config)
|
|
2380
2483
|
|
|
2381
2484
|
const allinpay = new AllinPay({
|
|
2382
2485
|
cusid: mch_id || union_mchId,
|