|
|
@@ -1,4 +1,4 @@
|
|
|
-import { Injectable, Req } from '@nestjs/common'
|
|
|
+import { Injectable, Req, ServiceUnavailableException } from '@nestjs/common'
|
|
|
import { InjectRepository } from '@nestjs/typeorm'
|
|
|
import { PhoneList } from './entities/phone-list.entity'
|
|
|
import { DataSource, In, Repository } from 'typeorm'
|
|
|
@@ -8,6 +8,9 @@ import { Pagination, paginate } from 'nestjs-typeorm-paginate'
|
|
|
import { Response } from 'express'
|
|
|
import { Users } from '../users/entities/users.entity'
|
|
|
import axios from 'axios'
|
|
|
+import { FileService } from '../file/file.service'
|
|
|
+import { encryptData, getFileMd5FromUrl } from '../utils/crypto'
|
|
|
+import * as yauzl from 'yauzl'
|
|
|
|
|
|
const token =
|
|
|
'vLp1Vl/yauWWx2bhaf+e9/VgXzUt5QRIZS4Rj+UuOv4eUpQWkJQC4zVnM3gXaqf5jc6j7lEY2Lagw/QCIf/4/ZTB4MKMfcvUmHRc9ISg4vXgIoC6SB2dyoeJxkOqJ5wQTftzPG2QSLFBSyhV3BHZGOguKSoXSlexmhl8pTqL/Fs='
|
|
|
@@ -20,6 +23,23 @@ const axiosInstance = axios.create({
|
|
|
}
|
|
|
})
|
|
|
|
|
|
+const appId = 'GftmoIruy8mkX4Z5'
|
|
|
+const secret = 'mayzg1xAsHoNaPuF5bXEkpqkAF6vPaRN'
|
|
|
+const publicKey = `-----BEGIN PUBLIC KEY-----
|
|
|
+MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAIzEZG2iwnFrvOLVCtI7F
|
|
|
+SsMKmVx/
|
|
|
+BtY2iVgDNGt1PfgSwFMfHhwJ28fvO+FuuA7SlmmwLEw3KqjRiuUXrnh
|
|
|
+ph0CAwEAAQ==
|
|
|
+-----END PUBLIC KEY-----`
|
|
|
+
|
|
|
+const axiosInstanceV2 = axios.create({
|
|
|
+ baseURL: 'http://8.218.211.187/screenApi/',
|
|
|
+ headers: {
|
|
|
+ uhost: '7sbn61ty.bomcnt.com',
|
|
|
+ uprotocol: 'http'
|
|
|
+ }
|
|
|
+})
|
|
|
+
|
|
|
@Injectable()
|
|
|
export class PhoneListService {
|
|
|
constructor(
|
|
|
@@ -29,7 +49,8 @@ export class PhoneListService {
|
|
|
private phoneRepository: Repository<Phone>,
|
|
|
@InjectRepository(Users)
|
|
|
private userRepository: Repository<Users>,
|
|
|
- private readonly dataSource: DataSource
|
|
|
+ private readonly dataSource: DataSource,
|
|
|
+ private readonly fileService: FileService
|
|
|
) {}
|
|
|
|
|
|
async findAllPhoneList(req: PageRequest<PhoneList>): Promise<Pagination<PhoneList>> {
|
|
|
@@ -185,4 +206,141 @@ export class PhoneListService {
|
|
|
}
|
|
|
return phones
|
|
|
}
|
|
|
+
|
|
|
+ async screenPhoneNumberV2(file: Express.Multer.File, country: string): Promise<string[]> {
|
|
|
+ const fileRes = await this.fileService.upload(file)
|
|
|
+ if (!fileRes.url) {
|
|
|
+ throw new ServiceUnavailableException(`File upload error!`)
|
|
|
+ }
|
|
|
+ const filePath = fileRes.url
|
|
|
+ const fileMd5 = await getFileMd5FromUrl(filePath)
|
|
|
+
|
|
|
+ // 获取token
|
|
|
+ const tokenRes = await axiosInstanceV2.post('getToken', {
|
|
|
+ appId,
|
|
|
+ secret
|
|
|
+ })
|
|
|
+ const tokenData = tokenRes.data
|
|
|
+ if (tokenData.code !== 0) {
|
|
|
+ throw new ServiceUnavailableException(`Get token error!`)
|
|
|
+ }
|
|
|
+ const token = tokenData.token
|
|
|
+ const config = {
|
|
|
+ headers: {
|
|
|
+ 'Content-Type': 'application/json',
|
|
|
+ appId,
|
|
|
+ token
|
|
|
+ }
|
|
|
+ }
|
|
|
+ console.log('config:', config)
|
|
|
+
|
|
|
+ const sendParam = {
|
|
|
+ filePath,
|
|
|
+ fileMd5,
|
|
|
+ operate: 'filter',
|
|
|
+ country: 'US'
|
|
|
+ }
|
|
|
+ const sendParamString = JSON.stringify(sendParam)
|
|
|
+ const sendData = encryptData(sendParamString, publicKey)
|
|
|
+ console.log('sendData:', sendData)
|
|
|
+
|
|
|
+ // 添加任务
|
|
|
+ const addRes = await axiosInstanceV2.post('api/addTask', sendData, config)
|
|
|
+ console.log('addRes:', addRes.data)
|
|
|
+ if (addRes.data.code !== 0) {
|
|
|
+ throw new ServiceUnavailableException(`ScreenPhoneNumberV2 addTask error!`)
|
|
|
+ }
|
|
|
+ const taskId = addRes.data.data.taskId
|
|
|
+
|
|
|
+ // 开启任务
|
|
|
+ const startParam = {
|
|
|
+ taskId,
|
|
|
+ operate: 'filter'
|
|
|
+ }
|
|
|
+ const startParamString = JSON.stringify(startParam)
|
|
|
+ const startData = encryptData(startParamString, publicKey)
|
|
|
+ const startRes = await axiosInstanceV2.post('api/startTask', startData, config)
|
|
|
+ console.log('startRes:', startRes.data)
|
|
|
+
|
|
|
+ // 获取进度
|
|
|
+ let check = true
|
|
|
+ let attempts = 1
|
|
|
+ while (check && attempts <= 50) {
|
|
|
+ await new Promise((resolve) => setTimeout(resolve, 5000))
|
|
|
+ console.log(`第${attempts}次查询晒号任务状态`)
|
|
|
+ const progressRes = await axiosInstanceV2.post('api/getProcess', startData, config)
|
|
|
+ console.log('progressRes:', progressRes.data)
|
|
|
+ if (progressRes.data.code === 0) {
|
|
|
+ if (progressRes.data.data.state === 'finish') {
|
|
|
+ console.log('progressRes:', progressRes.data)
|
|
|
+ check = false
|
|
|
+ break
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ throw new ServiceUnavailableException(`ScreenPhoneNumberV2 getProcess error!`)
|
|
|
+ }
|
|
|
+ attempts++
|
|
|
+ }
|
|
|
+
|
|
|
+ if (check) {
|
|
|
+ throw new ServiceUnavailableException(`ScreenPhoneNumberV2 getProcess timed out after 50 attempts!`)
|
|
|
+ }
|
|
|
+ // 获取报告
|
|
|
+ const reportParam = {
|
|
|
+ taskId,
|
|
|
+ operate: 'filter',
|
|
|
+ downloadType: 1
|
|
|
+ }
|
|
|
+ const reportParamString = JSON.stringify(reportParam)
|
|
|
+ const reportData = encryptData(reportParamString, publicKey)
|
|
|
+
|
|
|
+ const reportResponse = await axiosInstanceV2.post('api/getReport', reportData, {
|
|
|
+ headers: {
|
|
|
+ 'Content-Type': 'application/json',
|
|
|
+ appId,
|
|
|
+ token
|
|
|
+ },
|
|
|
+ responseType: 'arraybuffer'
|
|
|
+ })
|
|
|
+
|
|
|
+ let numbers = []
|
|
|
+ await new Promise((resolve, reject) => {
|
|
|
+ yauzl.fromBuffer(Buffer.from(reportResponse.data), { lazyEntries: true }, (err, zipFile) => {
|
|
|
+ if (err) return reject(err)
|
|
|
+
|
|
|
+ zipFile.readEntry()
|
|
|
+ zipFile.on('entry', (entry) => {
|
|
|
+ if (entry.fileName.endsWith('.txt')) {
|
|
|
+ zipFile.openReadStream(entry, (err, readStream) => {
|
|
|
+ if (err) return reject(err)
|
|
|
+
|
|
|
+ const chunks = []
|
|
|
+ readStream.on('data', (chunk) => chunks.push(chunk))
|
|
|
+ readStream.on('end', () => {
|
|
|
+ const content = Buffer.concat(chunks).toString('utf-8')
|
|
|
+ numbers = content
|
|
|
+ .split('\n')
|
|
|
+ .map((line) => line.trim())
|
|
|
+ .filter((line) => line)
|
|
|
+ zipFile.close()
|
|
|
+ resolve(numbers)
|
|
|
+ })
|
|
|
+ })
|
|
|
+ } else {
|
|
|
+ zipFile.readEntry()
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ zipFile.on('end', () => resolve(numbers))
|
|
|
+ zipFile.on('error', (err) => reject(err))
|
|
|
+ })
|
|
|
+ })
|
|
|
+ .then((numbers) => console.log('ScreenPhoneNumberV2 getReport success!'))
|
|
|
+ .catch((err) => {
|
|
|
+ console.error('Error:', err)
|
|
|
+ throw new ServiceUnavailableException(`ScreenPhoneNumberV2 getReport error!`)
|
|
|
+ })
|
|
|
+
|
|
|
+ return numbers
|
|
|
+ }
|
|
|
}
|