Compare commits
No commits in common. "ecc6cca6c1db85e5e2a6fb1dbd1ac025e75955d8" and "22fe77f26af73c7e5cd646e3091f7a3946033717" have entirely different histories.
ecc6cca6c1
...
22fe77f26a
37
.cursorrules
37
.cursorrules
@ -1,37 +0,0 @@
|
||||
// Uniapp Vue 3 best practices
|
||||
|
||||
const vue3CompositionApiBestPractices = [
|
||||
"Use setup() function for component logic",
|
||||
"Utilize ref and reactive for reactive state",
|
||||
"Implement computed properties with computed()",
|
||||
"Use watch and watchEffect for side effects",
|
||||
"Implement lifecycle hooks with onMounted, onUpdated, etc.",
|
||||
"Utilize provide/inject for dependency injection",
|
||||
];
|
||||
|
||||
// Folder structure
|
||||
|
||||
const folderStructure = `
|
||||
src/
|
||||
components/
|
||||
composables/
|
||||
views/
|
||||
static/
|
||||
ui/
|
||||
App.vue
|
||||
main.ts
|
||||
`;
|
||||
|
||||
// Additional instructions
|
||||
|
||||
const additionalInstructions = `
|
||||
1. Follow the uniapp vue3 version
|
||||
2. Pay attention to the compatibility of mobile APP
|
||||
3. Implement proper props and emits definitions
|
||||
4. Utilize Vue 3's Teleport component when needed
|
||||
5. Use Suspense for async components
|
||||
6. Implement proper error handling
|
||||
7. Follow Vue 3 style guide and naming conventions
|
||||
8. Use Vite for fast development and building
|
||||
`;
|
||||
|
5
.env
5
.env
@ -1,5 +0,0 @@
|
||||
# 基础环境变量配置
|
||||
VITE_APP_BASE_URL=https://www.quannengcha.com
|
||||
VITE_APP_SHARE_URL=https://www.tianyuandata.com
|
||||
# 默认环境配置
|
||||
VITE_APP_DEBUG=false
|
@ -1,5 +0,0 @@
|
||||
# 开发环境配置
|
||||
VITE_APP_BASE_URL=https://www.quannengcha.com
|
||||
|
||||
# 是否启用调试模式
|
||||
VITE_APP_DEBUG=true
|
@ -1,5 +0,0 @@
|
||||
# 生产环境配置
|
||||
VITE_APP_BASE_URL=https://www.quannengcha.com
|
||||
|
||||
# 关闭调试模式
|
||||
VITE_APP_DEBUG=false
|
1
.vscode/settings.json
vendored
1
.vscode/settings.json
vendored
@ -5,6 +5,7 @@
|
||||
|
||||
// Auto fix
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll.eslint": "explicit",
|
||||
"source.organizeImports": "never"
|
||||
},
|
||||
|
||||
|
251
dataRender/1.json
Normal file
251
dataRender/1.json
Normal file
@ -0,0 +1,251 @@
|
||||
{
|
||||
"code": "00",
|
||||
"data": {
|
||||
"als_m12_id_max_monnum": "2",
|
||||
"als_m1_cell_nbank_allnum": "1",
|
||||
"als_d15_cell_nbank_week_allnum": "0",
|
||||
"als_d15_id_nbank_allnum": "1",
|
||||
"als_m12_id_min_monnum": "0",
|
||||
"als_m3_id_max_monnum": "1",
|
||||
"als_m12_cell_min_inteday": "14",
|
||||
"als_m6_cell_nbank_max_inteday": "46",
|
||||
"als_d15_cell_nbank_selfnum": "0",
|
||||
"als_d15_cell_nbank_sloan_allnum": "1",
|
||||
"als_m3_id_nbank_orgnum": "2",
|
||||
"als_m12_cell_nbank_ca_allnum": "2",
|
||||
"als_m1_id_nbank_week_orgnum": "0",
|
||||
"als_m6_id_nbank_orgnum": "2",
|
||||
"als_m3_cell_min_monnum": "1",
|
||||
"als_m6_id_avg_monnum": "1.00",
|
||||
"als_m6_cell_nbank_orgnum": "2",
|
||||
"DataStrategy": {
|
||||
"strategy_version": "1.0",
|
||||
"product_type": "100099",
|
||||
"strategy_id": "DTA_BR0007512",
|
||||
"product_name": "预置_借贷意向验证",
|
||||
"scene": "lend"
|
||||
},
|
||||
"als_d15_id_rel_orgnum": "1",
|
||||
"als_m3_cell_nbank_cf_orgnum": "1",
|
||||
"als_m12_cell_nbank_sloan_orgnum": "2",
|
||||
"als_fst_id_nbank_inteday": "264",
|
||||
"als_m1_id_nbank_allnum": "1",
|
||||
"als_m6_cell_nbank_max_monnum": "1",
|
||||
"als_m12_cell_caon_allnum": "2",
|
||||
"als_m1_cell_nbank_cf_allnum": "1",
|
||||
"als_m6_cell_nbank_night_allnum": "1",
|
||||
"als_m12_id_nbank_night_allnum": "1",
|
||||
"als_m3_cell_caon_orgnum": "1",
|
||||
"als_m12_id_nbank_avg_monnum": "1.20",
|
||||
"als_d15_cell_nbank_orgnum": "1",
|
||||
"als_m12_id_nbank_cf_allnum": "4",
|
||||
"als_m3_cell_nbank_orgnum": "2",
|
||||
"als_m12_id_nbank_sloan_allnum": "6",
|
||||
"als_m3_cell_min_inteday": "31",
|
||||
"als_m6_cell_nbank_sloan_allnum": "4",
|
||||
"als_m3_id_nbank_cf_allnum": "2",
|
||||
"als_m6_cell_nbank_avg_monnum": "1.00",
|
||||
"als_m12_id_nbank_max_monnum": "2",
|
||||
"als_m1_cell_nbank_sloan_allnum": "1",
|
||||
"als_m6_cell_nbank_ca_allnum": "2",
|
||||
"als_m3_id_min_inteday": "31",
|
||||
"als_m3_cell_caon_allnum": "1",
|
||||
"als_m6_id_nbank_cf_orgnum": "1",
|
||||
"als_m1_cell_nbank_night_orgnum": "0",
|
||||
"als_m1_id_nbank_cf_orgnum": "1",
|
||||
"als_m3_id_nbank_cf_orgnum": "1",
|
||||
"als_d15_cell_nbank_night_orgnum": "0",
|
||||
"als_m6_cell_nbank_night_orgnum": "1",
|
||||
"als_m12_id_nbank_night_orgnum": "1",
|
||||
"als_m3_id_nbank_avg_monnum": "1.00",
|
||||
"als_m3_id_min_monnum": "1",
|
||||
"als_lst_cell_nbank_csinteday": "1",
|
||||
"als_m12_cell_nbank_max_inteday": "128",
|
||||
"als_m6_cell_max_monnum": "1",
|
||||
"als_d15_cell_nbank_night_allnum": "0",
|
||||
"als_m12_cell_min_monnum": "0",
|
||||
"als_m3_id_nbank_max_monnum": "1",
|
||||
"als_m3_cell_max_monnum": "1",
|
||||
"als_m1_id_rel_orgnum": "1",
|
||||
"als_m1_cell_nbank_cf_orgnum": "1",
|
||||
"als_m12_id_nbank_orgnum": "2",
|
||||
"als_m1_cell_nbank_night_allnum": "0",
|
||||
"als_m3_cell_nbank_allnum": "3",
|
||||
"als_m3_id_nbank_night_allnum": "1",
|
||||
"als_d15_cell_rel_orgnum": "1",
|
||||
"als_d15_cell_nbank_cf_allnum": "1",
|
||||
"als_m6_cell_nbank_selfnum": "0",
|
||||
"als_m6_cell_caon_orgnum": "1",
|
||||
"als_m12_cell_nbank_sloan_allnum": "6",
|
||||
"als_m3_id_caon_allnum": "1",
|
||||
"als_m12_cell_nbank_night_orgnum": "1",
|
||||
"als_m12_id_min_inteday": "14",
|
||||
"als_m12_id_nbank_sloan_orgnum": "2",
|
||||
"als_m6_id_nbank_ca_allnum": "2",
|
||||
"als_d15_id_nbank_orgnum": "1",
|
||||
"als_m6_cell_nbank_cf_orgnum": "1",
|
||||
"swift_number": "3034309_20241022220649_604904CBA19",
|
||||
"als_m6_cell_nbank_tot_mons": "4",
|
||||
"als_m12_id_tot_mons": "5",
|
||||
"als_m12_id_avg_monnum": "1.20",
|
||||
"als_m3_id_nbank_sloan_orgnum": "2",
|
||||
"als_m3_cell_nbank_max_inteday": "38",
|
||||
"als_m1_id_nbank_orgnum": "1",
|
||||
"als_m12_id_nbank_cf_orgnum": "1",
|
||||
"als_m1_cell_nbank_orgnum": "1",
|
||||
"als_d15_cell_nbank_allnum": "1",
|
||||
"als_m6_id_max_monnum": "1",
|
||||
"als_m12_id_max_inteday": "128",
|
||||
"als_m3_cell_nbank_selfnum": "0",
|
||||
"als_m1_cell_nbank_selfnum": "0",
|
||||
"als_m12_id_nbank_ca_allnum": "2",
|
||||
"als_m6_id_nbank_night_allnum": "1",
|
||||
"als_m3_id_nbank_max_inteday": "38",
|
||||
"als_d15_id_nbank_selfnum": "0",
|
||||
"als_m6_id_nbank_avg_monnum": "1.00",
|
||||
"als_m12_cell_nbank_max_monnum": "2",
|
||||
"als_m6_cell_min_monnum": "0",
|
||||
"als_d15_cell_rel_allnum": "1",
|
||||
"als_m6_cell_nbank_cf_allnum": "2",
|
||||
"als_m12_id_nbank_selfnum": "0",
|
||||
"als_m6_id_nbank_sloan_orgnum": "2",
|
||||
"als_m1_cell_rel_allnum": "1",
|
||||
"als_m12_id_nbank_max_inteday": "128",
|
||||
"als_m6_cell_max_inteday": "46",
|
||||
"als_m6_id_caon_allnum": "2",
|
||||
"als_m6_id_nbank_night_orgnum": "1",
|
||||
"als_lst_id_nbank_consnum": "1",
|
||||
"als_m3_cell_nbank_max_monnum": "1",
|
||||
"als_m6_id_rel_allnum": "2",
|
||||
"als_m6_id_rel_orgnum": "1",
|
||||
"als_m6_id_nbank_sloan_allnum": "4",
|
||||
"als_m1_cell_rel_orgnum": "1",
|
||||
"als_m6_cell_tot_mons": "4",
|
||||
"als_m12_cell_nbank_min_inteday": "14",
|
||||
"als_m12_id_nbank_ca_orgnum": "1",
|
||||
"als_m6_id_caon_orgnum": "1",
|
||||
"als_m3_id_max_inteday": "38",
|
||||
"als_m6_cell_min_inteday": "31",
|
||||
"als_m3_cell_nbank_sloan_orgnum": "2",
|
||||
"als_m12_id_caon_orgnum": "1",
|
||||
"als_m1_id_nbank_night_orgnum": "0",
|
||||
"als_m6_cell_nbank_week_orgnum": "2",
|
||||
"als_m3_cell_rel_orgnum": "1",
|
||||
"als_m6_cell_rel_orgnum": "1",
|
||||
"als_m3_id_nbank_sloan_allnum": "3",
|
||||
"als_m12_cell_avg_monnum": "1.20",
|
||||
"flag_datastrategy": "1",
|
||||
"als_d15_id_nbank_cf_allnum": "1",
|
||||
"als_m3_cell_max_inteday": "38",
|
||||
"als_m12_cell_nbank_cf_allnum": "4",
|
||||
"flag_applyloanstr": "1",
|
||||
"als_m6_id_nbank_ca_orgnum": "1",
|
||||
"als_m3_id_rel_orgnum": "1",
|
||||
"als_m12_id_nbank_week_orgnum": "2",
|
||||
"als_m3_cell_nbank_tot_mons": "3",
|
||||
"als_m6_id_nbank_min_inteday": "31",
|
||||
"als_m3_id_nbank_ca_orgnum": "1",
|
||||
"als_m3_id_caon_orgnum": "1",
|
||||
"als_m12_cell_nbank_week_allnum": "2",
|
||||
"als_m1_cell_nbank_week_allnum": "0",
|
||||
"als_m12_id_nbank_week_allnum": "2",
|
||||
"als_m1_id_nbank_sloan_allnum": "1",
|
||||
"als_m3_cell_nbank_min_inteday": "31",
|
||||
"als_m12_id_nbank_allnum": "6",
|
||||
"als_m1_id_nbank_cf_allnum": "1",
|
||||
"als_m3_cell_avg_monnum": "1.00",
|
||||
"als_m6_id_nbank_tot_mons": "4",
|
||||
"als_lst_cell_nbank_inteday": "7",
|
||||
"als_m3_id_nbank_ca_allnum": "1",
|
||||
"als_m6_cell_caon_allnum": "2",
|
||||
"als_m6_id_max_inteday": "46",
|
||||
"als_m12_cell_rel_orgnum": "1",
|
||||
"als_m12_id_nbank_tot_mons": "5",
|
||||
"als_m12_cell_nbank_min_monnum": "0",
|
||||
"als_m6_id_tot_mons": "4",
|
||||
"als_m3_cell_tot_mons": "3",
|
||||
"als_m3_id_nbank_night_orgnum": "1",
|
||||
"als_m12_id_nbank_min_inteday": "14",
|
||||
"als_m12_id_rel_allnum": "4",
|
||||
"als_m6_cell_nbank_week_allnum": "2",
|
||||
"als_m3_id_rel_allnum": "2",
|
||||
"als_m12_cell_nbank_selfnum": "0",
|
||||
"als_m12_id_caon_allnum": "2",
|
||||
"als_m3_id_nbank_min_inteday": "31",
|
||||
"als_m12_cell_tot_mons": "5",
|
||||
"als_m12_id_rel_orgnum": "1",
|
||||
"als_m6_cell_nbank_ca_orgnum": "1",
|
||||
"als_d15_id_nbank_cf_orgnum": "1",
|
||||
"als_m6_id_nbank_min_monnum": "0",
|
||||
"als_m6_cell_avg_monnum": "1.00",
|
||||
"als_m12_cell_nbank_night_allnum": "1",
|
||||
"als_d15_cell_nbank_cf_orgnum": "1",
|
||||
"als_m6_id_nbank_week_allnum": "2",
|
||||
"als_m3_id_nbank_tot_mons": "3",
|
||||
"als_m3_cell_nbank_night_orgnum": "1",
|
||||
"als_m6_cell_nbank_sloan_orgnum": "2",
|
||||
"als_m3_cell_nbank_ca_allnum": "1",
|
||||
"als_m1_id_nbank_selfnum": "0",
|
||||
"als_m6_id_nbank_cf_allnum": "2",
|
||||
"als_m1_id_nbank_sloan_orgnum": "1",
|
||||
"als_m6_id_nbank_week_orgnum": "2",
|
||||
"als_m1_id_rel_allnum": "1",
|
||||
"als_m3_cell_nbank_min_monnum": "1",
|
||||
"als_m12_cell_max_monnum": "2",
|
||||
"als_m12_cell_nbank_allnum": "6",
|
||||
"als_d15_id_nbank_week_orgnum": "0",
|
||||
"als_m1_id_nbank_night_allnum": "0",
|
||||
"als_m6_id_min_inteday": "31",
|
||||
"als_m12_cell_rel_allnum": "4",
|
||||
"als_m6_id_nbank_max_inteday": "46",
|
||||
"als_m12_cell_caon_orgnum": "1",
|
||||
"als_d15_cell_nbank_week_orgnum": "0",
|
||||
"als_d15_cell_nbank_sloan_orgnum": "1",
|
||||
"als_m1_cell_nbank_sloan_orgnum": "1",
|
||||
"als_m3_id_nbank_selfnum": "0",
|
||||
"als_m1_cell_nbank_week_orgnum": "0",
|
||||
"als_d15_id_nbank_sloan_allnum": "1",
|
||||
"als_m3_cell_rel_allnum": "2",
|
||||
"als_d15_id_nbank_sloan_orgnum": "1",
|
||||
"als_m6_id_nbank_max_monnum": "1",
|
||||
"als_m6_cell_nbank_allnum": "4",
|
||||
"als_m3_cell_nbank_cf_allnum": "2",
|
||||
"als_m1_id_nbank_week_allnum": "0",
|
||||
"als_d15_id_rel_allnum": "1",
|
||||
"als_m12_cell_nbank_tot_mons": "5",
|
||||
"als_m3_id_tot_mons": "3",
|
||||
"als_m6_cell_rel_allnum": "2",
|
||||
"als_m12_cell_nbank_week_orgnum": "2",
|
||||
"als_lst_id_nbank_inteday": "7",
|
||||
"als_m6_id_nbank_selfnum": "0",
|
||||
"als_m6_id_min_monnum": "0",
|
||||
"code": "00",
|
||||
"als_m12_cell_nbank_ca_orgnum": "1",
|
||||
"als_m3_id_nbank_week_orgnum": "1",
|
||||
"als_d15_id_nbank_week_allnum": "0",
|
||||
"als_m3_id_nbank_min_monnum": "1",
|
||||
"als_m3_id_avg_monnum": "1.00",
|
||||
"als_d15_id_nbank_night_orgnum": "0",
|
||||
"als_m3_cell_nbank_night_allnum": "1",
|
||||
"als_fst_cell_nbank_inteday": "264",
|
||||
"als_m3_id_nbank_week_allnum": "1",
|
||||
"als_d15_id_nbank_night_allnum": "0",
|
||||
"als_m12_cell_nbank_orgnum": "2",
|
||||
"als_m3_cell_nbank_ca_orgnum": "1",
|
||||
"als_m3_cell_nbank_sloan_allnum": "3",
|
||||
"als_m12_cell_max_inteday": "128",
|
||||
"als_m6_cell_nbank_min_inteday": "31",
|
||||
"als_m12_id_nbank_min_monnum": "0",
|
||||
"als_lst_id_nbank_csinteday": "1",
|
||||
"als_lst_cell_nbank_consnum": "1",
|
||||
"als_m3_cell_nbank_week_orgnum": "1",
|
||||
"als_m12_cell_nbank_avg_monnum": "1.20",
|
||||
"als_m3_id_nbank_allnum": "3",
|
||||
"als_m6_id_nbank_allnum": "4",
|
||||
"als_m12_cell_nbank_cf_orgnum": "1",
|
||||
"als_m3_cell_nbank_avg_monnum": "1.00",
|
||||
"als_m6_cell_nbank_min_monnum": "0",
|
||||
"als_m3_cell_nbank_week_allnum": "1"
|
||||
},
|
||||
"flag_applyloanstr": "1"
|
||||
}
|
2093
dataRender/jdyx.txt
Normal file
2093
dataRender/jdyx.txt
Normal file
File diff suppressed because it is too large
Load Diff
55
dataRender/jdyxRender.js
Normal file
55
dataRender/jdyxRender.js
Normal file
@ -0,0 +1,55 @@
|
||||
const fs = require('node:fs')
|
||||
const path = require('node:path')
|
||||
|
||||
// 读取文件路径
|
||||
const filePath = path.join(__dirname, 'jdyx.txt')
|
||||
|
||||
// 输出文件路径
|
||||
const outputFilePath = path.join(__dirname, 'output.json')
|
||||
|
||||
// 读取文件内容
|
||||
fs.readFile(filePath, 'utf8', (err, data) => {
|
||||
if (err) {
|
||||
console.error('读取文件失败:', err)
|
||||
return
|
||||
}
|
||||
|
||||
const records = []
|
||||
let currentRecord = ''
|
||||
let capturing = false // 是否正在捕获一条记录
|
||||
|
||||
// 按字符处理数据
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
const char = data[i]
|
||||
|
||||
// 检查是否找到 `als`
|
||||
if (!capturing && data.slice(i, i + 3) === 'als') {
|
||||
capturing = true // 开始捕获
|
||||
currentRecord = 'als' // 初始化记录
|
||||
i += 2 // 跳过已匹配的 "als"
|
||||
continue
|
||||
}
|
||||
|
||||
// 捕获状态下,遇到空格时结束记录
|
||||
if (capturing) {
|
||||
if (char === ' ') {
|
||||
records.push(currentRecord) // 保存当前记录
|
||||
capturing = false // 停止捕获
|
||||
currentRecord = '' // 重置记录
|
||||
}
|
||||
else {
|
||||
currentRecord += char // 继续捕获字符
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 将结果写入到JSON文件中
|
||||
fs.writeFile(outputFilePath, JSON.stringify(records, null, 2), (err) => {
|
||||
if (err) {
|
||||
console.error('写入文件失败:', err)
|
||||
}
|
||||
else {
|
||||
console.log(`记录已保存到文件: ${outputFilePath}`)
|
||||
}
|
||||
})
|
||||
})
|
41
dataRender/jdyxRender2.js
Normal file
41
dataRender/jdyxRender2.js
Normal file
@ -0,0 +1,41 @@
|
||||
const fs = require('node:fs')
|
||||
const path = require('node:path')
|
||||
|
||||
// 读取文件路径
|
||||
const inputFilePath = path.join(__dirname, 'output.json')
|
||||
|
||||
// 输出文件路径
|
||||
const outputFilePath = path.join(__dirname, 'word_list.json')
|
||||
|
||||
// 读取JSON文件
|
||||
fs.readFile(inputFilePath, 'utf8', (err, data) => {
|
||||
if (err) {
|
||||
console.error('读取文件失败:', err)
|
||||
return
|
||||
}
|
||||
|
||||
// 解析JSON内容
|
||||
const records = JSON.parse(data)
|
||||
|
||||
// 用于存储所有分割后的单词
|
||||
const wordSet = new Set()
|
||||
|
||||
// 遍历每个元素,将其按下划线分割
|
||||
records.forEach((record) => {
|
||||
const words = record.split('_')
|
||||
words.forEach(word => wordSet.add(word)) // 去重
|
||||
})
|
||||
|
||||
// 将Set转换为数组
|
||||
const uniqueWords = Array.from(wordSet)
|
||||
|
||||
// 将结果写入到新的JSON文件
|
||||
fs.writeFile(outputFilePath, JSON.stringify(uniqueWords, null, 2), (err) => {
|
||||
if (err) {
|
||||
console.error('写入文件失败:', err)
|
||||
}
|
||||
else {
|
||||
console.log(`单词列表已保存到文件: ${outputFilePath}`)
|
||||
}
|
||||
})
|
||||
})
|
822
dataRender/output.json
Normal file
822
dataRender/output.json
Normal file
@ -0,0 +1,822 @@
|
||||
[
|
||||
"als_d7_id_pdl_allnum",
|
||||
"als_d7_id_pdl_orgnum",
|
||||
"als_d7_id_caon_allnum",
|
||||
"als_d7_id_caon_orgnum",
|
||||
"als_d7_id_rel_allnum",
|
||||
"als_d7_id_rel_orgnum",
|
||||
"als_d7_id_caoff_allnum",
|
||||
"als_d7_id_caoff_orgnum",
|
||||
"als_d7_id_cooff_allnum",
|
||||
"als_d7_id_cooff_orgnum",
|
||||
"als_d7_id_af_allnum",
|
||||
"als_d7_id_af_orgnum",
|
||||
"als_d7_id_coon_allnum",
|
||||
"als_d7_id_coon_orgnum",
|
||||
"als_d7_id_oth_allnum",
|
||||
"als_d7_id_oth_orgnum",
|
||||
"als_d7_id_bank_selfnum",
|
||||
"als_d7_id_bank_allnum",
|
||||
"als_d7_id_bank_tra_allnum",
|
||||
"als_d7_id_bank_ret_allnum",
|
||||
"als_d7_id_bank_orgnum",
|
||||
"als_d7_id_bank_tra_orgnum",
|
||||
"als_d7_id_bank_ret_orgnum",
|
||||
"als_d7_id_bank_week_allnum",
|
||||
"als_d7_id_bank_week_orgnum",
|
||||
"als_d7_id_bank_night_allnum",
|
||||
"als_d7_id_bank_night_orgnum",
|
||||
"als_d7_id_nbank_selfnum",
|
||||
"als_d7_id_nbank_allnum",
|
||||
"als_d7_id_nbank_p2p_allnum",
|
||||
"als_d7_id_nbank_mc_allnum",
|
||||
"als_d7_id_nbank_ca_allnum",
|
||||
"als_d7_id_nbank_cf_allnum",
|
||||
"als_d7_id_nbank_com_allnum",
|
||||
"als_d7_id_nbank_oth_allnum",
|
||||
"als_d7_id_nbank_nsloan_allnum",
|
||||
"als_d7_id_nbank_autofin_allnum",
|
||||
"als_d7_id_nbank_sloan_allnum",
|
||||
"als_d7_id_nbank_cons_allnum",
|
||||
"als_d7_id_nbank_finlea_allnum",
|
||||
"als_d7_id_nbank_else_allnum",
|
||||
"als_d7_id_nbank_orgnum",
|
||||
"als_d7_id_nbank_p2p_orgnum",
|
||||
"als_d7_id_nbank_mc_orgnum",
|
||||
"als_d7_id_nbank_ca_orgnum",
|
||||
"als_d7_id_nbank_cf_orgnum",
|
||||
"als_d7_id_nbank_com_orgnum",
|
||||
"als_d7_id_nbank_oth_orgnum",
|
||||
"als_d7_id_nbank_nsloan_orgnum",
|
||||
"als_d7_id_nbank_autofin_orgnum",
|
||||
"als_d7_id_nbank_sloan_orgnum",
|
||||
"als_d7_id_nbank_cons_orgnum",
|
||||
"als_d7_id_nbank_finlea_orgnum",
|
||||
"als_d7_id_nbank_else_orgnum",
|
||||
"als_d7_id_nbank_week_allnum",
|
||||
"als_d7_id_nbank_week_orgnum",
|
||||
"als_d7_id_nbank_night_allnum",
|
||||
"als_d7_id_nbank_night_orgnum",
|
||||
"als_d7_cell_pdl_allnum",
|
||||
"als_d7_cell_pdl_orgnum",
|
||||
"als_d7_cell_caon_allnum",
|
||||
"als_d7_cell_caon_orgnum",
|
||||
"als_d7_cell_rel_allnum",
|
||||
"als_d7_cell_rel_orgnum",
|
||||
"als_d7_cell_caoff_allnum",
|
||||
"als_d7_cell_caoff_orgnum",
|
||||
"als_d7_cell_cooff_allnum",
|
||||
"als_d7_cell_cooff_orgnum",
|
||||
"als_d7_cell_af_allnum",
|
||||
"als_d7_cell_af_orgnum",
|
||||
"als_d7_cell_coon_allnum",
|
||||
"als_d7_cell_coon_orgnum",
|
||||
"als_d7_cell_oth_allnum",
|
||||
"als_d7_cell_oth_orgnum",
|
||||
"als_d7_cell_bank_selfnum",
|
||||
"als_d7_cell_bank_allnum",
|
||||
"als_d7_cell_bank_tra_allnum",
|
||||
"als_d7_cell_bank_ret_allnum",
|
||||
"als_d7_cell_bank_orgnum",
|
||||
"als_d7_cell_bank_tra_orgnum",
|
||||
"als_d7_cell_bank_ret_orgnum",
|
||||
"als_d7_cell_bank_week_allnum",
|
||||
"als_d7_cell_bank_week_orgnum",
|
||||
"als_d7_cell_bank_night_allnum",
|
||||
"als_d7_cell_bank_night_orgnum",
|
||||
"als_d7_cell_nbank_selfnum",
|
||||
"als_d7_cell_nbank_allnum",
|
||||
"als_d7_cell_nbank_p2p_allnum",
|
||||
"als_d7_cell_nbank_mc_allnum",
|
||||
"als_d7_cell_nbank_ca_allnum",
|
||||
"als_d7_cell_nbank_cf_allnum",
|
||||
"als_d7_cell_nbank_com_allnum",
|
||||
"als_d7_cell_nbank_oth_allnum",
|
||||
"als_d7_cell_nbank_nsloan_allnum",
|
||||
"als_d7_cell_nbank_autofin_allnum",
|
||||
"als_d7_cell_nbank_sloan_allnum",
|
||||
"als_d7_cell_nbank_cons_allnum",
|
||||
"als_d7_cell_nbank_finlea_allnum",
|
||||
"als_d7_cell_nbank_else_allnum",
|
||||
"als_d7_cell_nbank_orgnum",
|
||||
"als_d7_cell_nbank_p2p_orgnum",
|
||||
"als_d7_cell_nbank_mc_orgnum",
|
||||
"als_d7_cell_nbank_ca_orgnum",
|
||||
"als_d7_cell_nbank_cf_orgnum",
|
||||
"als_d7_cell_nbank_com_orgnum",
|
||||
"als_d7_cell_nbank_oth_orgnum",
|
||||
"als_d7_cell_nbank_nsloan_orgnum",
|
||||
"als_d7_cell_nbank_autofin_orgnum",
|
||||
"als_d7_cell_nbank_sloan_orgnum",
|
||||
"als_d7_cell_nbank_cons_orgnum",
|
||||
"als_d7_cell_nbank_finlea_orgnum",
|
||||
"als_d7_cell_nbank_else_orgnum",
|
||||
"als_d7_cell_nbank_week_allnum",
|
||||
"als_d7_cell_nbank_week_orgnum",
|
||||
"als_d7_cell_nbank_night_allnum",
|
||||
"als_d7_cell_nbank_night_orgnum",
|
||||
"als_d15_id_pdl_allnum",
|
||||
"als_d15_id_pdl_orgnum",
|
||||
"als_d15_id_caon_allnum",
|
||||
"als_d15_id_caon_orgnum",
|
||||
"als_d15_id_rel_allnum",
|
||||
"als_d15_id_rel_orgnum",
|
||||
"als_d15_id_caoff_allnum",
|
||||
"als_d15_id_caoff_orgnum",
|
||||
"als_d15_id_cooff_allnum",
|
||||
"als_d15_id_cooff_orgnum",
|
||||
"als_d15_id_af_allnum",
|
||||
"als_d15_id_af_orgnum",
|
||||
"als_d15_id_coon_allnum",
|
||||
"als_d15_id_coon_orgnum",
|
||||
"als_d15_id_oth_allnum",
|
||||
"als_d15_id_oth_orgnum",
|
||||
"als_d15_id_bank_selfnum",
|
||||
"als_d15_id_bank_allnum",
|
||||
"als_d15_id_bank_tra_allnum",
|
||||
"als_d15_id_bank_ret_allnum",
|
||||
"als_d15_id_bank_orgnum",
|
||||
"als_d15_id_bank_tra_orgnum",
|
||||
"als_d15_id_bank_ret_orgnum",
|
||||
"als_d15_id_bank_week_allnum",
|
||||
"als_d15_id_bank_week_orgnum",
|
||||
"als_d15_id_bank_night_allnum",
|
||||
"als_d15_id_bank_night_orgnum",
|
||||
"als_d15_id_nbank_selfnum",
|
||||
"als_d15_id_nbank_allnum",
|
||||
"als_d15_id_nbank_p2p_allnum",
|
||||
"als_d15_id_nbank_mc_allnum",
|
||||
"als_d15_id_nbank_ca_allnum",
|
||||
"als_d15_id_nbank_cf_allnum",
|
||||
"als_d15_id_nbank_com_allnum",
|
||||
"als_d15_id_nbank_oth_allnum",
|
||||
"als_d15_id_nbank_nsloan_allnum",
|
||||
"als_d15_id_nbank_autofin_allnum",
|
||||
"als_d15_id_nbank_sloan_allnum",
|
||||
"als_d15_id_nbank_cons_allnum",
|
||||
"als_d15_id_nbank_finlea_allnum",
|
||||
"als_d15_id_nbank_else_allnum",
|
||||
"als_d15_id_nbank_orgnum",
|
||||
"als_d15_id_nbank_p2p_orgnum",
|
||||
"als_d15_id_nbank_mc_orgnum",
|
||||
"als_d15_id_nbank_ca_orgnum",
|
||||
"als_d15_id_nbank_cf_orgnum",
|
||||
"als_d15_id_nbank_com_orgnum",
|
||||
"als_d15_id_nbank_oth_orgnum",
|
||||
"als_d15_id_nbank_nsloan_orgnum",
|
||||
"als_d15_id_nbank_autofin_orgnum",
|
||||
"als_d15_id_nbank_sloan_orgnum",
|
||||
"als_d15_id_nbank_cons_orgnum",
|
||||
"als_d15_id_nbank_finlea_orgnum",
|
||||
"als_d15_id_nbank_else_orgnum",
|
||||
"als_d15_id_nbank_week_allnum",
|
||||
"als_d15_id_nbank_week_orgnum",
|
||||
"als_d15_id_nbank_night_allnum",
|
||||
"als_d15_id_nbank_night_orgnum",
|
||||
"als_d15_cell_pdl_allnum",
|
||||
"als_d15_cell_pdl_orgnum",
|
||||
"als_d15_cell_caon_allnum",
|
||||
"als_d15_cell_caon_orgnum",
|
||||
"als_d15_cell_rel_allnum",
|
||||
"als_d15_cell_rel_orgnum",
|
||||
"als_d15_cell_caoff_allnum",
|
||||
"als_d15_cell_caoff_orgnum",
|
||||
"als_d15_cell_cooff_allnum",
|
||||
"als_d15_cell_cooff_orgnum",
|
||||
"als_d15_cell_af_allnum",
|
||||
"als_d15_cell_af_orgnum",
|
||||
"als_d15_cell_coon_allnum",
|
||||
"als_d15_cell_coon_orgnum",
|
||||
"als_d15_cell_oth_allnum",
|
||||
"als_d15_cell_oth_orgnum",
|
||||
"als_d15_cell_bank_selfnum",
|
||||
"als_d15_cell_bank_allnum",
|
||||
"als_d15_cell_bank_tra_allnum",
|
||||
"als_d15_cell_bank_ret_allnum",
|
||||
"als_d15_cell_bank_orgnum",
|
||||
"als_d15_cell_bank_tra_orgnum",
|
||||
"als_d15_cell_bank_ret_orgnum",
|
||||
"als_d15_cell_bank_week_allnum",
|
||||
"als_d15_cell_bank_week_orgnum",
|
||||
"als_d15_cell_bank_night_allnum",
|
||||
"als_d15_cell_bank_night_orgnum",
|
||||
"als_d15_cell_nbank_selfnum",
|
||||
"als_d15_cell_nbank_allnum",
|
||||
"als_d15_cell_nbank_p2p_allnum",
|
||||
"als_d15_cell_nbank_mc_allnum",
|
||||
"als_d15_cell_nbank_ca_allnum",
|
||||
"als_d15_cell_nbank_cf_allnum",
|
||||
"als_d15_cell_nbank_com_allnum",
|
||||
"als_d15_cell_nbank_oth_allnum",
|
||||
"als_d15_cell_nbank_nsloan_allnum",
|
||||
"als_d15_cell_nbank_autofin_allnum",
|
||||
"als_d15_cell_nbank_sloan_allnum",
|
||||
"als_d15_cell_nbank_cons_allnum",
|
||||
"als_d15_cell_nbank_finlea_allnum",
|
||||
"als_d15_cell_nbank_else_allnum",
|
||||
"als_d15_cell_nbank_orgnum",
|
||||
"als_d15_cell_nbank_p2p_orgnum",
|
||||
"als_d15_cell_nbank_mc_orgnum",
|
||||
"als_d15_cell_nbank_ca_orgnum",
|
||||
"als_d15_cell_nbank_cf_orgnum",
|
||||
"als_d15_cell_nbank_com_orgnum",
|
||||
"als_d15_cell_nbank_oth_orgnum",
|
||||
"als_d15_cell_nbank_nsloan_orgnum",
|
||||
"als_d15_cell_nbank_autofin_orgnum",
|
||||
"als_d15_cell_nbank_sloan_orgnum",
|
||||
"als_d15_cell_nbank_cons_orgnum",
|
||||
"als_d15_cell_nbank_finlea_orgnum",
|
||||
"als_d15_cell_nbank_else_orgnum",
|
||||
"als_d15_cell_nbank_week_allnum",
|
||||
"als_d15_cell_nbank_week_orgnum",
|
||||
"als_d15_cell_nbank_night_allnum",
|
||||
"als_d15_cell_nbank_night_orgnum",
|
||||
"als_m1_id_pdl_allnum",
|
||||
"als_m1_id_pdl_orgnum",
|
||||
"als_m1_id_caon_allnum",
|
||||
"als_m1_id_caon_orgnum",
|
||||
"als_m1_id_rel_allnum",
|
||||
"als_m1_id_rel_orgnum",
|
||||
"als_m1_id_caoff_allnum",
|
||||
"als_m1_id_caoff_orgnum",
|
||||
"als_m1_id_cooff_allnum",
|
||||
"als_m1_id_cooff_orgnum",
|
||||
"als_m1_id_af_allnum",
|
||||
"als_m1_id_af_orgnum",
|
||||
"als_m1_id_coon_allnum",
|
||||
"als_m1_id_coon_orgnum",
|
||||
"als_m1_id_oth_allnum",
|
||||
"als_m1_id_oth_orgnum",
|
||||
"als_m1_id_bank_selfnum",
|
||||
"als_m1_id_bank_allnum",
|
||||
"als_m1_id_bank_tra_allnum",
|
||||
"als_m1_id_bank_ret_allnum",
|
||||
"als_m1_id_bank_orgnum",
|
||||
"als_m1_id_bank_tra_orgnum",
|
||||
"als_m1_id_bank_ret_orgnum",
|
||||
"als_m1_id_bank_week_allnum",
|
||||
"als_m1_id_bank_week_orgnum",
|
||||
"als_m1_id_bank_night_allnum",
|
||||
"als_m1_id_bank_night_orgnum",
|
||||
"als_m1_id_nbank_selfnum",
|
||||
"als_m1_id_nbank_allnum",
|
||||
"als_m1_id_nbank_p2p_allnum",
|
||||
"als_m1_id_nbank_mc_allnum",
|
||||
"als_m1_id_nbank_ca_allnum",
|
||||
"als_m1_id_nbank_cf_allnum",
|
||||
"als_m1_id_nbank_com_allnum",
|
||||
"als_m1_id_nbank_oth_allnum",
|
||||
"als_m1_id_nbank_nsloan_allnum",
|
||||
"als_m1_id_nbank_autofin_allnum",
|
||||
"als_m1_id_nbank_sloan_allnum",
|
||||
"als_m1_id_nbank_cons_allnum",
|
||||
"als_m1_id_nbank_finlea_allnum",
|
||||
"als_m1_id_nbank_else_allnum",
|
||||
"als_m1_id_nbank_orgnum",
|
||||
"als_m1_id_nbank_p2p_orgnum",
|
||||
"als_m1_id_nbank_mc_orgnum",
|
||||
"als_m1_id_nbank_ca_orgnum",
|
||||
"als_m1_id_nbank_cf_orgnum",
|
||||
"als_m1_id_nbank_com_orgnum",
|
||||
"als_m1_id_nbank_oth_orgnum",
|
||||
"als_m1_id_nbank_nsloan_orgnum",
|
||||
"als_m1_id_nbank_autofin_orgnum",
|
||||
"als_m1_id_nbank_sloan_orgnum",
|
||||
"als_m1_id_nbank_cons_orgnum",
|
||||
"als_m1_id_nbank_finlea_orgnum",
|
||||
"als_m1_id_nbank_else_orgnum",
|
||||
"als_m1_id_nbank_week_allnum",
|
||||
"als_m1_id_nbank_week_orgnum",
|
||||
"als_m1_id_nbank_night_allnum",
|
||||
"als_m1_id_nbank_night_orgnum",
|
||||
"als_m1_cell_pdl_allnum",
|
||||
"als_m1_cell_pdl_orgnum",
|
||||
"als_m1_cell_caon_allnum",
|
||||
"als_m1_cell_caon_orgnum",
|
||||
"als_m1_cell_rel_allnum",
|
||||
"als_m1_cell_rel_orgnum",
|
||||
"als_m1_cell_caoff_allnum",
|
||||
"als_m1_cell_caoff_orgnum",
|
||||
"als_m1_cell_cooff_allnum",
|
||||
"als_m1_cell_cooff_orgnum",
|
||||
"als_m1_cell_af_allnum",
|
||||
"als_m1_cell_af_orgnum",
|
||||
"als_m1_cell_coon_allnum",
|
||||
"als_m1_cell_coon_orgnum",
|
||||
"als_m1_cell_oth_allnum",
|
||||
"als_m1_cell_oth_orgnum",
|
||||
"als_m1_cell_bank_selfnum",
|
||||
"als_m1_cell_bank_allnum",
|
||||
"als_m1_cell_bank_tra_allnum",
|
||||
"als_m1_cell_bank_ret_allnum",
|
||||
"als_m1_cell_bank_orgnum",
|
||||
"als_m1_cell_bank_tra_orgnum",
|
||||
"als_m1_cell_bank_ret_orgnum",
|
||||
"als_m1_cell_bank_week_allnum",
|
||||
"als_m1_cell_bank_week_orgnum",
|
||||
"als_m1_cell_bank_night_allnum",
|
||||
"als_m1_cell_bank_night_orgnum",
|
||||
"als_m1_cell_nbank_selfnum",
|
||||
"als_m1_cell_nbank_allnum",
|
||||
"als_m1_cell_nbank_p2p_allnum",
|
||||
"als_m1_cell_nbank_mc_allnum",
|
||||
"als_m1_cell_nbank_ca_allnum",
|
||||
"als_m1_cell_nbank_cf_allnum",
|
||||
"als_m1_cell_nbank_com_allnum",
|
||||
"als_m1_cell_nbank_oth_allnum",
|
||||
"als_m1_cell_nbank_nsloan_allnum",
|
||||
"als_m1_cell_nbank_autofin_allnum",
|
||||
"als_m1_cell_nbank_sloan_allnum",
|
||||
"als_m1_cell_nbank_cons_allnum",
|
||||
"als_m1_cell_nbank_finlea_allnum",
|
||||
"als_m1_cell_nbank_else_allnum",
|
||||
"als_m1_cell_nbank_orgnum",
|
||||
"als_m1_cell_nbank_p2p_orgnum",
|
||||
"als_m1_cell_nbank_mc_orgnum",
|
||||
"als_m1_cell_nbank_ca_orgnum",
|
||||
"als_m1_cell_nbank_cf_orgnum",
|
||||
"als_m1_cell_nbank_com_orgnum",
|
||||
"als_m1_cell_nbank_oth_orgnum",
|
||||
"als_m1_cell_nbank_nsloan_orgnum",
|
||||
"als_m1_cell_nbank_autofin_orgnum",
|
||||
"als_m1_cell_nbank_sloan_orgnum",
|
||||
"als_m1_cell_nbank_cons_orgnum",
|
||||
"als_m1_cell_nbank_finlea_orgnum",
|
||||
"als_m1_cell_nbank_else_orgnum",
|
||||
"als_m1_cell_nbank_week_allnum",
|
||||
"als_m1_cell_nbank_week_orgnum",
|
||||
"als_m1_cell_nbank_night_allnum",
|
||||
"als_m1_cell_nbank_night_orgnum",
|
||||
"als_m3_id_max_inteday",
|
||||
"als_m3_id_min_inteday",
|
||||
"als_m3_id_tot_mons",
|
||||
"als_m3_id_avg_monnum",
|
||||
"als_m3_id_max_monnum",
|
||||
"als_m3_id_min_monnum",
|
||||
"als_m3_id_pdl_allnum",
|
||||
"als_m3_id_pdl_orgnum",
|
||||
"als_m3_id_caon_allnum",
|
||||
"als_m3_id_caon_orgnum",
|
||||
"als_m3_id_rel_allnum",
|
||||
"als_m3_id_rel_orgnum",
|
||||
"als_m3_id_caoff_allnum",
|
||||
"als_m3_id_caoff_orgnum",
|
||||
"als_m3_id_cooff_allnum",
|
||||
"als_m3_id_cooff_orgnum",
|
||||
"als_m3_id_af_allnum",
|
||||
"als_m3_id_af_orgnum",
|
||||
"als_m3_id_coon_allnum",
|
||||
"als_m3_id_coon_orgnum",
|
||||
"als_m3_id_oth_allnum",
|
||||
"als_m3_id_oth_orgnum",
|
||||
"als_m3_id_bank_selfnum",
|
||||
"als_m3_id_bank_allnum",
|
||||
"als_m3_id_bank_tra_allnum",
|
||||
"als_m3_id_bank_ret_allnum",
|
||||
"als_m3_id_bank_orgnum",
|
||||
"als_m3_id_bank_tra_orgnum",
|
||||
"als_m3_id_bank_ret_orgnum",
|
||||
"als_m3_id_bank_tot_mons",
|
||||
"als_m3_id_bank_avg_monnum",
|
||||
"als_m3_id_bank_max_monnum",
|
||||
"als_m3_id_bank_min_monnum",
|
||||
"als_m3_id_bank_max_inteday",
|
||||
"als_m3_id_bank_min_inteday",
|
||||
"als_m3_id_bank_week_allnum",
|
||||
"als_m3_id_bank_week_orgnum",
|
||||
"als_m3_id_bank_night_allnum",
|
||||
"als_m3_id_bank_night_orgnum",
|
||||
"als_m3_id_nbank_selfnum",
|
||||
"als_m3_id_nbank_allnum",
|
||||
"als_m3_id_nbank_p2p_allnum",
|
||||
"als_m3_id_nbank_mc_allnum",
|
||||
"als_m3_id_nbank_ca_allnum",
|
||||
"als_m3_id_nbank_cf_allnum",
|
||||
"als_m3_id_nbank_com_allnum",
|
||||
"als_m3_id_nbank_oth_allnum",
|
||||
"als_m3_id_nbank_nsloan_allnum",
|
||||
"als_m3_id_nbank_autofin_allnum",
|
||||
"als_m3_id_nbank_sloan_allnum",
|
||||
"als_m3_id_nbank_cons_allnum",
|
||||
"als_m3_id_nbank_finlea_allnum",
|
||||
"als_m3_id_nbank_else_allnum",
|
||||
"als_m3_id_nbank_orgnum",
|
||||
"als_m3_id_nbank_p2p_orgnum",
|
||||
"als_m3_id_nbank_mc_orgnum",
|
||||
"als_m3_id_nbank_ca_orgnum",
|
||||
"als_m3_id_nbank_cf_orgnum",
|
||||
"als_m3_id_nbank_com_orgnum",
|
||||
"als_m3_id_nbank_oth_orgnum",
|
||||
"als_m3_id_nbank_nsloan_orgnum",
|
||||
"als_m3_id_nbank_autofin_orgnum",
|
||||
"als_m3_id_nbank_sloan_orgnum",
|
||||
"als_m3_id_nbank_cons_orgnum",
|
||||
"als_m3_id_nbank_finlea_orgnum",
|
||||
"als_m3_id_nbank_else_orgnum",
|
||||
"als_m3_id_nbank_tot_mons",
|
||||
"als_m3_id_nbank_avg_monnum",
|
||||
"als_m3_id_nbank_max_monnum",
|
||||
"als_m3_id_nbank_min_monnum",
|
||||
"als_m3_id_nbank_max_inteday",
|
||||
"als_m3_id_nbank_min_inteday",
|
||||
"als_m3_id_nbank_week_allnum",
|
||||
"als_m3_id_nbank_week_orgnum",
|
||||
"als_m3_id_nbank_night_allnum",
|
||||
"als_m3_id_nbank_night_orgnum",
|
||||
"als_m3_cell_max_inteday",
|
||||
"als_m3_cell_min_inteday",
|
||||
"als_m3_cell_tot_mons",
|
||||
"als_m3_cell_avg_monnum",
|
||||
"als_m3_cell_max_monnum",
|
||||
"als_m3_cell_min_monnum",
|
||||
"als_m3_cell_pdl_allnum",
|
||||
"als_m3_cell_pdl_orgnum",
|
||||
"als_m3_cell_caon_allnum",
|
||||
"als_m3_cell_caon_orgnum",
|
||||
"als_m3_cell_rel_allnum",
|
||||
"als_m3_cell_rel_orgnum",
|
||||
"als_m3_cell_caoff_allnum",
|
||||
"als_m3_cell_caoff_orgnum",
|
||||
"als_m3_cell_cooff_allnum",
|
||||
"als_m3_cell_cooff_orgnum",
|
||||
"als_m3_cell_af_allnum",
|
||||
"als_m3_cell_af_orgnum",
|
||||
"als_m3_cell_coon_allnum",
|
||||
"als_m3_cell_coon_orgnum",
|
||||
"als_m3_cell_oth_allnum",
|
||||
"als_m3_cell_oth_orgnum",
|
||||
"als_m3_cell_bank_selfnum",
|
||||
"als_m3_cell_bank_allnum",
|
||||
"als_m3_cell_bank_tra_allnum",
|
||||
"als_m3_cell_bank_ret_allnum",
|
||||
"als_m3_cell_bank_orgnum",
|
||||
"als_m3_cell_bank_tra_orgnum",
|
||||
"als_m3_cell_bank_ret_orgnum",
|
||||
"als_m3_cell_bank_tot_mons",
|
||||
"als_m3_cell_bank_avg_monnum",
|
||||
"als_m3_cell_bank_max_monnum",
|
||||
"als_m3_cell_bank_min_monnum",
|
||||
"als_m3_cell_bank_max_inteday",
|
||||
"als_m3_cell_bank_min_inteday",
|
||||
"als_m3_cell_bank_week_allnum",
|
||||
"als_m3_cell_bank_week_orgnum",
|
||||
"als_m3_cell_bank_night_allnum",
|
||||
"als_m3_cell_bank_night_orgnum",
|
||||
"als_m3_cell_nbank_selfnum",
|
||||
"als_m3_cell_nbank_allnum",
|
||||
"als_m3_cell_nbank_p2p_allnum",
|
||||
"als_m3_cell_nbank_mc_allnum",
|
||||
"als_m3_cell_nbank_ca_allnum",
|
||||
"als_m3_cell_nbank_cf_allnum",
|
||||
"als_m3_cell_nbank_com_allnum",
|
||||
"als_m3_cell_nbank_oth_allnum",
|
||||
"als_m3_cell_nbank_nsloan_allnum",
|
||||
"als_m3_cell_nbank_autofin_allnum",
|
||||
"als_m3_cell_nbank_sloan_allnum",
|
||||
"als_m3_cell_nbank_cons_allnum",
|
||||
"als_m3_cell_nbank_finlea_allnum",
|
||||
"als_m3_cell_nbank_else_allnum",
|
||||
"als_m3_cell_nbank_orgnum",
|
||||
"als_m3_cell_nbank_p2p_orgnum",
|
||||
"als_m3_cell_nbank_mc_orgnum",
|
||||
"als_m3_cell_nbank_ca_orgnum",
|
||||
"als_m3_cell_nbank_cf_orgnum",
|
||||
"als_m3_cell_nbank_com_orgnum",
|
||||
"als_m3_cell_nbank_oth_orgnum",
|
||||
"als_m3_cell_nbank_nsloan_orgnum",
|
||||
"als_m3_cell_nbank_autofin_orgnum",
|
||||
"als_m3_cell_nbank_sloan_orgnum",
|
||||
"als_m3_cell_nbank_cons_orgnum",
|
||||
"als_m3_cell_nbank_finlea_orgnum",
|
||||
"als_m3_cell_nbank_else_orgnum",
|
||||
"als_m3_cell_nbank_tot_mons",
|
||||
"als_m3_cell_nbank_avg_monnum",
|
||||
"als_m3_cell_nbank_max_monnum",
|
||||
"als_m3_cell_nbank_min_monnum",
|
||||
"als_m3_cell_nbank_max_inteday",
|
||||
"als_m3_cell_nbank_min_inteday",
|
||||
"als_m3_cell_nbank_week_allnum",
|
||||
"als_m3_cell_nbank_week_orgnum",
|
||||
"als_m3_cell_nbank_night_allnum",
|
||||
"als_m3_cell_nbank_night_orgnum",
|
||||
"als_m6_id_max_inteday",
|
||||
"als_m6_id_min_inteday",
|
||||
"als_m6_id_tot_mons",
|
||||
"als_m6_id_avg_monnum",
|
||||
"als_m6_id_max_monnum",
|
||||
"als_m6_id_min_monnum",
|
||||
"als_m6_id_pdl_allnum",
|
||||
"als_m6_id_pdl_orgnum",
|
||||
"als_m6_id_caon_allnum",
|
||||
"als_m6_id_caon_orgnum",
|
||||
"als_m6_id_rel_allnum",
|
||||
"als_m6_id_rel_orgnum",
|
||||
"als_m6_id_caoff_allnum",
|
||||
"als_m6_id_caoff_orgnum",
|
||||
"als_m6_id_cooff_allnum",
|
||||
"als_m6_id_cooff_orgnum",
|
||||
"als_m6_id_af_allnum",
|
||||
"als_m6_id_af_orgnum",
|
||||
"als_m6_id_coon_allnum",
|
||||
"als_m6_id_coon_orgnum",
|
||||
"als_m6_id_oth_allnum",
|
||||
"als_m6_id_oth_orgnum",
|
||||
"als_m6_id_bank_selfnum",
|
||||
"als_m6_id_bank_allnum",
|
||||
"als_m6_id_bank_tra_allnum",
|
||||
"als_m6_id_bank_ret_allnum",
|
||||
"als_m6_id_bank_orgnum",
|
||||
"als_m6_id_bank_tra_orgnum",
|
||||
"als_m6_id_bank_ret_orgnum",
|
||||
"als_m6_id_bank_tot_mons",
|
||||
"als_m6_id_bank_avg_monnum",
|
||||
"als_m6_id_bank_max_monnum",
|
||||
"als_m6_id_bank_min_monnum",
|
||||
"als_m6_id_bank_max_inteday",
|
||||
"als_m6_id_bank_min_inteday",
|
||||
"als_m6_id_bank_week_allnum",
|
||||
"als_m6_id_bank_week_orgnum",
|
||||
"als_m6_id_bank_night_allnum",
|
||||
"als_m6_id_bank_night_orgnum",
|
||||
"als_m6_id_nbank_selfnum",
|
||||
"als_m6_id_nbank_allnum",
|
||||
"als_m6_id_nbank_p2p_allnum",
|
||||
"als_m6_id_nbank_mc_allnum",
|
||||
"als_m6_id_nbank_ca_allnum",
|
||||
"als_m6_id_nbank_cf_allnum",
|
||||
"als_m6_id_nbank_com_allnum",
|
||||
"als_m6_id_nbank_oth_allnum",
|
||||
"als_m6_id_nbank_nsloan_allnum",
|
||||
"als_m6_id_nbank_autofin_allnum",
|
||||
"als_m6_id_nbank_sloan_allnum",
|
||||
"als_m6_id_nbank_cons_allnum",
|
||||
"als_m6_id_nbank_finlea_allnum",
|
||||
"als_m6_id_nbank_else_allnum",
|
||||
"als_m6_id_nbank_orgnum",
|
||||
"als_m6_id_nbank_p2p_orgnum",
|
||||
"als_m6_id_nbank_mc_orgnum",
|
||||
"als_m6_id_nbank_ca_orgnum",
|
||||
"als_m6_id_nbank_cf_orgnum",
|
||||
"als_m6_id_nbank_com_orgnum",
|
||||
"als_m6_id_nbank_oth_orgnum",
|
||||
"als_m6_id_nbank_nsloan_orgnum",
|
||||
"als_m6_id_nbank_autofin_orgnum",
|
||||
"als_m6_id_nbank_sloan_orgnum",
|
||||
"als_m6_id_nbank_cons_orgnum",
|
||||
"als_m6_id_nbank_finlea_orgnum",
|
||||
"als_m6_id_nbank_else_orgnum",
|
||||
"als_m6_id_nbank_tot_mons",
|
||||
"als_m6_id_nbank_avg_monnum",
|
||||
"als_m6_id_nbank_max_monnum",
|
||||
"als_m6_id_nbank_min_monnum",
|
||||
"als_m6_id_nbank_max_inteday",
|
||||
"als_m6_id_nbank_min_inteday",
|
||||
"als_m6_id_nbank_week_allnum",
|
||||
"als_m6_id_nbank_week_orgnum",
|
||||
"als_m6_id_nbank_night_allnum",
|
||||
"als_m6_id_nbank_night_orgnum",
|
||||
"als_m6_cell_max_inteday",
|
||||
"als_m6_cell_min_inteday",
|
||||
"als_m6_cell_tot_mons",
|
||||
"als_m6_cell_avg_monnum",
|
||||
"als_m6_cell_max_monnum",
|
||||
"als_m6_cell_min_monnum",
|
||||
"als_m6_cell_pdl_allnum",
|
||||
"als_m6_cell_pdl_orgnum",
|
||||
"als_m6_cell_caon_allnum",
|
||||
"als_m6_cell_caon_orgnum",
|
||||
"als_m6_cell_rel_allnum",
|
||||
"als_m6_cell_rel_orgnum",
|
||||
"als_m6_cell_caoff_allnum",
|
||||
"als_m6_cell_caoff_orgnum",
|
||||
"als_m6_cell_cooff_allnum",
|
||||
"als_m6_cell_cooff_orgnum",
|
||||
"als_m6_cell_af_allnum",
|
||||
"als_m6_cell_af_orgnum",
|
||||
"als_m6_cell_coon_allnum",
|
||||
"als_m6_cell_coon_orgnum",
|
||||
"als_m6_cell_oth_allnum",
|
||||
"als_m6_cell_oth_orgnum",
|
||||
"als_m6_cell_bank_selfnum",
|
||||
"als_m6_cell_bank_allnum",
|
||||
"als_m6_cell_bank_tra_allnum",
|
||||
"als_m6_cell_bank_ret_allnum",
|
||||
"als_m6_cell_bank_orgnum",
|
||||
"als_m6_cell_bank_tra_orgnum",
|
||||
"als_m6_cell_bank_ret_orgnum",
|
||||
"als_m6_cell_bank_tot_mons",
|
||||
"als_m6_cell_bank_avg_monnum",
|
||||
"als_m6_cell_bank_max_monnum",
|
||||
"als_m6_cell_bank_min_monnum",
|
||||
"als_m6_cell_bank_max_inteday",
|
||||
"als_m6_cell_bank_min_inteday",
|
||||
"als_m6_cell_bank_week_allnum",
|
||||
"als_m6_cell_bank_week_orgnum",
|
||||
"als_m6_cell_bank_night_allnum",
|
||||
"als_m6_cell_bank_night_orgnum",
|
||||
"als_m6_cell_nbank_selfnum",
|
||||
"als_m6_cell_nbank_allnum",
|
||||
"als_m6_cell_nbank_p2p_allnum",
|
||||
"als_m6_cell_nbank_mc_allnum",
|
||||
"als_m6_cell_nbank_ca_allnum",
|
||||
"als_m6_cell_nbank_cf_allnum",
|
||||
"als_m6_cell_nbank_com_allnum",
|
||||
"als_m6_cell_nbank_oth_allnum",
|
||||
"als_m6_cell_nbank_nsloan_allnum",
|
||||
"als_m6_cell_nbank_autofin_allnum",
|
||||
"als_m6_cell_nbank_sloan_allnum",
|
||||
"als_m6_cell_nbank_cons_allnum",
|
||||
"als_m6_cell_nbank_finlea_allnum",
|
||||
"als_m6_cell_nbank_else_allnum",
|
||||
"als_m6_cell_nbank_orgnum",
|
||||
"als_m6_cell_nbank_p2p_orgnum",
|
||||
"als_m6_cell_nbank_mc_orgnum",
|
||||
"als_m6_cell_nbank_ca_orgnum",
|
||||
"als_m6_cell_nbank_cf_orgnum",
|
||||
"als_m6_cell_nbank_com_orgnum",
|
||||
"als_m6_cell_nbank_oth_orgnum",
|
||||
"als_m6_cell_nbank_nsloan_orgnum",
|
||||
"als_m6_cell_nbank_autofin_orgnum",
|
||||
"als_m6_cell_nbank_sloan_orgnum",
|
||||
"als_m6_cell_nbank_cons_orgnum",
|
||||
"als_m6_cell_nbank_finlea_orgnum",
|
||||
"als_m6_cell_nbank_else_orgnum",
|
||||
"als_m6_cell_nbank_tot_mons",
|
||||
"als_m6_cell_nbank_avg_monnum",
|
||||
"als_m6_cell_nbank_max_monnum",
|
||||
"als_m6_cell_nbank_min_monnum",
|
||||
"als_m6_cell_nbank_max_inteday",
|
||||
"als_m6_cell_nbank_min_inteday",
|
||||
"als_m6_cell_nbank_week_allnum",
|
||||
"als_m6_cell_nbank_week_orgnum",
|
||||
"als_m6_cell_nbank_night_allnum",
|
||||
"als_m6_cell_nbank_night_orgnum",
|
||||
"als_m12_id_max_inteday",
|
||||
"als_m12_id_min_inteday",
|
||||
"als_m12_id_tot_mons",
|
||||
"als_m12_id_avg_monnum",
|
||||
"als_m12_id_max_monnum",
|
||||
"als_m12_id_min_monnum",
|
||||
"als_m12_id_pdl_allnum",
|
||||
"als_m12_id_pdl_orgnum",
|
||||
"als_m12_id_caon_allnum",
|
||||
"als_m12_id_caon_orgnum",
|
||||
"als_m12_id_rel_allnum",
|
||||
"als_m12_id_rel_orgnum",
|
||||
"als_m12_id_caoff_allnum",
|
||||
"als_m12_id_caoff_orgnum",
|
||||
"als_m12_id_cooff_allnum",
|
||||
"als_m12_id_cooff_orgnum",
|
||||
"als_m12_id_af_allnum",
|
||||
"als_m12_id_af_orgnum",
|
||||
"als_m12_id_coon_allnum",
|
||||
"als_m12_id_coon_orgnum",
|
||||
"als_m12_id_oth_allnum",
|
||||
"als_m12_id_oth_orgnum",
|
||||
"als_m12_id_bank_selfnum",
|
||||
"als_m12_id_bank_allnum",
|
||||
"als_m12_id_bank_tra_allnum",
|
||||
"als_m12_id_bank_ret_allnum",
|
||||
"als_m12_id_bank_orgnum",
|
||||
"als_m12_id_bank_tra_orgnum",
|
||||
"als_m12_id_bank_ret_orgnum",
|
||||
"als_m12_id_bank_tot_mons",
|
||||
"als_m12_id_bank_avg_monnum",
|
||||
"als_m12_id_bank_max_monnum",
|
||||
"als_m12_id_bank_min_monnum",
|
||||
"als_m12_id_bank_max_inteday",
|
||||
"als_m12_id_bank_min_inteday",
|
||||
"als_m12_id_bank_week_allnum",
|
||||
"als_m12_id_bank_week_orgnum",
|
||||
"als_m12_id_bank_night_allnum",
|
||||
"als_m12_id_bank_night_orgnum",
|
||||
"als_m12_id_nbank_selfnum",
|
||||
"als_m12_id_nbank_allnum",
|
||||
"als_m12_id_nbank_p2p_allnum",
|
||||
"als_m12_id_nbank_mc_allnum",
|
||||
"als_m12_id_nbank_ca_allnum",
|
||||
"als_m12_id_nbank_cf_allnum",
|
||||
"als_m12_id_nbank_com_allnum",
|
||||
"als_m12_id_nbank_oth_allnum",
|
||||
"als_m12_id_nbank_nsloan_allnum",
|
||||
"als_m12_id_nbank_autofin_allnum",
|
||||
"als_m12_id_nbank_sloan_allnum",
|
||||
"als_m12_id_nbank_cons_allnum",
|
||||
"als_m12_id_nbank_finlea_allnum",
|
||||
"als_m12_id_nbank_else_allnum",
|
||||
"als_m12_id_nbank_orgnum",
|
||||
"als_m12_id_nbank_p2p_orgnum",
|
||||
"als_m12_id_nbank_mc_orgnum",
|
||||
"als_m12_id_nbank_ca_orgnum",
|
||||
"als_m12_id_nbank_cf_orgnum",
|
||||
"als_m12_id_nbank_com_orgnum",
|
||||
"als_m12_id_nbank_oth_orgnum",
|
||||
"als_m12_id_nbank_nsloan_orgnum",
|
||||
"als_m12_id_nbank_autofin_orgnum",
|
||||
"als_m12_id_nbank_sloan_orgnum",
|
||||
"als_m12_id_nbank_cons_orgnum",
|
||||
"als_m12_id_nbank_finlea_orgnum",
|
||||
"als_m12_id_nbank_else_orgnum",
|
||||
"als_m12_id_nbank_tot_mons",
|
||||
"als_m12_id_nbank_avg_monnum",
|
||||
"als_m12_id_nbank_max_monnum",
|
||||
"als_m12_id_nbank_min_monnum",
|
||||
"als_m12_id_nbank_max_inteday",
|
||||
"als_m12_id_nbank_min_inteday",
|
||||
"als_m12_id_nbank_week_allnum",
|
||||
"als_m12_id_nbank_week_orgnum",
|
||||
"als_m12_id_nbank_night_allnum",
|
||||
"als_m12_id_nbank_night_orgnum",
|
||||
"als_m12_cell_max_inteday",
|
||||
"als_m12_cell_min_inteday",
|
||||
"als_m12_cell_tot_mons",
|
||||
"als_m12_cell_avg_monnum",
|
||||
"als_m12_cell_max_monnum",
|
||||
"als_m12_cell_min_monnum",
|
||||
"als_m12_cell_pdl_allnum",
|
||||
"als_m12_cell_pdl_orgnum",
|
||||
"als_m12_cell_caon_allnum",
|
||||
"als_m12_cell_caon_orgnum",
|
||||
"als_m12_cell_rel_allnum",
|
||||
"als_m12_cell_rel_orgnum",
|
||||
"als_m12_cell_caoff_allnum",
|
||||
"als_m12_cell_caoff_orgnum",
|
||||
"als_m12_cell_cooff_allnum",
|
||||
"als_m12_cell_cooff_orgnum",
|
||||
"als_m12_cell_af_allnum",
|
||||
"als_m12_cell_af_orgnum",
|
||||
"als_m12_cell_coon_allnum",
|
||||
"als_m12_cell_coon_orgnum",
|
||||
"als_m12_cell_oth_allnum",
|
||||
"als_m12_cell_oth_orgnum",
|
||||
"als_m12_cell_bank_selfnum",
|
||||
"als_m12_cell_bank_allnum",
|
||||
"als_m12_cell_bank_tra_allnum",
|
||||
"als_m12_cell_bank_ret_allnum",
|
||||
"als_m12_cell_bank_orgnum",
|
||||
"als_m12_cell_bank_tra_orgnum",
|
||||
"als_m12_cell_bank_ret_orgnum",
|
||||
"als_m12_cell_bank_tot_mons",
|
||||
"als_m12_cell_bank_avg_monnum",
|
||||
"als_m12_cell_bank_max_monnum",
|
||||
"als_m12_cell_bank_min_monnum",
|
||||
"als_m12_cell_bank_max_inteday",
|
||||
"als_m12_cell_bank_min_inteday",
|
||||
"als_m12_cell_bank_week_allnum",
|
||||
"als_m12_cell_bank_week_orgnum",
|
||||
"als_m12_cell_bank_night_allnum",
|
||||
"als_m12_cell_bank_night_orgnum",
|
||||
"als_m12_cell_nbank_selfnum",
|
||||
"als_m12_cell_nbank_allnum",
|
||||
"als_m12_cell_nbank_p2p_allnum",
|
||||
"als_m12_cell_nbank_mc_allnum",
|
||||
"als_m12_cell_nbank_ca_allnum",
|
||||
"als_m12_cell_nbank_cf_allnum",
|
||||
"als_m12_cell_nbank_com_allnum",
|
||||
"als_m12_cell_nbank_oth_allnum",
|
||||
"als_m12_cell_nbank_nsloan_allnum",
|
||||
"als_m12_cell_nbank_autofin_allnum",
|
||||
"als_m12_cell_nbank_sloan_allnum",
|
||||
"als_m12_cell_nbank_cons_allnum",
|
||||
"als_m12_cell_nbank_finlea_allnum",
|
||||
"als_m12_cell_nbank_else_allnum",
|
||||
"als_m12_cell_nbank_orgnum",
|
||||
"als_m12_cell_nbank_p2p_orgnum",
|
||||
"als_m12_cell_nbank_mc_orgnum",
|
||||
"als_m12_cell_nbank_ca_orgnum",
|
||||
"als_m12_cell_nbank_cf_orgnum",
|
||||
"als_m12_cell_nbank_com_orgnum",
|
||||
"als_m12_cell_nbank_oth_orgnum",
|
||||
"als_m12_cell_nbank_nsloan_orgnum",
|
||||
"als_m12_cell_nbank_autofin_orgnum",
|
||||
"als_m12_cell_nbank_sloan_orgnum",
|
||||
"als_m12_cell_nbank_cons_orgnum",
|
||||
"als_m12_cell_nbank_finlea_orgnum",
|
||||
"als_m12_cell_nbank_else_orgnum",
|
||||
"als_m12_cell_nbank_tot_mons",
|
||||
"als_m12_cell_nbank_avg_monnum",
|
||||
"als_m12_cell_nbank_max_monnum",
|
||||
"als_m12_cell_nbank_min_monnum",
|
||||
"als_m12_cell_nbank_max_inteday",
|
||||
"als_m12_cell_nbank_min_inteday",
|
||||
"als_m12_cell_nbank_week_allnum",
|
||||
"als_m12_cell_nbank_week_orgnum",
|
||||
"als_m12_cell_nbank_night_allnum",
|
||||
"als_m12_cell_nbank_night_orgnum",
|
||||
"als_fst_id_bank_inteday",
|
||||
"als_fst_id_nbank_inteday",
|
||||
"als_fst_cell_bank_inteday",
|
||||
"als_fst_cell_nbank_inteday",
|
||||
"als_lst_id_bank_inteday",
|
||||
"als_lst_id_bank_consnum",
|
||||
"als_lst_id_bank_csinteday",
|
||||
"als_lst_id_nbank_inteday",
|
||||
"als_lst_id_nbank_consnum",
|
||||
"als_lst_id_nbank_csinteday",
|
||||
"als_lst_cell_bank_inteday",
|
||||
"als_lst_cell_bank_consnum",
|
||||
"als_lst_cell_bank_csinteday",
|
||||
"als_lst_cell_nbank_inteday",
|
||||
"als_lst_cell_nbank_consnum",
|
||||
"als_lst_cell_nbank_csinteday"
|
||||
]
|
51
dataRender/word_list.js
Normal file
51
dataRender/word_list.js
Normal file
@ -0,0 +1,51 @@
|
||||
const keyword = [
|
||||
'als',
|
||||
'd7', // 近7日
|
||||
'id', // 身份证号
|
||||
'pdl', // 线上小额现金贷
|
||||
'allnum', // 次数
|
||||
'orgnum', // 机构数、
|
||||
'week', // 周末
|
||||
'night', // 夜间申请
|
||||
'caon', // 线上现金分期
|
||||
'rel', // 信用卡(类信用卡)
|
||||
'caoff', // 线下现金分期
|
||||
'cooff', // 线下消费分期
|
||||
'af', // 汽车金融
|
||||
'coon', // 线上消费分期
|
||||
'oth', // 申请其他
|
||||
'bank', // 银行机构
|
||||
'selfnum', // 本银行机构
|
||||
'tra', // 传统银行
|
||||
'ret', // 网络银行
|
||||
'nbank', // 非银行机构
|
||||
'p2p', // 改制机构
|
||||
'mc', // 小贷机构
|
||||
'ca', // 现金类分期机构
|
||||
'cf', // 消费类分期机构
|
||||
'com', // 代偿类分期机构
|
||||
'nsloan', // 持牌网络小贷
|
||||
'autofin', // 持牌汽车金融机构
|
||||
'sloan', // 持牌小贷机构
|
||||
'cons', // 持牌消费金融机构
|
||||
'finlea', // 持牌融资租赁机构
|
||||
'else', // 其他申请
|
||||
'cell', // 10 按手机号查询,
|
||||
'd15', // 近 15 天申
|
||||
'm1', // 近 1 个月
|
||||
'm3', // 3 个月
|
||||
'max', // 最大
|
||||
'inteday', // 间隔天数
|
||||
'min', // 最小
|
||||
'tot', // 申请记录
|
||||
'mons', // 月份数
|
||||
'avg', // 平均
|
||||
'monnum', // 最大月
|
||||
'm6', // 6 个月
|
||||
'm12', // 12个月
|
||||
'fst', // 最早
|
||||
'lst', // 最近
|
||||
'consnum', // 连续申请
|
||||
'csinteday', // 连续申请持续天数
|
||||
]
|
||||
console.log(keyword)
|
65
dataRender/人企关系.json
Normal file
65
dataRender/人企关系.json
Normal file
@ -0,0 +1,65 @@
|
||||
{
|
||||
"msg": "查询成功",
|
||||
"code": "0000",
|
||||
"orderNo": "20241028112921367340619",
|
||||
"data": {
|
||||
"total": 1,
|
||||
"datalist": [
|
||||
{
|
||||
"orgName": "海南省学宇思网络科技有限公司",
|
||||
"pName": "刘福思",
|
||||
"stockHolderItem": {
|
||||
"orgHolderType": "自然人",
|
||||
"investDate": "",
|
||||
"investRate": "40%",
|
||||
"subscriptAmt": "40.000000",
|
||||
"orgHolderName": "刘福思"
|
||||
},
|
||||
"relationship": [
|
||||
"lp",
|
||||
"sh",
|
||||
"tm"
|
||||
],
|
||||
"fsource": "",
|
||||
"basicInfo": {
|
||||
"regStatus": "存续",
|
||||
"regCapital": "100.0000万人民币",
|
||||
"reccap": 0,
|
||||
"city": "海口市",
|
||||
"industry_code": "I",
|
||||
"industry": "互联网和相关服务",
|
||||
"type": "1",
|
||||
"staffList": {
|
||||
"result": [
|
||||
{
|
||||
"name": "刘福思",
|
||||
"type": "2",
|
||||
"typeJoin": [
|
||||
"执行董事兼总经理"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"nic_code": "I64",
|
||||
"legalPersonName": "刘福思",
|
||||
"regNumber": "460108011261916",
|
||||
"creditCode": "91460108MADNY3F43W",
|
||||
"province": "海南省",
|
||||
"regorg": "海南省市场监督管理局",
|
||||
"companyOrgType": "有限责任公司(自然人投资或控股)",
|
||||
"revdate": "",
|
||||
"estiblishTime": "2024-06-20",
|
||||
"opscope": "一般经营项目:品牌管理;5G通信技术服务;人工智能应用软件开发;互联网安全服务;量子计算技术服务;技术服务、技术开发、技术咨询、技术交流、技术转让、技术推广;网络技术服务;专业设计服务;互联网数据服务;互联网销售(除销售需要许可的商品);食品互联网销售(仅销售预包装食品);软件开发;动漫游戏开发;计算机软硬件及辅助设备零售;计算机软硬件及辅助设备批发;计算器设备销售;机械设备销售;五金产品零售;五金产品批发;电子产品销售;人工智能硬件销售;通信设备销售;光通信设备销售;通信设备制造;信息系统集成服务;图文设计制作;广告设计、代理;广告发布;数字内容制作服务(不含出版发行);数字文化创意软件开发;软件销售;市场营销策划;企业管理咨询;信息咨询服务(不含许可类信息咨询服务);市场调查(不含涉外调查);工业设计服务;玩具销售;化妆品零售;化妆品批发;摄像及视频制作服务;平面设计;法律咨询(不含依法须律师事务所执业许可的业务);旅游开发项目策划咨询;体育用品及器材批发;体育用品及器材零售;户外用品销售;体育赛事策划;体育健康服务;组织体育表演活动;体育中介代理服务;信息技术咨询服务;数据处理服务;数据处理和存储支持服务;大数据服务;云计算装备技术服务;电子、机械设备维护(不含特种设备);智能机器人的研发(经营范围中的一般经营项目依法自主开展经营活动,通过国家企业信用信息公示系统(海南)向社会公示)许可经营项目:食品进出口;货物进出口;技术进出口;在线数据处理与交易处理业务(经营类电子商务);互联网游戏服务;第二类增值电信业务;互联网信息服务(许可经营项目凭许可证件经营)",
|
||||
"reccapcur": "人民币",
|
||||
"regCapitalCurrency": "人民币",
|
||||
"nic_name": "信息传输、软件和信息技术服务业-互联网和相关服务",
|
||||
"candate": "",
|
||||
"district": "秀英区",
|
||||
"name": "海南省学宇思网络科技有限公司",
|
||||
"base": "han",
|
||||
"apprdate": "2024-09-14"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
646
dataRender/人企关系2.json
Normal file
646
dataRender/人企关系2.json
Normal file
@ -0,0 +1,646 @@
|
||||
{
|
||||
"msg": "查询成功",
|
||||
"code": "0000",
|
||||
"orderNo": "20241113191941335900073",
|
||||
"data": {
|
||||
"total": 8,
|
||||
"datalist": [
|
||||
{
|
||||
"executedPerson": [
|
||||
{
|
||||
"caseCode": "(2014)城中执字第00062号",
|
||||
"partyCardNum": "45252819740****3016",
|
||||
"pname": "李强",
|
||||
"caseCreateTime": "2014-02-11",
|
||||
"execCourtName": "",
|
||||
"execMoney": 220605
|
||||
}
|
||||
],
|
||||
"dishonestExecutedPerson": [
|
||||
{
|
||||
"businessentity": "",
|
||||
"areaname": "广西",
|
||||
"courtname": "柳州市城中区人民法院",
|
||||
"unperformPart": "",
|
||||
"type": "0",
|
||||
"performedPart": "",
|
||||
"iname": "李强",
|
||||
"disrupttypename": "其他有履行能力而拒不履行生效法律文书确定义务",
|
||||
"casecode": "(2014)城中执字第00062号",
|
||||
"cardnum": "4525281974****3016",
|
||||
"performance": "全部未履行",
|
||||
"regdate": "2014-02-11",
|
||||
"duty": "中国农业银行股份有限公司柳州城中支行申请执行李强220604.73元",
|
||||
"gistunit": "柳州市城中区人民法院",
|
||||
"publishdate": "2014-06-19",
|
||||
"gistid": "(2010)城中民二初字第480号民事判决书"
|
||||
}
|
||||
],
|
||||
"orgName": "广西鼎铭房地产开发有限公司",
|
||||
"pName": "李强",
|
||||
"stockHolderItem": {
|
||||
"orgHolderType": "自然人",
|
||||
"investDate": "",
|
||||
"investRate": "10.0%",
|
||||
"subscriptAmt": 100,
|
||||
"orgHolderName": "李强"
|
||||
},
|
||||
"relationship": [
|
||||
"sh",
|
||||
"lp",
|
||||
"tm"
|
||||
],
|
||||
"fsource": "1",
|
||||
"basicInfo": {
|
||||
"regStatus": "吊销,未注销",
|
||||
"regCapital": "1000.000000万人民币",
|
||||
"reccap": 0,
|
||||
"city": "",
|
||||
"industry_code": "K",
|
||||
"industry": "房地产业",
|
||||
"type": "1",
|
||||
"nic_code": "K7010",
|
||||
"staffList": {
|
||||
"result": [
|
||||
{
|
||||
"name": "李强",
|
||||
"type": "2",
|
||||
"typeJoin": [
|
||||
"监事"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"legalPersonName": "李强",
|
||||
"regNumber": "450000200012318",
|
||||
"creditCode": "91450100742080353R",
|
||||
"province": "广西壮族自治区",
|
||||
"regorg": "南宁市市场监督管理局高新技术产业开发区分局",
|
||||
"companyOrgType": "有限责任公司(自然人投资或控股)",
|
||||
"revdate": "2016-03-19",
|
||||
"estiblishTime": "2002-10-16",
|
||||
"opscope": "房地产开发经营(取得相应资质后方可在其资质等级核定范围内从事房地产开发经营活动);建筑材料、装饰材料、农副土特产品、日用百货、五金交电、汽车零配件的购销;计算机销售及维修。",
|
||||
"reccapcur": "人民币",
|
||||
"regCapitalCurrency": "人民币",
|
||||
"nic_name": "房地产业-房地产业-房地产开发经营-房地产开发经营",
|
||||
"candate": "",
|
||||
"district": "",
|
||||
"name": "广西鼎铭房地产开发有限公司",
|
||||
"base": "gx",
|
||||
"apprdate": "2016-03-19"
|
||||
},
|
||||
"adminPenalty": [
|
||||
{
|
||||
"departmentName": "南宁市工商行政管理局高新技术产业开发区分局",
|
||||
"reason": "公司成立后无正当理由超过6个月未开业的,或者开业后自行停业连续6个月以上",
|
||||
"punishNumber": "南工商高新处字(2016)500010024号",
|
||||
"type": "",
|
||||
"content": "",
|
||||
"decisionDate": "2016-03-19",
|
||||
"legalPersonName": "李强"
|
||||
},
|
||||
{
|
||||
"departmentName": "45011101",
|
||||
"reason": "南宁恒发网络科技有限公司等3177户企业,未依法进行企业信息网上年报公示。经我分局执法人员在以上企业的执照注册住所检查,发现上述企业已不在其注册住所经营或办公,根据企业注册登记时所留电话也联系不上上述企业。",
|
||||
"punishNumber": "南工商高新处字(2016)500010024号",
|
||||
"type": "吊销执照(登记证)",
|
||||
"content": "-",
|
||||
"decisionDate": "2016-03-19",
|
||||
"legalPersonName": "李强"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"executedPerson": [
|
||||
{
|
||||
"caseCode": "(2010)青执字第01000号",
|
||||
"partyCardNum": "452528********3012",
|
||||
"pname": "李健",
|
||||
"caseCreateTime": "2010-09-06",
|
||||
"execCourtName": "",
|
||||
"execMoney": 283845
|
||||
},
|
||||
{
|
||||
"caseCode": "(2010)青执字第00188号",
|
||||
"partyCardNum": "45252819691****3012",
|
||||
"pname": "李健",
|
||||
"caseCreateTime": "2010-02-08",
|
||||
"execCourtName": "",
|
||||
"execMoney": 308464
|
||||
}
|
||||
],
|
||||
"orgName": "南宁市铭鼎商贸有限公司",
|
||||
"pName": "李强",
|
||||
"stockHolderItem": {
|
||||
"orgHolderType": "自然人",
|
||||
"investDate": "",
|
||||
"investRate": "20.0%",
|
||||
"subscriptAmt": 20,
|
||||
"orgHolderName": "李强"
|
||||
},
|
||||
"relationship": [
|
||||
"sh"
|
||||
],
|
||||
"fsource": "1",
|
||||
"basicInfo": {
|
||||
"regStatus": "吊销,未注销",
|
||||
"regCapital": "100.000000万人民币",
|
||||
"reccap": 0,
|
||||
"city": "南宁市",
|
||||
"industry_code": "F",
|
||||
"industry": "零售业",
|
||||
"type": "1",
|
||||
"nic_code": "F5211",
|
||||
"legalPersonName": "李健",
|
||||
"regNumber": "4501002508737",
|
||||
"creditCode": "91450107MA5KK3PU6A",
|
||||
"province": "广西壮族自治区",
|
||||
"regorg": "南宁市西乡塘区市场监督管理局",
|
||||
"companyOrgType": "有限责任公司(自然人投资或控股)",
|
||||
"revdate": "2016-05-28",
|
||||
"estiblishTime": "2004-07-02",
|
||||
"opscope": "窗帘布艺,家居用品,装饰材料(危险化学品除外),日用百货,服装,纺织品。",
|
||||
"reccapcur": "人民币",
|
||||
"regCapitalCurrency": "人民币",
|
||||
"nic_name": "批发和零售业-零售业-综合零售-百货零售",
|
||||
"candate": "",
|
||||
"district": "",
|
||||
"name": "南宁市铭鼎商贸有限公司",
|
||||
"base": "gx",
|
||||
"apprdate": "2016-05-28"
|
||||
}
|
||||
},
|
||||
{
|
||||
"executedPerson": [
|
||||
{
|
||||
"caseCode": "(2014)城中执字第00062号",
|
||||
"partyCardNum": "45252819740****3016",
|
||||
"pname": "李强",
|
||||
"caseCreateTime": "2014-02-11",
|
||||
"execCourtName": "",
|
||||
"execMoney": 220605
|
||||
}
|
||||
],
|
||||
"dishonestExecutedPerson": [
|
||||
{
|
||||
"businessentity": "",
|
||||
"areaname": "广西",
|
||||
"courtname": "柳州市城中区人民法院",
|
||||
"unperformPart": "",
|
||||
"type": "0",
|
||||
"performedPart": "",
|
||||
"iname": "李强",
|
||||
"disrupttypename": "其他有履行能力而拒不履行生效法律文书确定义务",
|
||||
"casecode": "(2014)城中执字第00062号",
|
||||
"cardnum": "4525281974****3016",
|
||||
"performance": "全部未履行",
|
||||
"regdate": "2014-02-11",
|
||||
"duty": "中国农业银行股份有限公司柳州城中支行申请执行李强220604.73元",
|
||||
"gistunit": "柳州市城中区人民法院",
|
||||
"publishdate": "2014-06-19",
|
||||
"gistid": "(2010)城中民二初字第480号民事判决书"
|
||||
}
|
||||
],
|
||||
"orgName": "广西鼎铭房地产置换服务有限公司南宁分公司",
|
||||
"pName": "李强",
|
||||
"relationship": [
|
||||
"lp",
|
||||
"tm",
|
||||
"his_tm"
|
||||
],
|
||||
"fsource": "1",
|
||||
"basicInfo": {
|
||||
"regStatus": "吊销,未注销",
|
||||
"regCapital": "5.0万人民币",
|
||||
"reccap": 0,
|
||||
"city": "南宁市",
|
||||
"industry_code": "K",
|
||||
"industry": "房地产业",
|
||||
"type": "1",
|
||||
"nic_code": "K7030",
|
||||
"staffList": {
|
||||
"result": [
|
||||
{
|
||||
"name": "李强",
|
||||
"type": "2",
|
||||
"typeJoin": [
|
||||
""
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"legalPersonName": "李强",
|
||||
"regNumber": "4501001005198",
|
||||
"creditCode": "",
|
||||
"province": "广西壮族自治区",
|
||||
"his_staffList": {
|
||||
"result": [
|
||||
{
|
||||
"name": "李强",
|
||||
"type": "2",
|
||||
"typeJoin": [
|
||||
""
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"regorg": "南宁市青秀区市场监督管理局",
|
||||
"companyOrgType": "有限责任公司分公司(自然人投资或控股)",
|
||||
"revdate": "2018-06-25",
|
||||
"estiblishTime": "2002-01-28",
|
||||
"opscope": "房地产信息咨询服务,房地产交易居间、代理、行纪;商品信息咨询(不含期货、金融、保险、证券等国家专项规定),商品交易居间、代理、行纪。",
|
||||
"reccapcur": "人民币",
|
||||
"regCapitalCurrency": "人民币",
|
||||
"nic_name": "房地产业-房地产业-房地产中介服务-房地产中介服务",
|
||||
"candate": "",
|
||||
"district": "青秀区",
|
||||
"name": "广西鼎铭房地产置换服务有限公司南宁分公司",
|
||||
"base": "gx",
|
||||
"apprdate": "2018-06-25"
|
||||
}
|
||||
},
|
||||
{
|
||||
"executedPerson": [
|
||||
{
|
||||
"caseCode": "(2014)城中执字第00062号",
|
||||
"partyCardNum": "45252819740****3016",
|
||||
"pname": "李强",
|
||||
"caseCreateTime": "2014-02-11",
|
||||
"execCourtName": "",
|
||||
"execMoney": 220605
|
||||
}
|
||||
],
|
||||
"dishonestExecutedPerson": [
|
||||
{
|
||||
"businessentity": "",
|
||||
"areaname": "广西",
|
||||
"courtname": "柳州市城中区人民法院",
|
||||
"unperformPart": "",
|
||||
"type": "0",
|
||||
"performedPart": "",
|
||||
"iname": "李强",
|
||||
"disrupttypename": "其他有履行能力而拒不履行生效法律文书确定义务",
|
||||
"casecode": "(2014)城中执字第00062号",
|
||||
"cardnum": "4525281974****3016",
|
||||
"performance": "全部未履行",
|
||||
"regdate": "2014-02-11",
|
||||
"duty": "中国农业银行股份有限公司柳州城中支行申请执行李强220604.73元",
|
||||
"gistunit": "柳州市城中区人民法院",
|
||||
"publishdate": "2014-06-19",
|
||||
"gistid": "(2010)城中民二初字第480号民事判决书"
|
||||
}
|
||||
],
|
||||
"orgName": "深圳市亿讯时空信息技术有限公司北京分公司",
|
||||
"pName": "李强",
|
||||
"relationship": [
|
||||
"lp",
|
||||
"tm"
|
||||
],
|
||||
"fsource": "1",
|
||||
"basicInfo": {
|
||||
"regStatus": "吊销",
|
||||
"regCapital": "",
|
||||
"reccap": 0,
|
||||
"city": "北京市",
|
||||
"industry_code": "I",
|
||||
"industry": "软件和信息技术服务业",
|
||||
"type": "1",
|
||||
"nic_code": "I659",
|
||||
"staffList": {
|
||||
"result": [
|
||||
{
|
||||
"name": "李强",
|
||||
"type": "2",
|
||||
"typeJoin": [
|
||||
"负责人"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"legalPersonName": "李强",
|
||||
"regNumber": "1101081949120",
|
||||
"creditCode": "91110108MA0464P97H",
|
||||
"province": "北京市",
|
||||
"regorg": "北京市工商行政管理局海淀分局",
|
||||
"companyOrgType": "其他有限责任公司分公司",
|
||||
"revdate": "2010-11-25",
|
||||
"estiblishTime": "2006-04-13",
|
||||
"opscope": "计算机软件和系统集成及辅助设备;网络工程;通讯设备的技术开发、咨询;广告设计。",
|
||||
"reccapcur": "人民币",
|
||||
"regCapitalCurrency": "人民币",
|
||||
"nic_name": "信息传输、软件和信息技术服务业-软件和信息技术服务业-其他信息技术服务业",
|
||||
"candate": "",
|
||||
"district": "海淀区",
|
||||
"name": "深圳市亿讯时空信息技术有限公司北京分公司",
|
||||
"base": "bj",
|
||||
"apprdate": "2006-04-13"
|
||||
},
|
||||
"adminPenalty": [
|
||||
{
|
||||
"departmentName": "海淀分局",
|
||||
"reason": "",
|
||||
"punishNumber": "京工商海处字(2010)第D2389号",
|
||||
"type": "逾期年检",
|
||||
"content": "",
|
||||
"decisionDate": "2010-08-23",
|
||||
"legalPersonName": "李强"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"executedPerson": [
|
||||
{
|
||||
"caseCode": "(2014)城中执字第00062号",
|
||||
"partyCardNum": "45252819740****3016",
|
||||
"pname": "李强",
|
||||
"caseCreateTime": "2014-02-11",
|
||||
"execCourtName": "",
|
||||
"execMoney": 220605
|
||||
},
|
||||
{
|
||||
"caseCode": "(2010)青执字第00198号",
|
||||
"partyCardNum": "36042819721****0037",
|
||||
"pname": "秦学文",
|
||||
"caseCreateTime": "2010-02-08",
|
||||
"execCourtName": "",
|
||||
"execMoney": 444028
|
||||
}
|
||||
],
|
||||
"dishonestExecutedPerson": [
|
||||
{
|
||||
"businessentity": "",
|
||||
"areaname": "广西",
|
||||
"courtname": "柳州市城中区人民法院",
|
||||
"unperformPart": "",
|
||||
"type": "0",
|
||||
"performedPart": "",
|
||||
"iname": "李强",
|
||||
"disrupttypename": "其他有履行能力而拒不履行生效法律文书确定义务",
|
||||
"casecode": "(2014)城中执字第00062号",
|
||||
"cardnum": "4525281974****3016",
|
||||
"performance": "全部未履行",
|
||||
"regdate": "2014-02-11",
|
||||
"duty": "中国农业银行股份有限公司柳州城中支行申请执行李强220604.73元",
|
||||
"gistunit": "柳州市城中区人民法院",
|
||||
"publishdate": "2014-06-19",
|
||||
"gistid": "(2010)城中民二初字第480号民事判决书"
|
||||
}
|
||||
],
|
||||
"orgName": "深圳市亿讯时空信息技术有限公司",
|
||||
"pName": "李强",
|
||||
"stockHolderItem": {
|
||||
"orgHolderType": "自然人",
|
||||
"investDate": "",
|
||||
"investRate": "17.0%",
|
||||
"subscriptAmt": 170,
|
||||
"orgHolderName": "李强"
|
||||
},
|
||||
"relationship": [
|
||||
"sh",
|
||||
"tm"
|
||||
],
|
||||
"fsource": "1",
|
||||
"basicInfo": {
|
||||
"regStatus": "吊销,未注销",
|
||||
"regCapital": "1000.000000万人民币",
|
||||
"reccap": 0,
|
||||
"city": "深圳市",
|
||||
"industry_code": "M",
|
||||
"industry": "科技推广和应用服务业",
|
||||
"type": "1",
|
||||
"nic_code": "M7590",
|
||||
"staffList": {
|
||||
"result": [
|
||||
{
|
||||
"name": "李强",
|
||||
"type": "2",
|
||||
"typeJoin": [
|
||||
"董事,总经理"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"legalPersonName": "李铭",
|
||||
"regNumber": "440301103603769",
|
||||
"creditCode": "91440300786556245H",
|
||||
"province": "广东省",
|
||||
"regorg": "福田局",
|
||||
"companyOrgType": "有限责任公司",
|
||||
"revdate": "2020-04-07",
|
||||
"estiblishTime": "2006-03-23",
|
||||
"opscope": "一般经营项目是:计算机软件和系统集成及辅助设备、网络工程、通讯设备的技术开发、咨询、销售,国内贸易(不含专营、专控、专卖商品),从事货物、技术进出口业务(不含分销、国家专营专控商品);广告业务。,许可经营项目是:",
|
||||
"reccapcur": "人民币",
|
||||
"regCapitalCurrency": "人民币",
|
||||
"nic_name": "科学研究和技术服务业-科技推广和应用服务业-其他科技推广服务业-其他科技推广服务业",
|
||||
"candate": "2020-04-07",
|
||||
"district": "福田区",
|
||||
"name": "深圳市亿讯时空信息技术有限公司",
|
||||
"base": "gd",
|
||||
"apprdate": "2008-09-04"
|
||||
}
|
||||
},
|
||||
{
|
||||
"executedPerson": [
|
||||
{
|
||||
"caseCode": "(2010)青执字第01000号",
|
||||
"partyCardNum": "452528********3012",
|
||||
"pname": "李健",
|
||||
"caseCreateTime": "2010-09-06",
|
||||
"execCourtName": "",
|
||||
"execMoney": 283845
|
||||
},
|
||||
{
|
||||
"caseCode": "(2010)青执字第00188号",
|
||||
"partyCardNum": "45252819691****3012",
|
||||
"pname": "李健",
|
||||
"caseCreateTime": "2010-02-08",
|
||||
"execCourtName": "",
|
||||
"execMoney": 308464
|
||||
}
|
||||
],
|
||||
"orgName": "南宁市豆花香食品有限公司",
|
||||
"pName": "李强",
|
||||
"stockHolderItem": {
|
||||
"orgHolderType": "自然人",
|
||||
"investDate": "2003-08-06",
|
||||
"investRate": "50.0%",
|
||||
"subscriptAmt": 25,
|
||||
"orgHolderName": "李强"
|
||||
},
|
||||
"relationship": [
|
||||
"sh"
|
||||
],
|
||||
"fsource": "1",
|
||||
"basicInfo": {
|
||||
"regStatus": "吊销,未注销",
|
||||
"regCapital": "50万元人民币",
|
||||
"reccap": 0,
|
||||
"city": "南宁市",
|
||||
"industry_code": "F",
|
||||
"industry": "零售业",
|
||||
"type": "1",
|
||||
"nic_code": "F5227",
|
||||
"legalPersonName": "李健",
|
||||
"regNumber": "4501002505675",
|
||||
"creditCode": "91450100MA5KJ83P3J",
|
||||
"province": "广西壮族自治区",
|
||||
"regorg": "南宁市行政审批局",
|
||||
"companyOrgType": "有限责任公司(自然人投资或控股)",
|
||||
"revdate": "2007-02-08",
|
||||
"estiblishTime": "2003-08-06",
|
||||
"opscope": "豆制品的生产及销售;农副土特产品,日用百货,五金交电的销售。",
|
||||
"reccapcur": "人民币",
|
||||
"regCapitalCurrency": "人民币",
|
||||
"nic_name": "批发和零售业-零售业-食品、饮料及烟草制品专门零售-烟草制品零售",
|
||||
"candate": "",
|
||||
"district": "",
|
||||
"name": "南宁市豆花香食品有限公司",
|
||||
"base": "gx",
|
||||
"apprdate": "2004-06-30"
|
||||
}
|
||||
},
|
||||
{
|
||||
"executedPerson": [
|
||||
{
|
||||
"caseCode": "(2010)青执字第01000号",
|
||||
"partyCardNum": "452528********3012",
|
||||
"pname": "李健",
|
||||
"caseCreateTime": "2010-09-06",
|
||||
"execCourtName": "",
|
||||
"execMoney": 283845
|
||||
},
|
||||
{
|
||||
"caseCode": "(2010)青执字第00188号",
|
||||
"partyCardNum": "45252819691****3012",
|
||||
"pname": "李健",
|
||||
"caseCreateTime": "2010-02-08",
|
||||
"execCourtName": "",
|
||||
"execMoney": 308464
|
||||
},
|
||||
{
|
||||
"caseCode": "(2014)城中执字第00062号",
|
||||
"partyCardNum": "45252819740****3016",
|
||||
"pname": "李强",
|
||||
"caseCreateTime": "2014-02-11",
|
||||
"execCourtName": "",
|
||||
"execMoney": 220605
|
||||
}
|
||||
],
|
||||
"dishonestExecutedPerson": [
|
||||
{
|
||||
"businessentity": "",
|
||||
"areaname": "广西",
|
||||
"courtname": "柳州市城中区人民法院",
|
||||
"unperformPart": "",
|
||||
"type": "0",
|
||||
"performedPart": "",
|
||||
"iname": "李强",
|
||||
"disrupttypename": "其他有履行能力而拒不履行生效法律文书确定义务",
|
||||
"casecode": "(2014)城中执字第00062号",
|
||||
"cardnum": "4525281974****3016",
|
||||
"performance": "全部未履行",
|
||||
"regdate": "2014-02-11",
|
||||
"duty": "中国农业银行股份有限公司柳州城中支行申请执行李强220604.73元",
|
||||
"gistunit": "柳州市城中区人民法院",
|
||||
"publishdate": "2014-06-19",
|
||||
"gistid": "(2010)城中民二初字第480号民事判决书"
|
||||
}
|
||||
],
|
||||
"orgName": "广西鼎铭房地产置换服务有限公司",
|
||||
"pName": "李强",
|
||||
"stockHolderItem": {
|
||||
"orgHolderType": "自然人",
|
||||
"investDate": "",
|
||||
"investRate": "10.87%",
|
||||
"subscriptAmt": 50,
|
||||
"orgHolderName": "李强"
|
||||
},
|
||||
"relationship": [
|
||||
"sh",
|
||||
"tm"
|
||||
],
|
||||
"fsource": "1",
|
||||
"basicInfo": {
|
||||
"regStatus": "吊销,未注销",
|
||||
"regCapital": "250万元人民币",
|
||||
"reccap": 200,
|
||||
"city": "柳州市",
|
||||
"industry_code": "I",
|
||||
"industry": "软件和信息技术服务业",
|
||||
"type": "1",
|
||||
"nic_code": "I6513",
|
||||
"staffList": {
|
||||
"result": [
|
||||
{
|
||||
"name": "李强",
|
||||
"type": "2",
|
||||
"typeJoin": [
|
||||
"监事"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"legalPersonName": "李健",
|
||||
"regNumber": "4502002501968",
|
||||
"creditCode": "91450200MA5KPNEG3T",
|
||||
"province": "广西壮族自治区",
|
||||
"regorg": "柳州市市场监督管理局",
|
||||
"companyOrgType": "有限责任公司(自然人投资或控股)",
|
||||
"revdate": "2009-01-04",
|
||||
"estiblishTime": "2001-04-11",
|
||||
"opscope": "连锁经营:房地产信息咨询服务,房地产交易居间、代理、行纪;商品信息咨询(不含期货、金融、保险、证券等国家专项规定),商品交易居间、代理、行纪。",
|
||||
"reccapcur": "人民币",
|
||||
"regCapitalCurrency": "人民币",
|
||||
"nic_name": "信息传输、软件和信息技术服务业-软件和信息技术服务业-软件开发-应用软件开发",
|
||||
"candate": "",
|
||||
"district": "",
|
||||
"name": "广西鼎铭房地产置换服务有限公司",
|
||||
"base": "gx",
|
||||
"apprdate": "2005-09-26"
|
||||
}
|
||||
},
|
||||
{
|
||||
"orgName": "广西鼎铭装饰工程有限公司",
|
||||
"pName": "李强",
|
||||
"stockHolderItem": {
|
||||
"orgHolderType": "自然人",
|
||||
"investDate": "",
|
||||
"investRate": "5.26%",
|
||||
"subscriptAmt": 30,
|
||||
"orgHolderName": "李强"
|
||||
},
|
||||
"relationship": [
|
||||
"sh"
|
||||
],
|
||||
"fsource": "1",
|
||||
"basicInfo": {
|
||||
"regStatus": "吊销,未注销",
|
||||
"regCapital": "300万元人民币",
|
||||
"reccap": 0,
|
||||
"city": "南宁市",
|
||||
"industry_code": "E",
|
||||
"industry": "建筑装饰、装修和其他建筑业",
|
||||
"type": "1",
|
||||
"nic_code": "E5011",
|
||||
"legalPersonName": "李健",
|
||||
"regNumber": "4500002501464",
|
||||
"creditCode": "914500007479525012",
|
||||
"province": "广西壮族自治区",
|
||||
"regorg": "广西壮族自治区市场监督管理局",
|
||||
"companyOrgType": "有限责任公司(自然人投资或控股)",
|
||||
"revdate": "2007-09-14",
|
||||
"estiblishTime": "2003-02-27",
|
||||
"opscope": "建筑装修装饰工程专业承包(暂定)叁级;五金交电、日用百货、建筑材料、装饰材料、机电产品、汽车配件、摩托车配件的购销。",
|
||||
"reccapcur": "人民币",
|
||||
"regCapitalCurrency": "人民币",
|
||||
"nic_name": "建筑业-建筑装饰、装修和其他建筑业-建筑装饰和装修业-公共建筑装饰和装修",
|
||||
"candate": "",
|
||||
"district": "",
|
||||
"name": "广西鼎铭装饰工程有限公司",
|
||||
"base": "gx",
|
||||
"apprdate": "2005-03-10"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
150
dataRender/人企关系3.json
Normal file
150
dataRender/人企关系3.json
Normal file
@ -0,0 +1,150 @@
|
||||
{
|
||||
"msg": "查询成功",
|
||||
"code": "0000",
|
||||
"orderNo": "20241113214538120270654",
|
||||
"data": {
|
||||
"total": 4,
|
||||
"datalist": [
|
||||
{
|
||||
"orgName": "厦门市湖里区肖山泗建材店",
|
||||
"pName": "李金桂",
|
||||
"relationship": [
|
||||
"lp"
|
||||
],
|
||||
"fsource": "1",
|
||||
"basicInfo": {
|
||||
"regStatus": "吊销,未注销",
|
||||
"regCapital": "",
|
||||
"reccap": 0,
|
||||
"city": "厦门市",
|
||||
"industry_code": "F",
|
||||
"industry": "批发业",
|
||||
"type": "1",
|
||||
"nic_code": "F516",
|
||||
"legalPersonName": "李金桂",
|
||||
"regNumber": "350206800393889",
|
||||
"creditCode": "92350206MA3212DY6N",
|
||||
"province": "福建省",
|
||||
"regorg": "厦门市湖里区市场监督管理局",
|
||||
"companyOrgType": "个体",
|
||||
"revdate": "2024-09-06",
|
||||
"estiblishTime": "2018-08-21",
|
||||
"opscope": "",
|
||||
"reccapcur": "人民币",
|
||||
"regCapitalCurrency": "人民币",
|
||||
"nic_name": "批发和零售业-批发业-矿产品、建材及化工产品批发",
|
||||
"candate": "",
|
||||
"district": "湖里区",
|
||||
"name": "厦门市湖里区肖山泗建材店",
|
||||
"base": "fj",
|
||||
"apprdate": "2018-08-21"
|
||||
}
|
||||
},
|
||||
{
|
||||
"orgName": "南安市仑苍巢李水暖配件店",
|
||||
"pName": "李金桂",
|
||||
"relationship": [
|
||||
"lp"
|
||||
],
|
||||
"fsource": "1",
|
||||
"basicInfo": {
|
||||
"regStatus": "存续(在营、开业、在册)",
|
||||
"regCapital": "",
|
||||
"reccap": 0,
|
||||
"city": "泉州市",
|
||||
"industry_code": "F",
|
||||
"industry": "零售业",
|
||||
"type": "1",
|
||||
"nic_code": "F5281",
|
||||
"legalPersonName": "李金桂",
|
||||
"regNumber": "350583601550067",
|
||||
"creditCode": "92350583MA34MA8K8Y",
|
||||
"province": "福建省",
|
||||
"regorg": "福建省南安市市场监督管理局",
|
||||
"companyOrgType": "个体",
|
||||
"revdate": "",
|
||||
"estiblishTime": "2020-09-08",
|
||||
"opscope": "",
|
||||
"reccapcur": "人民币",
|
||||
"regCapitalCurrency": "人民币",
|
||||
"nic_name": "批发和零售业-零售业-五金、家具及室内装饰材料专门零售-五金零售",
|
||||
"candate": "",
|
||||
"district": "南安市",
|
||||
"name": "南安市仑苍巢李水暖配件店",
|
||||
"base": "fj",
|
||||
"apprdate": "2021-03-22"
|
||||
}
|
||||
},
|
||||
{
|
||||
"orgName": "厦门市湖里区苑熙照建材店",
|
||||
"pName": "李金桂",
|
||||
"relationship": [
|
||||
"lp"
|
||||
],
|
||||
"fsource": "1",
|
||||
"basicInfo": {
|
||||
"regStatus": "吊销,未注销",
|
||||
"regCapital": "",
|
||||
"reccap": 0,
|
||||
"city": "厦门市",
|
||||
"industry_code": "F",
|
||||
"industry": "零售业",
|
||||
"type": "1",
|
||||
"nic_code": "F528",
|
||||
"legalPersonName": "李金桂",
|
||||
"regNumber": "350206800392843",
|
||||
"creditCode": "92350206MA320UEM5W",
|
||||
"province": "福建省",
|
||||
"regorg": "厦门市湖里区市场监督管理局",
|
||||
"companyOrgType": "个体",
|
||||
"revdate": "2024-09-06",
|
||||
"estiblishTime": "2018-08-17",
|
||||
"opscope": "",
|
||||
"reccapcur": "人民币",
|
||||
"regCapitalCurrency": "人民币",
|
||||
"nic_name": "批发和零售业-零售业-五金、家具及室内装饰材料专门零售",
|
||||
"candate": "",
|
||||
"district": "湖里区",
|
||||
"name": "厦门市湖里区苑熙照建材店",
|
||||
"base": "fj",
|
||||
"apprdate": "2018-08-17"
|
||||
}
|
||||
},
|
||||
{
|
||||
"orgName": "厦门市湖里区镜永捷亦服饰店",
|
||||
"pName": "李金桂",
|
||||
"relationship": [
|
||||
"lp"
|
||||
],
|
||||
"fsource": "1",
|
||||
"basicInfo": {
|
||||
"regStatus": "吊销,未注销",
|
||||
"regCapital": "",
|
||||
"reccap": 0,
|
||||
"city": "厦门市",
|
||||
"industry_code": "F",
|
||||
"industry": "零售业",
|
||||
"type": "1",
|
||||
"nic_code": "F523",
|
||||
"legalPersonName": "李金桂",
|
||||
"regNumber": "350206800389905",
|
||||
"creditCode": "92350206MA320JJ58B",
|
||||
"province": "福建省",
|
||||
"regorg": "厦门市湖里区市场监督管理局",
|
||||
"companyOrgType": "个体",
|
||||
"revdate": "2024-09-06",
|
||||
"estiblishTime": "2018-08-15",
|
||||
"opscope": "",
|
||||
"reccapcur": "人民币",
|
||||
"regCapitalCurrency": "人民币",
|
||||
"nic_name": "批发和零售业-零售业-纺织、服装及日用品专门零售",
|
||||
"candate": "",
|
||||
"district": "湖里区",
|
||||
"name": "厦门市湖里区镜永捷亦服饰店",
|
||||
"base": "fj",
|
||||
"apprdate": "2018-08-15"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
154
dataRender/借贷意向1.json
Normal file
154
dataRender/借贷意向1.json
Normal file
@ -0,0 +1,154 @@
|
||||
{
|
||||
"als_fst_cell_nbank_inteday": "290",
|
||||
"als_fst_id_nbank_inteday": "138",
|
||||
"als_lst_cell_nbank_consnum": "1",
|
||||
"als_lst_cell_nbank_csinteday": "1",
|
||||
"als_lst_cell_nbank_inteday": "33",
|
||||
"als_lst_id_nbank_consnum": "1",
|
||||
"als_lst_id_nbank_csinteday": "1",
|
||||
"als_lst_id_nbank_inteday": "94",
|
||||
"als_m12_cell_avg_monnum": "1.20",
|
||||
"als_m12_cell_caon_allnum": "2",
|
||||
"als_m12_cell_caon_orgnum": "1",
|
||||
"als_m12_cell_max_inteday": "128",
|
||||
"als_m12_cell_max_monnum": "2",
|
||||
"als_m12_cell_min_inteday": "14",
|
||||
"als_m12_cell_min_monnum": "0",
|
||||
"als_m12_cell_nbank_allnum": "6",
|
||||
"als_m12_cell_nbank_avg_monnum": "1.20",
|
||||
"als_m12_cell_nbank_ca_allnum": "2",
|
||||
"als_m12_cell_nbank_ca_orgnum": "1",
|
||||
"als_m12_cell_nbank_cf_allnum": "4",
|
||||
"als_m12_cell_nbank_cf_orgnum": "1",
|
||||
"als_m12_cell_nbank_max_inteday": "128",
|
||||
"als_m12_cell_nbank_max_monnum": "2",
|
||||
"als_m12_cell_nbank_min_inteday": "14",
|
||||
"als_m12_cell_nbank_min_monnum": "0",
|
||||
"als_m12_cell_nbank_night_allnum": "1",
|
||||
"als_m12_cell_nbank_night_orgnum": "1",
|
||||
"als_m12_cell_nbank_orgnum": "2",
|
||||
"als_m12_cell_nbank_selfnum": "0",
|
||||
"als_m12_cell_nbank_sloan_allnum": "6",
|
||||
"als_m12_cell_nbank_sloan_orgnum": "2",
|
||||
"als_m12_cell_nbank_tot_mons": "5",
|
||||
"als_m12_cell_nbank_week_allnum": "2",
|
||||
"als_m12_cell_nbank_week_orgnum": "2",
|
||||
"als_m12_cell_rel_allnum": "4",
|
||||
"als_m12_cell_rel_orgnum": "1",
|
||||
"als_m12_cell_tot_mons": "5",
|
||||
"als_m12_id_avg_monnum": "1.00",
|
||||
"als_m12_id_caon_allnum": "2",
|
||||
"als_m12_id_caon_orgnum": "2",
|
||||
"als_m12_id_max_inteday": "44",
|
||||
"als_m12_id_max_monnum": "1",
|
||||
"als_m12_id_min_inteday": "44",
|
||||
"als_m12_id_min_monnum": "0",
|
||||
"als_m12_id_nbank_allnum": "2",
|
||||
"als_m12_id_nbank_avg_monnum": "1.00",
|
||||
"als_m12_id_nbank_ca_allnum": "1",
|
||||
"als_m12_id_nbank_ca_orgnum": "1",
|
||||
"als_m12_id_nbank_max_inteday": "44",
|
||||
"als_m12_id_nbank_max_monnum": "1",
|
||||
"als_m12_id_nbank_min_inteday": "44",
|
||||
"als_m12_id_nbank_min_monnum": "0",
|
||||
"als_m12_id_nbank_night_allnum": "0",
|
||||
"als_m12_id_nbank_night_orgnum": "0",
|
||||
"als_m12_id_nbank_nsloan_allnum": "1",
|
||||
"als_m12_id_nbank_nsloan_orgnum": "1",
|
||||
"als_m12_id_nbank_orgnum": "2",
|
||||
"als_m12_id_nbank_oth_allnum": "1",
|
||||
"als_m12_id_nbank_oth_orgnum": "1",
|
||||
"als_m12_id_nbank_selfnum": "0",
|
||||
"als_m12_id_nbank_sloan_allnum": "1",
|
||||
"als_m12_id_nbank_sloan_orgnum": "1",
|
||||
"als_m12_id_nbank_tot_mons": "2",
|
||||
"als_m12_id_nbank_week_allnum": "0",
|
||||
"als_m12_id_nbank_week_orgnum": "0",
|
||||
"als_m12_id_tot_mons": "2",
|
||||
"als_m3_cell_avg_monnum": "1.00",
|
||||
"als_m3_cell_max_inteday": "31",
|
||||
"als_m3_cell_max_monnum": "1",
|
||||
"als_m3_cell_min_inteday": "31",
|
||||
"als_m3_cell_min_monnum": "0",
|
||||
"als_m3_cell_nbank_allnum": "2",
|
||||
"als_m3_cell_nbank_avg_monnum": "1.00",
|
||||
"als_m3_cell_nbank_cf_allnum": "2",
|
||||
"als_m3_cell_nbank_cf_orgnum": "1",
|
||||
"als_m3_cell_nbank_max_inteday": "31",
|
||||
"als_m3_cell_nbank_max_monnum": "1",
|
||||
"als_m3_cell_nbank_min_inteday": "31",
|
||||
"als_m3_cell_nbank_min_monnum": "0",
|
||||
"als_m3_cell_nbank_night_allnum": "1",
|
||||
"als_m3_cell_nbank_night_orgnum": "1",
|
||||
"als_m3_cell_nbank_orgnum": "1",
|
||||
"als_m3_cell_nbank_selfnum": "0",
|
||||
"als_m3_cell_nbank_sloan_allnum": "2",
|
||||
"als_m3_cell_nbank_sloan_orgnum": "1",
|
||||
"als_m3_cell_nbank_tot_mons": "2",
|
||||
"als_m3_cell_nbank_week_allnum": "1",
|
||||
"als_m3_cell_nbank_week_orgnum": "1",
|
||||
"als_m3_cell_rel_allnum": "2",
|
||||
"als_m3_cell_rel_orgnum": "1",
|
||||
"als_m3_cell_tot_mons": "2",
|
||||
"als_m6_cell_avg_monnum": "1.00",
|
||||
"als_m6_cell_caon_allnum": "2",
|
||||
"als_m6_cell_caon_orgnum": "1",
|
||||
"als_m6_cell_max_inteday": "46",
|
||||
"als_m6_cell_max_monnum": "1",
|
||||
"als_m6_cell_min_inteday": "31",
|
||||
"als_m6_cell_min_monnum": "0",
|
||||
"als_m6_cell_nbank_allnum": "4",
|
||||
"als_m6_cell_nbank_avg_monnum": "1.00",
|
||||
"als_m6_cell_nbank_ca_allnum": "2",
|
||||
"als_m6_cell_nbank_ca_orgnum": "1",
|
||||
"als_m6_cell_nbank_cf_allnum": "2",
|
||||
"als_m6_cell_nbank_cf_orgnum": "1",
|
||||
"als_m6_cell_nbank_max_inteday": "46",
|
||||
"als_m6_cell_nbank_max_monnum": "1",
|
||||
"als_m6_cell_nbank_min_inteday": "31",
|
||||
"als_m6_cell_nbank_min_monnum": "0",
|
||||
"als_m6_cell_nbank_night_allnum": "1",
|
||||
"als_m6_cell_nbank_night_orgnum": "1",
|
||||
"als_m6_cell_nbank_orgnum": "2",
|
||||
"als_m6_cell_nbank_selfnum": "0",
|
||||
"als_m6_cell_nbank_sloan_allnum": "4",
|
||||
"als_m6_cell_nbank_sloan_orgnum": "2",
|
||||
"als_m6_cell_nbank_tot_mons": "4",
|
||||
"als_m6_cell_nbank_week_allnum": "2",
|
||||
"als_m6_cell_nbank_week_orgnum": "2",
|
||||
"als_m6_cell_rel_allnum": "2",
|
||||
"als_m6_cell_rel_orgnum": "1",
|
||||
"als_m6_cell_tot_mons": "4",
|
||||
"als_m6_id_avg_monnum": "1.00",
|
||||
"als_m6_id_caon_allnum": "2",
|
||||
"als_m6_id_caon_orgnum": "2",
|
||||
"als_m6_id_max_inteday": "44",
|
||||
"als_m6_id_max_monnum": "1",
|
||||
"als_m6_id_min_inteday": "44",
|
||||
"als_m6_id_min_monnum": "0",
|
||||
"als_m6_id_nbank_allnum": "2",
|
||||
"als_m6_id_nbank_avg_monnum": "1.00",
|
||||
"als_m6_id_nbank_ca_allnum": "1",
|
||||
"als_m6_id_nbank_ca_orgnum": "1",
|
||||
"als_m6_id_nbank_max_inteday": "44",
|
||||
"als_m6_id_nbank_max_monnum": "1",
|
||||
"als_m6_id_nbank_min_inteday": "44",
|
||||
"als_m6_id_nbank_min_monnum": "0",
|
||||
"als_m6_id_nbank_night_allnum": "0",
|
||||
"als_m6_id_nbank_night_orgnum": "0",
|
||||
"als_m6_id_nbank_nsloan_allnum": "1",
|
||||
"als_m6_id_nbank_nsloan_orgnum": "1",
|
||||
"als_m6_id_nbank_orgnum": "2",
|
||||
"als_m6_id_nbank_oth_allnum": "1",
|
||||
"als_m6_id_nbank_oth_orgnum": "1",
|
||||
"als_m6_id_nbank_selfnum": "0",
|
||||
"als_m6_id_nbank_sloan_allnum": "1",
|
||||
"als_m6_id_nbank_sloan_orgnum": "1",
|
||||
"als_m6_id_nbank_tot_mons": "2",
|
||||
"als_m6_id_nbank_week_allnum": "0",
|
||||
"als_m6_id_nbank_week_orgnum": "0",
|
||||
"als_m6_id_tot_mons": "2",
|
||||
"code": "00",
|
||||
"flag_applyloanstr": "1",
|
||||
"flag_datastrategy": "1"
|
||||
}
|
133
dataRender/借贷行为1.json
Normal file
133
dataRender/借贷行为1.json
Normal file
@ -0,0 +1,133 @@
|
||||
{
|
||||
"code": "00",
|
||||
"data": {
|
||||
"tl_id_t11_nbank_org": "1",
|
||||
"tl_id_m6_nbank_passnum": "2",
|
||||
"tl_cell_t2_nbank_lendamt": "10",
|
||||
"tl_cell_t5_nbank_org": "1",
|
||||
"tl_id_t5_nbank_num": "1",
|
||||
"tl_id_t0_nbank_org": "1",
|
||||
"tl_cell_t9_nbank_num": "1",
|
||||
"tl_id_t7_nbank_org": "1",
|
||||
"tl_id_m1_nbank_passlendamt": "5",
|
||||
"tl_cell_m9_nbank_passnum": "2",
|
||||
"flag_datastrategy": "1",
|
||||
"tl_cell_m6_nbank_passorg": "1",
|
||||
"tl_cell_m1_nbank_passorg": "1",
|
||||
"tl_id_m12_nbank_passorg": "1",
|
||||
"tl_id_m3_nbank_passnum": "1",
|
||||
"DataStrategy": {
|
||||
"strategy_version": "1.0",
|
||||
"product_type": "",
|
||||
"strategy_id": "DTA_BR0008250",
|
||||
"product_name": "预置_借贷行为验证",
|
||||
"scene": "lend"
|
||||
},
|
||||
"tl_id_t6_nbank_lendamt": "9",
|
||||
"tl_id_t6_nbank_org": "1",
|
||||
"tl_cell_m12_nbank_passlendamt": "18",
|
||||
"tl_cell_m3_nbank_passlendamt": "9",
|
||||
"tl_cell_t7_nbank_lendamt": "9",
|
||||
"tl_cell_m12_nbank_passnum": "2",
|
||||
"tl_cell_t2_nbank_num": "2",
|
||||
"tl_cell_t6_nbank_org": "1",
|
||||
"tl_cell_t11_nbank_num": "1",
|
||||
"tl_id_m3_nbank_passlendamt": "9",
|
||||
"tl_cell_m6_nbank_passnum": "2",
|
||||
"tl_id_t7_nbank_lendamt": "9",
|
||||
"tl_cell_t11_nbank_org": "1",
|
||||
"tl_id_m3_nbank_passorg": "1",
|
||||
"tl_cell_t8_nbank_num": "1",
|
||||
"tl_id_t6_nbank_num": "1",
|
||||
"tl_cell_m12_nbank_passorg": "1",
|
||||
"tl_id_t6_nbank_reamt": "3",
|
||||
"tl_id_t7_nbank_reamt": "3",
|
||||
"tl_id_t3_nbank_num": "2",
|
||||
"tl_cell_t8_nbank_lendamt": "9",
|
||||
"tl_id_t9_nbank_org": "1",
|
||||
"tl_id_t1_nbank_lendamt": "14",
|
||||
"tl_cell_t7_nbank_org": "1",
|
||||
"tl_id_t9_nbank_reamt": "3",
|
||||
"tl_id_t8_nbank_reamt": "3",
|
||||
"tl_id_t1_nbank_org": "1",
|
||||
"tl_cell_t3_nbank_num": "2",
|
||||
"tl_id_t8_nbank_lendamt": "9",
|
||||
"tl_cell_t11_nbank_lendamt": "5",
|
||||
"tl_cell_m3_nbank_passorg": "1",
|
||||
"tl_id_t0_nbank_num": "2",
|
||||
"tl_cell_t4_nbank_org": "1",
|
||||
"tl_cell_t0_nbank_num": "2",
|
||||
"tl_id_t0_nbank_lendamt": "18",
|
||||
"tl_cell_t1_nbank_org": "1",
|
||||
"tl_id_t9_nbank_lendamt": "9",
|
||||
"tl_cell_t9_nbank_lendamt": "9",
|
||||
"tl_cell_t0_nbank_lendamt": "18",
|
||||
"tl_id_t1_nbank_num": "2",
|
||||
"tl_cell_t0_nbank_reamt": "7",
|
||||
"tl_cell_t1_nbank_reamt": "7",
|
||||
"tl_id_t5_nbank_lendamt": "9",
|
||||
"tl_cell_m3_nbank_passnum": "1",
|
||||
"tl_id_m6_nbank_passlendamt": "10",
|
||||
"tl_cell_t6_nbank_lendamt": "9",
|
||||
"tl_id_m1_nbank_passorg": "1",
|
||||
"tl_cell_t6_nbank_num": "1",
|
||||
"tl_id_t8_nbank_num": "1",
|
||||
"tl_id_t4_nbank_org": "1",
|
||||
"tl_cell_t1_nbank_lendamt": "14",
|
||||
"tl_cell_t2_nbank_org": "1",
|
||||
"tl_cell_t3_nbank_lendamt": "10",
|
||||
"tl_id_t2_nbank_num": "2",
|
||||
"tl_cell_t5_nbank_num": "1",
|
||||
"swift_number": "3034309_20241113153507_46522614A19",
|
||||
"tl_id_t5_nbank_reamt": "3",
|
||||
"tl_cell_t7_nbank_reamt": "3",
|
||||
"tl_cell_t9_nbank_org": "1",
|
||||
"tl_cell_t9_nbank_reamt": "3",
|
||||
"tl_id_t4_nbank_reamt": "3",
|
||||
"tl_id_t3_nbank_reamt": "4",
|
||||
"tl_cell_t8_nbank_reamt": "3",
|
||||
"tl_cell_t4_nbank_reamt": "3",
|
||||
"tl_id_t1_nbank_reamt": "7",
|
||||
"tl_id_t2_nbank_reamt": "4",
|
||||
"tl_cell_t5_nbank_reamt": "3",
|
||||
"tl_cell_t3_nbank_reamt": "4",
|
||||
"tl_cell_t6_nbank_reamt": "3",
|
||||
"tl_cell_m9_nbank_passorg": "1",
|
||||
"tl_cell_t2_nbank_reamt": "4",
|
||||
"tl_cell_m9_nbank_passlendamt": "10",
|
||||
"tl_id_m12_nbank_passlendamt": "18",
|
||||
"tl_id_t9_nbank_num": "1",
|
||||
"tl_id_m9_nbank_passorg": "1",
|
||||
"tl_id_t0_nbank_reamt": "7",
|
||||
"tl_id_t2_nbank_lendamt": "10",
|
||||
"tl_id_t3_nbank_org": "1",
|
||||
"tl_cell_t4_nbank_num": "1",
|
||||
"tl_cell_t3_nbank_org": "1",
|
||||
"tl_cell_m1_nbank_passnum": "1",
|
||||
"code": "00",
|
||||
"tl_id_t2_nbank_org": "1",
|
||||
"tl_id_m12_nbank_passnum": "2",
|
||||
"tl_cell_t4_nbank_lendamt": "9",
|
||||
"tl_id_m9_nbank_passlendamt": "10",
|
||||
"tl_cell_t0_nbank_org": "1",
|
||||
"tl_id_m9_nbank_passnum": "2",
|
||||
"tl_id_t3_nbank_lendamt": "10",
|
||||
"tl_cell_m1_nbank_passlendamt": "5",
|
||||
"tl_cell_t1_nbank_num": "2",
|
||||
"tl_id_m6_nbank_passorg": "1",
|
||||
"tl_id_t11_nbank_lendamt": "5",
|
||||
"tl_id_t11_nbank_num": "1",
|
||||
"tl_cell_t5_nbank_lendamt": "9",
|
||||
"tl_id_t5_nbank_org": "1",
|
||||
"tl_id_t4_nbank_lendamt": "9",
|
||||
"tl_cell_t8_nbank_org": "1",
|
||||
"tl_id_t7_nbank_num": "1",
|
||||
"tl_cell_m6_nbank_passlendamt": "10",
|
||||
"tl_id_t4_nbank_num": "1",
|
||||
"tl_id_m1_nbank_passnum": "1",
|
||||
"tl_id_t8_nbank_org": "1",
|
||||
"tl_cell_t7_nbank_num": "1",
|
||||
"flag_totalloan": "1"
|
||||
},
|
||||
"flag_totalloan": "1"
|
||||
}
|
17
dataRender/特殊名单1.json
Normal file
17
dataRender/特殊名单1.json
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"code": "100002",
|
||||
"flag_specialList_c": "0",
|
||||
"data": {
|
||||
"code": "100002",
|
||||
"flag_specialList_c": "0",
|
||||
"swift_number": "3034309_20241113140028_45772614A19",
|
||||
"flag_datastrategy": "0",
|
||||
"DataStrategy": {
|
||||
"strategy_version": "1.0",
|
||||
"product_type": "100099",
|
||||
"strategy_id": "DTA_BR0007511",
|
||||
"product_name": "预置_特殊名单验证",
|
||||
"scene": "lend"
|
||||
}
|
||||
}
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
# 环境变量配置说明
|
||||
|
||||
## 环境变量文件
|
||||
|
||||
本项目使用 Vite 的环境变量功能,支持以下环境变量文件:
|
||||
|
||||
- `.env`:所有环境都会加载的默认变量
|
||||
- `.env.development`:开发环境变量(`npm run dev` 时加载)
|
||||
- `.env.production`:生产环境变量(`npm run build` 时加载)
|
||||
|
||||
## 已配置的环境变量
|
||||
|
||||
| 变量名 | 说明 | 示例值 |
|
||||
|--------|------|--------|
|
||||
| VITE_APP_BASE_URL | API 基础URL | https://www.quannengcha.com |
|
||||
| VITE_APP_DEBUG | 调试模式 | true/false |
|
||||
|
||||
## 在项目中使用环境变量
|
||||
|
||||
### 在 Vue 组件中使用
|
||||
|
||||
```vue
|
||||
<script setup>
|
||||
// 使用 import.meta.env 访问环境变量
|
||||
const baseUrl = import.meta.env.VITE_APP_BASE_URL
|
||||
const isDebug = import.meta.env.VITE_APP_DEBUG === 'true'
|
||||
</script>
|
||||
```
|
||||
|
||||
### 在 JS/TS 文件中使用
|
||||
|
||||
```js
|
||||
// 使用 import.meta.env 访问环境变量
|
||||
const baseUrl = import.meta.env.VITE_APP_BASE_URL
|
||||
const isDebug = import.meta.env.VITE_APP_DEBUG === 'true'
|
||||
|
||||
// 获取当前环境模式
|
||||
const mode = import.meta.env.MODE
|
||||
```
|
||||
|
||||
## 获取当前环境
|
||||
|
||||
```js
|
||||
// 获取当前环境模式(development、production等)
|
||||
const mode = import.meta.env.MODE
|
||||
```
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. 所有环境变量必须以 `VITE_` 开头才能在客户端代码中访问
|
||||
2. 环境变量默认为字符串类型,需要自行转换为其他类型(如布尔值)
|
||||
3. 修改环境变量后需要重启开发服务器才能生效
|
||||
4. 不要在环境变量文件中存储敏感信息,如API密钥等
|
15
eslint.config.mjs
Normal file
15
eslint.config.mjs
Normal file
@ -0,0 +1,15 @@
|
||||
import uni from '@uni-helper/eslint-config'
|
||||
|
||||
export default uni(
|
||||
{
|
||||
globals: {
|
||||
uni: true,
|
||||
wx: true, // 如果您同时使用了微信小程序的全局变量
|
||||
},
|
||||
unocss: true,
|
||||
rules: {
|
||||
'no-console': 'off', // 关闭 no-console 规则
|
||||
'no-unused-vars': 'warn',
|
||||
},
|
||||
},
|
||||
)
|
@ -26,7 +26,6 @@ export default defineManifestConfig({
|
||||
/* 模块配置 */
|
||||
modules: {
|
||||
Payment: {},
|
||||
Share: {},
|
||||
},
|
||||
/* 应用发布信息 */
|
||||
distribute: {
|
||||
@ -61,19 +60,6 @@ export default defineManifestConfig({
|
||||
// #endif
|
||||
|
||||
},
|
||||
// share: {
|
||||
// weixin: {
|
||||
// appid: 'wx开头的微信开放平台AppID',
|
||||
// UniversalLinks: 'https://www.quannengcha.com/app/',
|
||||
// }
|
||||
// },
|
||||
// oauth: {
|
||||
// weixin: {
|
||||
// appid: 'wx开头的微信开放平台AppID',
|
||||
// appsecret: '微信开放平台AppSecret',
|
||||
// UniversalLinks: 'https://www.quannengcha.com/app/'
|
||||
// }
|
||||
// }
|
||||
},
|
||||
icons: {
|
||||
android: {
|
||||
@ -138,24 +124,4 @@ export default defineManifestConfig({
|
||||
enable: false,
|
||||
},
|
||||
'vueVersion': '3',
|
||||
|
||||
/* UTS 插件配置 */
|
||||
'uts': {
|
||||
'plugins': {
|
||||
'webview': {
|
||||
'version': '1.0.0',
|
||||
'description': 'Web视图插件,支持在App内打开网页',
|
||||
'platforms': {
|
||||
'android': {
|
||||
'appid': '__UNI_WEBVIEW_ANDROID',
|
||||
'autostart': false
|
||||
},
|
||||
'ios': {
|
||||
'appid': '__UNI_WEBVIEW_IOS',
|
||||
'autostart': false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
52
package.json
52
package.json
@ -41,43 +41,39 @@
|
||||
"build:quickapp-webview": "uni build -p quickapp-webview",
|
||||
"build:quickapp-webview-huawei": "uni build -p quickapp-webview-huawei",
|
||||
"build:quickapp-webview-union": "uni build -p quickapp-webview-union",
|
||||
"type-check": "vue-tsc --noEmit"
|
||||
"type-check": "vue-tsc --noEmit",
|
||||
"lint": "eslint .",
|
||||
"lint:fix": "eslint . --fix"
|
||||
},
|
||||
"dependencies": {
|
||||
"@dcloudio/uni-app": "3.0.0-4050520250307001",
|
||||
"@dcloudio/uni-app-harmony": "3.0.0-4050520250307001",
|
||||
"@dcloudio/uni-app-plus": "3.0.0-4050520250307001",
|
||||
"@dcloudio/uni-components": "3.0.0-4050520250307001",
|
||||
"@dcloudio/uni-h5": "3.0.0-4050520250307001",
|
||||
"@dcloudio/uni-mp-alipay": "3.0.0-4050520250307001",
|
||||
"@dcloudio/uni-mp-baidu": "3.0.0-4050520250307001",
|
||||
"@dcloudio/uni-mp-jd": "3.0.0-4050520250307001",
|
||||
"@dcloudio/uni-mp-kuaishou": "3.0.0-4050520250307001",
|
||||
"@dcloudio/uni-mp-lark": "3.0.0-4050520250307001",
|
||||
"@dcloudio/uni-mp-qq": "3.0.0-4050520250307001",
|
||||
"@dcloudio/uni-mp-toutiao": "3.0.0-4050520250307001",
|
||||
"@dcloudio/uni-mp-weixin": "3.0.0-4050520250307001",
|
||||
"@dcloudio/uni-mp-xhs": "3.0.0-4050520250307001",
|
||||
"@dcloudio/uni-quickapp-webview": "3.0.0-4050520250307001",
|
||||
"@dcloudio/uni-app": "3.0.0-4020420240722002",
|
||||
"@dcloudio/uni-app-plus": "3.0.0-4020420240722002",
|
||||
"@dcloudio/uni-components": "3.0.0-4020420240722002",
|
||||
"@dcloudio/uni-h5": "3.0.0-4020420240722002",
|
||||
"@dcloudio/uni-mp-alipay": "3.0.0-4020420240722002",
|
||||
"@dcloudio/uni-mp-baidu": "3.0.0-4020420240722002",
|
||||
"@dcloudio/uni-mp-jd": "3.0.0-4020420240722002",
|
||||
"@dcloudio/uni-mp-kuaishou": "3.0.0-4020420240722002",
|
||||
"@dcloudio/uni-mp-lark": "3.0.0-4020420240722002",
|
||||
"@dcloudio/uni-mp-qq": "3.0.0-4020420240722002",
|
||||
"@dcloudio/uni-mp-toutiao": "3.0.0-4020420240722002",
|
||||
"@dcloudio/uni-mp-weixin": "3.0.0-4020420240722002",
|
||||
"@dcloudio/uni-mp-xhs": "3.0.0-4020420240722002",
|
||||
"@dcloudio/uni-quickapp-webview": "3.0.0-4020420240722002",
|
||||
"@rollup/rollup-win32-x64-msvc": "^4.27.4",
|
||||
"@vant/area-data": "^2.0.0",
|
||||
"@vueuse/core": "^11.1.0",
|
||||
"crypto-js": "^4.2.0",
|
||||
"pinia": "^3.0.1",
|
||||
"qrcode": "^1.5.4",
|
||||
"uqrcodejs": "^4.0.7",
|
||||
"vue": "~3.4.21",
|
||||
"vue-i18n": "^9.14.1",
|
||||
"wot-design-uni": "^1.3.12"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@dcloudio/types": "^3.4.14",
|
||||
"@dcloudio/uni-automator": "3.0.0-4050520250307001",
|
||||
"@dcloudio/uni-cli-shared": "3.0.0-4050520250307001",
|
||||
"@dcloudio/uni-stacktracey": "3.0.0-4050520250307001",
|
||||
"@dcloudio/uni-uts-v1": "3.0.0-4050520250307001",
|
||||
"@dcloudio/types": "^3.4.12",
|
||||
"@dcloudio/uni-automator": "3.0.0-4020420240722002",
|
||||
"@dcloudio/uni-cli-shared": "3.0.0-4020420240722002",
|
||||
"@dcloudio/uni-stacktracey": "3.0.0-4020420240722002",
|
||||
"@dcloudio/uni-vue-devtools": "3.0.0-4020420240722002",
|
||||
"@dcloudio/vite-plugin-uni": "3.0.0-4050520250307001",
|
||||
"@dcloudio/vite-plugin-uni": "3.0.0-4020420240722002",
|
||||
"@iconify-json/carbon": "^1.2.3",
|
||||
"@mini-types/alipay": "^3.0.14",
|
||||
"@types/node": "^20.16.12",
|
||||
@ -93,14 +89,14 @@
|
||||
"@unocss/eslint-config": "^0.62.4",
|
||||
"@vue/runtime-core": "^3.5.12",
|
||||
"@vue/tsconfig": "^0.5.1",
|
||||
"eslint": "^9.12.0",
|
||||
"miniprogram-api-typings": "^3.12.3",
|
||||
"sass": "~1.79.0",
|
||||
"sass-embedded": "~1.79.0",
|
||||
"typescript": "~5.5.4",
|
||||
"unocss": "^0.62.4",
|
||||
"unplugin-auto-import": "^0.18.3",
|
||||
"unplugin-vue-components": "^28.4.1",
|
||||
"vite": "^5.2.8",
|
||||
"vite": "^5.4.9",
|
||||
"vue-tsc": "^2.1.6"
|
||||
}
|
||||
}
|
||||
|
@ -24,11 +24,6 @@ export default defineUniPages({
|
||||
text: '',
|
||||
visible: false,
|
||||
},
|
||||
{
|
||||
pagePath: 'pages/agent',
|
||||
text: '',
|
||||
visible: false,
|
||||
},
|
||||
{
|
||||
pagePath: 'pages/ai',
|
||||
text: '',
|
||||
|
1671
pnpm-lock.yaml
1671
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
84
src/App.vue
84
src/App.vue
@ -1,88 +1,4 @@
|
||||
<script setup>
|
||||
import { onLaunch } from '@dcloudio/uni-app'
|
||||
import { refreshToken, getUserInfo } from '@/api/apis'
|
||||
import { getAgentInfo } from '@/apis/agent'
|
||||
|
||||
onLaunch(() => {
|
||||
refreshTokenIfNeeded()
|
||||
getUser()
|
||||
getAgentInformation()
|
||||
})
|
||||
|
||||
|
||||
const refreshTokenIfNeeded = async () => {
|
||||
const token = uni.getStorageSync("token")
|
||||
const refreshAfter = uni.getStorageSync("refreshAfter")
|
||||
const accessExpire = uni.getStorageSync("accessExpire")
|
||||
const currentTime = new Date().getTime()
|
||||
|
||||
// 如果 token 已过期,直接返回
|
||||
if (accessExpire) {
|
||||
const accessExpireInMilliseconds = parseInt(accessExpire) * 1000 // 转换为毫秒级
|
||||
if (currentTime > accessExpireInMilliseconds) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 如果没有 token,直接返回
|
||||
if (!token) {
|
||||
return
|
||||
}
|
||||
|
||||
// 如果有 refreshAfter,检查当前时间是否超过 refreshAfter
|
||||
if (refreshAfter) {
|
||||
const refreshAfterInMilliseconds = parseInt(refreshAfter) * 1000 // 转换为毫秒级
|
||||
if (currentTime < refreshAfterInMilliseconds) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 如果没有 refreshAfter 或者时间超过 refreshAfter,执行刷新 token 的请求
|
||||
try {
|
||||
const res = await refreshToken()
|
||||
if (res.code === 200) {
|
||||
uni.setStorageSync("token", res.data.accessToken)
|
||||
uni.setStorageSync("refreshAfter", res.data.refreshAfter)
|
||||
uni.setStorageSync("accessExpire", res.data.accessExpire)
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('刷新token失败', error)
|
||||
}
|
||||
}
|
||||
const getAgentInformation = async () => {
|
||||
const token = uni.getStorageSync("token")
|
||||
if (!token) {
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
const res = await getAgentInfo()
|
||||
if (res.code === 200 && res.data) {
|
||||
// 将代理信息存入缓存
|
||||
uni.setStorageSync("agentInfo", {
|
||||
level: res.data.level,
|
||||
isAgent: res.data.is_agent, // 判断是否是代理
|
||||
status: res.data.status, // 获取代理状态 0=待审核,1=审核通过,2=审核未通过,3=未申请
|
||||
agentID: res.data.agent_id,
|
||||
mobile: res.data.mobile
|
||||
})
|
||||
|
||||
console.log('代理信息已获取并存入缓存')
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取代理信息失败', error)
|
||||
}
|
||||
}
|
||||
|
||||
const getUser = async () => {
|
||||
const token = uni.getStorageSync("token")
|
||||
if (!token) {
|
||||
return
|
||||
}
|
||||
const res = await getUserInfo()
|
||||
if (res.code === 200) {
|
||||
console.log(res.data)
|
||||
uni.setStorageSync("userInfo", res.data.userInfo)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -119,17 +119,3 @@ export function iapPaymentCallback(data) {
|
||||
data,
|
||||
})
|
||||
}
|
||||
export function getAgentRevenue() {
|
||||
return request({
|
||||
url: '/agent/revenue',
|
||||
method: 'GET'
|
||||
})
|
||||
}
|
||||
export function refreshToken() {
|
||||
return request({
|
||||
url: '/user/getToken',
|
||||
method: 'POST',
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,138 +0,0 @@
|
||||
// 代理相关API
|
||||
import request from '@/utils/request'
|
||||
|
||||
/**
|
||||
* 获取代理信息
|
||||
*/
|
||||
export const getAgentInfo = () => {
|
||||
return request({
|
||||
url: '/agent/info',
|
||||
method: 'GET'
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取代理佣金列表
|
||||
* @param {Object} params 查询参数 {page, page_size}
|
||||
*/
|
||||
export const getAgentCommission = (params) => {
|
||||
return request({
|
||||
url: '/agent/commission',
|
||||
method: 'GET',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取代理奖励列表
|
||||
* @param {Object} params 查询参数 {page, page_size}
|
||||
*/
|
||||
export const getAgentRewards = (params) => {
|
||||
return request({
|
||||
url: '/agent/rewards',
|
||||
method: 'GET',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取代理状态
|
||||
*/
|
||||
export const getAgentStatus = () => {
|
||||
return request({
|
||||
url: '/agent/status',
|
||||
method: 'GET'
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 代理申请
|
||||
* @param {Object} data 申请数据 {region, mobile, wechat_id, code, ancestor?}
|
||||
*/
|
||||
export const applyAgent = (data) => {
|
||||
return request({
|
||||
url: '/agent/apply',
|
||||
method: 'POST',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取代理会员用户配置
|
||||
* @param {Object} params 查询参数 {product_id}
|
||||
*/
|
||||
export const getAgentMembershipUserConfig = (params) => {
|
||||
return request({
|
||||
url: '/agent/membership/user_config',
|
||||
method: 'GET',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存代理会员用户配置
|
||||
* @param {Object} data 配置数据
|
||||
*/
|
||||
export const saveAgentMembershipUserConfig = (data) => {
|
||||
return request({
|
||||
url: '/agent/membership/save_user_config',
|
||||
method: 'POST',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取产品配置
|
||||
*/
|
||||
export const getProductConfig = () => {
|
||||
return request({
|
||||
url: '/agent/product_config',
|
||||
method: 'GET'
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成推广链接
|
||||
* @param {Object} data 推广数据 {product, price}
|
||||
*/
|
||||
export const generatePromotionLink = (data) => {
|
||||
return request({
|
||||
url: '/agent/generating_link',
|
||||
method: 'POST',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取代理收益
|
||||
*/
|
||||
export const getAgentRevenue = () => {
|
||||
return request({
|
||||
url: '/agent/revenue',
|
||||
method: 'GET'
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 代理提现
|
||||
* @param {Object} data 提现数据 {payee_account, amount, payee_name}
|
||||
*/
|
||||
export const agentWithdrawal = (data) => {
|
||||
return request({
|
||||
url: '/agent/withdrawal',
|
||||
method: 'POST',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取提现记录
|
||||
* @param {Object} params 查询参数 {page, page_size}
|
||||
*/
|
||||
export const getWithdrawalRecords = (params) => {
|
||||
return request({
|
||||
url: '/agent/withdrawal',
|
||||
method: 'GET',
|
||||
params
|
||||
})
|
||||
}
|
@ -3,8 +3,6 @@
|
||||
}
|
||||
|
||||
html {
|
||||
margin: auto !important;
|
||||
@apply max-w-lg;
|
||||
font-size: 4px; // * 方便unocss计算:1单位 = 0.25rem = 1px
|
||||
}
|
||||
|
||||
@ -42,9 +40,3 @@ html.dark {
|
||||
display: none; /* Chrome, Safari, and Edge */
|
||||
}
|
||||
|
||||
.safe-area-top {
|
||||
padding-top: env(safe-area-inset-top);
|
||||
}
|
||||
.safe-area-bottom {
|
||||
padding-bottom: env(safe-area-inset-bottom);
|
||||
}
|
||||
|
11
src/auto-imports.d.ts
vendored
11
src/auto-imports.d.ts
vendored
@ -11,8 +11,6 @@ declare global {
|
||||
const aesEncrypt: typeof import('./utils/crypto.js')['aesEncrypt']
|
||||
const asyncComputed: typeof import('@vueuse/core')['asyncComputed']
|
||||
const autoResetRef: typeof import('@vueuse/core')['autoResetRef']
|
||||
const chatCrypto: typeof import('./utils/chatCrypto.js')['default']
|
||||
const chatEncrypt: typeof import('./utils/chatEncrypt.js')['default']
|
||||
const computed: typeof import('vue')['computed']
|
||||
const computedAsync: typeof import('@vueuse/core')['computedAsync']
|
||||
const computedEager: typeof import('@vueuse/core')['computedEager']
|
||||
@ -113,8 +111,6 @@ declare global {
|
||||
const resolveComponent: typeof import('vue')['resolveComponent']
|
||||
const resolveRef: typeof import('@vueuse/core')['resolveRef']
|
||||
const resolveUnref: typeof import('@vueuse/core')['resolveUnref']
|
||||
const routerGuard: typeof import('./utils/routerGuard.js')['default']
|
||||
const setupRouterGuard: typeof import('./utils/routerGuard.js')['setupRouterGuard']
|
||||
const shallowReactive: typeof import('vue')['shallowReactive']
|
||||
const shallowReadonly: typeof import('vue')['shallowReadonly']
|
||||
const shallowRef: typeof import('vue')['shallowRef']
|
||||
@ -251,7 +247,6 @@ declare global {
|
||||
const useRafFn: typeof import('@vueuse/core')['useRafFn']
|
||||
const useRefHistory: typeof import('@vueuse/core')['useRefHistory']
|
||||
const useResizeObserver: typeof import('@vueuse/core')['useResizeObserver']
|
||||
const useRouterGuard: typeof import('./composables/useRouterGuard')['useRouterGuard']
|
||||
const useScreenOrientation: typeof import('@vueuse/core')['useScreenOrientation']
|
||||
const useScreenSafeArea: typeof import('@vueuse/core')['useScreenSafeArea']
|
||||
const useScriptTag: typeof import('@vueuse/core')['useScriptTag']
|
||||
@ -288,7 +283,6 @@ declare global {
|
||||
const useToggle: typeof import('@vueuse/core')['useToggle']
|
||||
const useTransition: typeof import('@vueuse/core')['useTransition']
|
||||
const useUrlSearchParams: typeof import('@vueuse/core')['useUrlSearchParams']
|
||||
const useUser: typeof import('./composables/useUser.js')['useUser']
|
||||
const useUserMedia: typeof import('@vueuse/core')['useUserMedia']
|
||||
const useVModel: typeof import('@vueuse/core')['useVModel']
|
||||
const useVModels: typeof import('@vueuse/core')['useVModels']
|
||||
@ -335,8 +329,6 @@ declare module 'vue' {
|
||||
readonly aesEncrypt: UnwrapRef<typeof import('./utils/crypto.js')['aesEncrypt']>
|
||||
readonly asyncComputed: UnwrapRef<typeof import('@vueuse/core')['asyncComputed']>
|
||||
readonly autoResetRef: UnwrapRef<typeof import('@vueuse/core')['autoResetRef']>
|
||||
readonly chatCrypto: UnwrapRef<typeof import('./utils/chatCrypto.js')['default']>
|
||||
readonly chatEncrypt: UnwrapRef<typeof import('./utils/chatEncrypt.js')['default']>
|
||||
readonly computed: UnwrapRef<typeof import('vue')['computed']>
|
||||
readonly computedAsync: UnwrapRef<typeof import('@vueuse/core')['computedAsync']>
|
||||
readonly computedEager: UnwrapRef<typeof import('@vueuse/core')['computedEager']>
|
||||
@ -437,7 +429,6 @@ declare module 'vue' {
|
||||
readonly resolveComponent: UnwrapRef<typeof import('vue')['resolveComponent']>
|
||||
readonly resolveRef: UnwrapRef<typeof import('@vueuse/core')['resolveRef']>
|
||||
readonly resolveUnref: UnwrapRef<typeof import('@vueuse/core')['resolveUnref']>
|
||||
readonly setupRouterGuard: UnwrapRef<typeof import('./utils/routerGuard.js')['setupRouterGuard']>
|
||||
readonly shallowReactive: UnwrapRef<typeof import('vue')['shallowReactive']>
|
||||
readonly shallowReadonly: UnwrapRef<typeof import('vue')['shallowReadonly']>
|
||||
readonly shallowRef: UnwrapRef<typeof import('vue')['shallowRef']>
|
||||
@ -489,6 +480,7 @@ declare module 'vue' {
|
||||
readonly useCloned: UnwrapRef<typeof import('@vueuse/core')['useCloned']>
|
||||
readonly useColorMode: UnwrapRef<typeof import('@vueuse/core')['useColorMode']>
|
||||
readonly useConfirmDialog: UnwrapRef<typeof import('@vueuse/core')['useConfirmDialog']>
|
||||
readonly useCount: UnwrapRef<typeof import('./composables/useCount')['useCount']>
|
||||
readonly useCounter: UnwrapRef<typeof import('@vueuse/core')['useCounter']>
|
||||
readonly useCssModule: UnwrapRef<typeof import('vue')['useCssModule']>
|
||||
readonly useCssVar: UnwrapRef<typeof import('@vueuse/core')['useCssVar']>
|
||||
@ -569,6 +561,7 @@ declare module 'vue' {
|
||||
readonly usePreferredLanguages: UnwrapRef<typeof import('@vueuse/core')['usePreferredLanguages']>
|
||||
readonly usePreferredReducedMotion: UnwrapRef<typeof import('@vueuse/core')['usePreferredReducedMotion']>
|
||||
readonly usePrevious: UnwrapRef<typeof import('@vueuse/core')['usePrevious']>
|
||||
readonly useQuery: UnwrapRef<typeof import('./composables/useQuery')['useQuery']>
|
||||
readonly useRafFn: UnwrapRef<typeof import('@vueuse/core')['useRafFn']>
|
||||
readonly useRefHistory: UnwrapRef<typeof import('@vueuse/core')['useRefHistory']>
|
||||
readonly useResizeObserver: UnwrapRef<typeof import('@vueuse/core')['useResizeObserver']>
|
||||
|
36
src/components.d.ts
vendored
36
src/components.d.ts
vendored
@ -7,11 +7,37 @@ export {}
|
||||
|
||||
declare module 'vue' {
|
||||
export interface GlobalComponents {
|
||||
AgentApplicationForm: typeof import('./components/AgentApplicationForm.vue')['default']
|
||||
EnvDemo: typeof import('./components/EnvDemo.vue')['default']
|
||||
PriceInputPopup: typeof import('./components/PriceInputPopup.vue')['default']
|
||||
AppFooter: typeof import('./components/AppFooter.vue')['default']
|
||||
AppLogos: typeof import('./components/AppLogos.vue')['default']
|
||||
HiCounter: typeof import('./components/HiCounter.vue')['default']
|
||||
InputEntry: typeof import('./components/InputEntry.vue')['default']
|
||||
LButtonGroup: typeof import('./components/LButtonGroup.vue')['default']
|
||||
LExpandCollapse: typeof import('./components/LExpandCollapse.vue')['default']
|
||||
LTabbar: typeof import('./components/LTabbar.vue')['default']
|
||||
LTable: typeof import('./components/LTable.vue')['default']
|
||||
LTitle: typeof import('./components/LTitle.vue')['default']
|
||||
PrivacyModel: typeof import('./components/PrivacyModel.vue')['default']
|
||||
QRcode: typeof import('./components/QRcode.vue')['default']
|
||||
VipBanner: typeof import('./components/VipBanner.vue')['default']
|
||||
QiunDataChartsQiunDataCharts: typeof import('./components/qiun-data-charts/qiun-data-charts.vue')['default']
|
||||
QiunErrorQiunError: typeof import('./components/qiun-error/qiun-error.vue')['default']
|
||||
QiunLoadingLoading1: typeof import('./components/qiun-loading/loading1.vue')['default']
|
||||
QiunLoadingLoading2: typeof import('./components/qiun-loading/loading2.vue')['default']
|
||||
QiunLoadingLoading3: typeof import('./components/qiun-loading/loading3.vue')['default']
|
||||
QiunLoadingLoading4: typeof import('./components/qiun-loading/loading4.vue')['default']
|
||||
QiunLoadingLoading5: typeof import('./components/qiun-loading/loading5.vue')['default']
|
||||
QiunLoadingQiunLoading: typeof import('./components/qiun-loading/qiun-loading.vue')['default']
|
||||
WdButton: typeof import('wot-design-uni/components/wd-button/wd-button.vue')['default']
|
||||
WdCell: typeof import('wot-design-uni/components/wd-cell/wd-cell.vue')['default']
|
||||
WdCheckbox: typeof import('wot-design-uni/components/wd-checkbox/wd-checkbox.vue')['default']
|
||||
WdDivider: typeof import('wot-design-uni/components/wd-divider/wd-divider.vue')['default']
|
||||
WdIcon: typeof import('wot-design-uni/components/wd-icon/wd-icon.vue')['default']
|
||||
WdImg: typeof import('wot-design-uni/components/wd-img/wd-img.vue')['default']
|
||||
WdInput: typeof import('wot-design-uni/components/wd-input/wd-input.vue')['default']
|
||||
WdLoadmore: typeof import('wot-design-uni/components/wd-loadmore/wd-loadmore.vue')['default']
|
||||
WdNavbar: typeof import('wot-design-uni/components/wd-navbar/wd-navbar.vue')['default']
|
||||
WdNoticeBar: typeof import('wot-design-uni/components/wd-notice-bar/wd-notice-bar.vue')['default']
|
||||
WdRadio: typeof import('wot-design-uni/components/wd-radio/wd-radio.vue')['default']
|
||||
WdRadioGroup: typeof import('wot-design-uni/components/wd-radio-group/wd-radio-group.vue')['default']
|
||||
WdTabbar: typeof import('wot-design-uni/components/wd-tabbar/wd-tabbar.vue')['default']
|
||||
WdTabbarItem: typeof import('wot-design-uni/components/wd-tabbar-item/wd-tabbar-item.vue')['default']
|
||||
}
|
||||
}
|
||||
|
@ -1,341 +0,0 @@
|
||||
<template>
|
||||
<wd-popup v-model="popupVisible" position="bottom" close-on-click-modal @close="handleClose">
|
||||
<view class="bg-white rounded-t-lg p-4">
|
||||
<view class="flex justify-between items-center mb-4">
|
||||
<text class="text-gray-400" @click="cancel">取消</text>
|
||||
<text class="text-lg font-medium">申请成为代理</text>
|
||||
<text class="text-gray-400" @click="cancel">关闭</text>
|
||||
</view>
|
||||
|
||||
<wd-form :model="form" :rules="rules">
|
||||
<wd-cell-group border>
|
||||
<!-- 区域选择 -->
|
||||
<wd-col-picker v-model="region" label="代理区域" label-width="100px" prop="region" placeholder="请选择代理区域"
|
||||
:columns="columns" :column-change="handleColumnChange" @confirm="handleRegionConfirm"
|
||||
:display-format="displayFormat" />
|
||||
<!-- 手机号 -->
|
||||
<wd-input label="手机号码" label-width="100px" type="number" v-model="form.mobile" prop="mobile"
|
||||
placeholder="请输入您的手机号" :rules="[
|
||||
{ required: true, message: '请输入手机号' },
|
||||
{ required: true, pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号' }
|
||||
]" />
|
||||
|
||||
<!-- 验证码 -->
|
||||
<wd-input label="验证码" label-width="100px" type="number" v-model="form.code" prop="code" placeholder="请输入验证码"
|
||||
:rules="[{ required: true, message: '请输入验证码' }]" use-suffix-slot>
|
||||
<template #suffix>
|
||||
<button class="verify-btn" :disabled="countdown > 0" @click.stop="sendVerifyCode">
|
||||
{{ countdown > 0 ? `${countdown}s` : '获取验证码' }}
|
||||
</button>
|
||||
</template>
|
||||
</wd-input>
|
||||
|
||||
<!-- 微信号 -->
|
||||
<wd-input label="微信号" label-width="100px" v-model="form.wechat_id" prop="wechat_id" placeholder="请输入您的微信号"
|
||||
:rules="[{ required: true, message: '请输入微信号' }]" />
|
||||
</wd-cell-group>
|
||||
|
||||
<!-- 同意条款的复选框 -->
|
||||
<view class="p-4">
|
||||
<view class="flex items-start">
|
||||
<wd-checkbox v-model="isAgreed" size="16px" class="flex-shrink-0 mr-2"></wd-checkbox>
|
||||
<view class="text-xs text-gray-400 leading-tight">
|
||||
我已阅读并同意
|
||||
<text class="text-blue-400" @click.stop="toUserAgreement">《用户协议》</text>
|
||||
<text class="text-blue-400" @click.stop="toServiceAgreement">《信息技术服务合同》</text>
|
||||
<text class="text-blue-400" @click.stop="toAgentManageAgreement">《推广方管理制度协议》</text>
|
||||
<view class="text-xs text-gray-400 mt-1">点击勾选即代表您同意上述法律文书的相关条款并签署上述法律文书</view>
|
||||
<view class="text-xs text-gray-400 mt-1">手机号未在本平台注册账号则申请后将自动生成账号</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="p-4">
|
||||
<wd-button type="primary" block @click="submitForm">提交申请</wd-button>
|
||||
<wd-button type="default" block class="mt-2" @click="cancel">取消</wd-button>
|
||||
</view>
|
||||
</wd-form>
|
||||
</view>
|
||||
</wd-popup>
|
||||
<wd-toast />
|
||||
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, watch, onUnmounted } from 'vue'
|
||||
import { useColPickerData } from '../hooks/useColPickerData'
|
||||
import { useToast } from 'wot-design-uni'
|
||||
import { getCode } from '@/api/apis.js' // 导入getCode API
|
||||
|
||||
const props = defineProps({
|
||||
show: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
ancestor: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
})
|
||||
const region = ref([]) // 存储地区代码数组
|
||||
const regionText = ref('') // 存储地区文本
|
||||
const isAgreed = ref(false) // 用户是否同意协议
|
||||
|
||||
// 格式化显示文本
|
||||
const displayFormat = (selectedItems) => {
|
||||
if (selectedItems.length === 0) return ''
|
||||
return selectedItems.map(item => item.label).join(' ')
|
||||
}
|
||||
|
||||
const emit = defineEmits(['update:show', 'submit', 'close'])
|
||||
const form = ref({
|
||||
mobile: '',
|
||||
code: '',
|
||||
wechat_id: ''
|
||||
})
|
||||
|
||||
// 使用wot-design-ui的toast组件
|
||||
const toast = useToast()
|
||||
|
||||
// 不再需要监听region变化触发表单验证
|
||||
// watch(region, (newVal) => {
|
||||
// // 当region变化时,触发表单验证
|
||||
// if (formRef.value) {
|
||||
// formRef.value.validate(['region'])
|
||||
// }
|
||||
// })
|
||||
|
||||
const popupVisible = ref(false)
|
||||
const countdown = ref(0)
|
||||
let timer = null
|
||||
|
||||
// 初始化省市区数据
|
||||
const { colPickerData, findChildrenByCode } = useColPickerData()
|
||||
const columns = ref([
|
||||
colPickerData.map((item) => {
|
||||
return {
|
||||
value: item.value,
|
||||
label: item.text
|
||||
}
|
||||
})
|
||||
])
|
||||
|
||||
// 表单验证规则 - 仍然保留以供wd-form组件使用
|
||||
const rules = {
|
||||
region: [{
|
||||
required: true,
|
||||
message: '请选择代理区域',
|
||||
validator: (value) => {
|
||||
// 这里直接检查region.value而不是传入的value
|
||||
if (Array.isArray(region.value) && region.value.length === 3) {
|
||||
return Promise.resolve()
|
||||
}
|
||||
return Promise.reject('请选择完整的省市区')
|
||||
}
|
||||
}],
|
||||
mobile: [
|
||||
{ required: true, message: '请输入手机号' },
|
||||
{ required: true, pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号' }
|
||||
],
|
||||
code: [{ required: true, message: '请输入验证码' }],
|
||||
wechat_id: [{ required: true, message: '请输入微信号' }]
|
||||
}
|
||||
|
||||
// 协议跳转函数
|
||||
const toUserAgreement = () => {
|
||||
uni.navigateTo({
|
||||
url: '/pages/agreement?type=user'
|
||||
})
|
||||
}
|
||||
|
||||
const toServiceAgreement = () => {
|
||||
uni.navigateTo({
|
||||
url: '/pages/agreement?type=service'
|
||||
})
|
||||
}
|
||||
|
||||
const toAgentManageAgreement = () => {
|
||||
uni.navigateTo({
|
||||
url: '/pages/agreement?type=manage'
|
||||
})
|
||||
}
|
||||
|
||||
// 监听show属性变化
|
||||
watch(() => props.show, (newVal) => {
|
||||
popupVisible.value = newVal
|
||||
})
|
||||
|
||||
// 监听popupVisible同步回props.show
|
||||
watch(() => popupVisible.value, (newVal) => {
|
||||
emit('update:show', newVal)
|
||||
})
|
||||
|
||||
// Popup关闭事件
|
||||
const handleClose = () => {
|
||||
emit('close')
|
||||
}
|
||||
|
||||
// 取消按钮
|
||||
const cancel = () => {
|
||||
popupVisible.value = false
|
||||
emit('close')
|
||||
}
|
||||
|
||||
// 处理列变化
|
||||
const handleColumnChange = ({ selectedItem, resolve, finish }) => {
|
||||
const children = findChildrenByCode(colPickerData, selectedItem.value)
|
||||
if (children && children.length) {
|
||||
resolve(children.map(item => ({
|
||||
label: item.text,
|
||||
value: item.value
|
||||
})))
|
||||
} else {
|
||||
finish()
|
||||
}
|
||||
}
|
||||
|
||||
// 区域选择确认 - 获取选中项的文本值
|
||||
const handleRegionConfirm = ({ value, selectedItems }) => {
|
||||
// 存储地区文本
|
||||
regionText.value = selectedItems.map(item => item.label).join('-')
|
||||
console.log('地区选择完成', regionText.value)
|
||||
}
|
||||
|
||||
// 判断手机号是否有效
|
||||
const isPhoneNumberValid = computed(() => {
|
||||
return /^1[3-9]\d{9}$/.test(form.value.mobile)
|
||||
})
|
||||
|
||||
// 发送验证码
|
||||
const sendVerifyCode = async () => {
|
||||
// 验证手机号
|
||||
if (!form.value.mobile) {
|
||||
toast.info('请输入手机号')
|
||||
return
|
||||
}
|
||||
if (!isPhoneNumberValid.value) {
|
||||
toast.info('手机号格式不正确')
|
||||
return
|
||||
}
|
||||
|
||||
// 发送验证码请求
|
||||
getCode({
|
||||
mobile: form.value.mobile,
|
||||
actionType: 'agentApply',
|
||||
}).then((res) => {
|
||||
if (res.code === 200) {
|
||||
toast.success('验证码已发送')
|
||||
// 开始倒计时
|
||||
startCountdown()
|
||||
} else {
|
||||
toast.error(res.msg || '发送失败')
|
||||
}
|
||||
}).catch((err) => {
|
||||
toast.error('网络错误')
|
||||
})
|
||||
}
|
||||
|
||||
// 开始倒计时
|
||||
const startCountdown = () => {
|
||||
countdown.value = 60
|
||||
if (timer) clearInterval(timer)
|
||||
|
||||
timer = setInterval(() => {
|
||||
countdown.value--
|
||||
if (countdown.value <= 0) {
|
||||
clearInterval(timer)
|
||||
timer = null
|
||||
}
|
||||
}, 1000)
|
||||
}
|
||||
|
||||
// 组件卸载时清除计时器
|
||||
onUnmounted(() => {
|
||||
if (timer) {
|
||||
clearInterval(timer)
|
||||
timer = null
|
||||
}
|
||||
})
|
||||
|
||||
// 提交表单 - 不再使用formRef验证
|
||||
const submitForm = () => {
|
||||
try {
|
||||
// 检查区域是否已选择
|
||||
if (!Array.isArray(region.value) || region.value.length < 3) {
|
||||
console.log('区域选择不完整:', region.value)
|
||||
toast.info('请选择完整的代理区域')
|
||||
return
|
||||
}
|
||||
|
||||
if (!regionText.value) {
|
||||
toast.info('请选择代理区域')
|
||||
return
|
||||
}
|
||||
|
||||
// 检查手机号
|
||||
if (!form.value.mobile) {
|
||||
console.log('手机号为空')
|
||||
toast.info('请输入手机号')
|
||||
return
|
||||
}
|
||||
|
||||
if (!isPhoneNumberValid.value) {
|
||||
console.log('手机号格式不正确:', form.value.mobile)
|
||||
toast.info('手机号格式不正确')
|
||||
return
|
||||
}
|
||||
|
||||
// 检查验证码
|
||||
if (!form.value.code) {
|
||||
console.log('验证码为空')
|
||||
toast.info('请输入验证码')
|
||||
return
|
||||
}
|
||||
|
||||
// 检查微信号
|
||||
if (!form.value.wechat_id) {
|
||||
console.log('微信号为空')
|
||||
toast.info('请输入微信号')
|
||||
return
|
||||
}
|
||||
|
||||
// 检查用户是否同意协议
|
||||
if (!isAgreed.value) {
|
||||
toast.info('请阅读并同意相关协议')
|
||||
return
|
||||
}
|
||||
|
||||
// 所有验证通过,构建表单数据
|
||||
const formData = {
|
||||
...form.value,
|
||||
region: regionText.value,
|
||||
}
|
||||
console.log('提交的表单数据:', formData)
|
||||
|
||||
// 提交完整数据
|
||||
emit('submit', formData)
|
||||
} catch (error) {
|
||||
console.error('提交表单过程中出现异常:', error)
|
||||
toast.error('系统错误,请稍后重试')
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.verify-btn {
|
||||
height: 32px;
|
||||
padding: 0 12px;
|
||||
background-color: #3b82f6;
|
||||
color: white;
|
||||
border-radius: 4px;
|
||||
font-size: 14px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.verify-btn[disabled] {
|
||||
background-color: #a0aec0;
|
||||
}
|
||||
</style>
|
25
src/components/AppFooter.vue
Normal file
25
src/components/AppFooter.vue
Normal file
@ -0,0 +1,25 @@
|
||||
<script lang="ts" setup>
|
||||
function handleClickGithub() {
|
||||
if (window?.open) {
|
||||
window.open('https://github.com/uni-helper/vitesse-uni-app')
|
||||
}
|
||||
else {
|
||||
uni.showToast({
|
||||
icon: 'none',
|
||||
title: '请使用浏览器打开',
|
||||
})
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<view text="xl gray4" m-5 flex items-center justify-center gap-3>
|
||||
<navigator url="/pages/index" open-type="redirect">
|
||||
<view i-carbon-campsite />
|
||||
</navigator>
|
||||
|
||||
<view cursor-pointer @click="handleClickGithub">
|
||||
<view i-carbon:logo-github />
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
27
src/components/AppLogos.vue
Normal file
27
src/components/AppLogos.vue
Normal file
@ -0,0 +1,27 @@
|
||||
<template>
|
||||
<view inline-flex cursor-default text-2xl font-300>
|
||||
<view
|
||||
flex
|
||||
flex-col
|
||||
items-center
|
||||
hover-class="drop-shadow-md drop-shadow-color-green5"
|
||||
>
|
||||
<image inline-block h-18 w-18 src="/static/logo.svg" />
|
||||
<text mt--2 text-green5>
|
||||
uni-helper
|
||||
</text>
|
||||
</view>
|
||||
<view
|
||||
text="3xl gray4"
|
||||
m="x-4 y-auto"
|
||||
|
||||
i-carbon-add transform transition-all-500 hover:rotate-135
|
||||
/>
|
||||
<view flex flex-col hover-class="drop-shadow-md drop-shadow-color-purple5">
|
||||
<image inline-block h-18 w-18 src="/static/vite.png" />
|
||||
<text mt--2 text-purple5>
|
||||
Vite
|
||||
</text>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
@ -1,84 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
// 在Vue组件中访问环境变量
|
||||
const baseUrl = import.meta.env.VITE_APP_BASE_URL
|
||||
const isDebug = import.meta.env.VITE_APP_DEBUG === 'true'
|
||||
|
||||
// 获取当前环境模式
|
||||
const mode = import.meta.env.MODE
|
||||
|
||||
// 用于测试的方法
|
||||
function testApiCall() {
|
||||
// 使用环境变量构建API URL
|
||||
const apiUrl = `${baseUrl}/api/v1/test`
|
||||
console.log('请求地址:', apiUrl)
|
||||
|
||||
// 这里可以添加实际的API调用
|
||||
uni.showToast({
|
||||
title: `环境: ${mode}, API: ${apiUrl}`,
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<view class="env-demo">
|
||||
<view class="env-info">
|
||||
<text class="info-title">环境变量信息</text>
|
||||
<view class="info-item">
|
||||
<text class="label">基础URL:</text>
|
||||
<text class="value">{{ baseUrl }}</text>
|
||||
</view>
|
||||
<view class="info-item">
|
||||
<text class="label">调试模式:</text>
|
||||
<text class="value">{{ isDebug ? '已开启' : '已关闭' }}</text>
|
||||
</view>
|
||||
<view class="info-item">
|
||||
<text class="label">当前环境:</text>
|
||||
<text class="value">{{ mode }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<button class="test-btn" @click="testApiCall">测试API调用</button>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
.env-demo {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.env-info {
|
||||
background-color: #f5f5f5;
|
||||
padding: 15px;
|
||||
border-radius: 8px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.info-title {
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 10px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.info-item {
|
||||
display: flex;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.label {
|
||||
font-weight: bold;
|
||||
margin-right: 10px;
|
||||
width: 80px;
|
||||
}
|
||||
|
||||
.value {
|
||||
flex: 1;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.test-btn {
|
||||
background-color: #007aff;
|
||||
color: #ffffff;
|
||||
}
|
||||
</style>
|
23
src/components/HiCounter.vue
Normal file
23
src/components/HiCounter.vue
Normal file
@ -0,0 +1,23 @@
|
||||
<script setup lang="ts">
|
||||
const { count, inc, dec } = useCount()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<view inline-flex m="y-3">
|
||||
<view class="btn" @click="dec()">
|
||||
<text i-carbon-subtract />
|
||||
</view>
|
||||
<view font="mono" w="15" m-auto inline-block>
|
||||
{{ count }}
|
||||
</view>
|
||||
<view class="btn" @click="inc()">
|
||||
<text i-carbon-add />
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
.btn {
|
||||
--at-apply: w-8 h-8 flex items-center justify-center rounded-full bg-teal-600 text-white cursor-pointer
|
||||
}
|
||||
</style>
|
47
src/components/InputEntry.vue
Normal file
47
src/components/InputEntry.vue
Normal file
@ -0,0 +1,47 @@
|
||||
<script setup lang="ts">
|
||||
const name = ref('')
|
||||
function go() {
|
||||
if (name.value) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/hi?name=${name.value}`,
|
||||
})
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<view>
|
||||
<view
|
||||
p="x-4 y-2"
|
||||
w="250px"
|
||||
m="t-5 auto"
|
||||
text="center"
|
||||
bg="transparent"
|
||||
border="~ rounded gray-200 dark:gray-700 solid"
|
||||
outline="none active:none"
|
||||
box-border
|
||||
w-full
|
||||
>
|
||||
<input
|
||||
v-model="name"
|
||||
placeholder="What's your name?"
|
||||
type="text"
|
||||
autocomplete="off"
|
||||
|
||||
mr-0 w-full
|
||||
>
|
||||
</view>
|
||||
<view>
|
||||
<button
|
||||
:disabled="!name"
|
||||
|
||||
m="t-3 auto"
|
||||
m-auto w-120rpx rounded bg-teal-600 px-4 py-1 text-sm text-white
|
||||
hover-class="bg-teal-700"
|
||||
@click="go"
|
||||
>
|
||||
GO
|
||||
</button>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
87
src/components/LButtonGroup.vue
Normal file
87
src/components/LButtonGroup.vue
Normal file
@ -0,0 +1,87 @@
|
||||
<script setup>
|
||||
// 接收 type 和 options props 以及 v-model
|
||||
const props = defineProps({
|
||||
type: {
|
||||
type: String,
|
||||
default: 'purple-pink', // 默认颜色渐变
|
||||
},
|
||||
options: {
|
||||
type: Array,
|
||||
required: true, // 动态传入选项
|
||||
},
|
||||
modelValue: {
|
||||
type: String,
|
||||
default: '', // v-model 绑定的值
|
||||
},
|
||||
})
|
||||
const emit = defineEmits(['update:modelValue'])
|
||||
// 选中内容绑定 v-model
|
||||
const selected = ref(props.modelValue)
|
||||
|
||||
// 监听 v-model 的变化
|
||||
watch(() => props.modelValue, (newValue) => {
|
||||
selected.value = newValue
|
||||
})
|
||||
|
||||
// 根据type动态生成分割线的类名
|
||||
const lineClass = computed(() => {
|
||||
switch (props.type) {
|
||||
case 'blue-green':
|
||||
return 'bg-gradient-to-r from-blue-400 via-green-500 to-teal-500'
|
||||
case 'orange-yellow':
|
||||
return 'bg-gradient-to-r from-orange-400 via-yellow-500 to-yellow-600'
|
||||
case 'red-purple':
|
||||
return 'bg-gradient-to-r from-red-500 via-purple-500 to-purple-600'
|
||||
default:
|
||||
return 'bg-gradient-to-r from-purple-400 via-pink-500 to-red-500'
|
||||
}
|
||||
})
|
||||
|
||||
// 计算滑动线的位置和宽度
|
||||
const slideLineStyle = computed(() => {
|
||||
const index = props.options.findIndex(option => option.value === selected.value)
|
||||
const buttonWidth = 100 / props.options.length
|
||||
return {
|
||||
width: `${buttonWidth}%`,
|
||||
transform: `translateX(${index * 100}%)`,
|
||||
}
|
||||
})
|
||||
|
||||
// 选择选项函数
|
||||
function selectOption(option) {
|
||||
selected.value = option.value
|
||||
// 触发 v-model 的更新
|
||||
emit('update:modelValue', option.value)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="relative flex">
|
||||
<div
|
||||
v-for="(option, index) in options"
|
||||
:key="index"
|
||||
class="flex-1 shrink-0 cursor-pointer py-2 text-center text-size-sm font-bold transition-transform duration-200 ease-in-out"
|
||||
:class="{ 'text-gray-900': selected === option.value, 'text-gray-500': selected !== option.value }"
|
||||
@click="selectOption(option)"
|
||||
>
|
||||
{{ option.label }}
|
||||
</div>
|
||||
<div
|
||||
class="absolute bottom-0 h-[3px] rounded transition-all duration-300"
|
||||
:style="slideLineStyle"
|
||||
:class="lineClass"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
/* 自定义样式 */
|
||||
button {
|
||||
outline: none;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
button:focus {
|
||||
outline: none;
|
||||
}
|
||||
</style>
|
61
src/components/LExpandCollapse.vue
Normal file
61
src/components/LExpandCollapse.vue
Normal file
@ -0,0 +1,61 @@
|
||||
<script setup>
|
||||
import { computed, ref, useSlots } from 'vue'
|
||||
|
||||
// 接收最大长度的 prop,默认值 100
|
||||
const props = defineProps({
|
||||
maxLength: {
|
||||
type: Number,
|
||||
default: 100,
|
||||
},
|
||||
})
|
||||
|
||||
// 记录当前是否展开
|
||||
const isExpanded = ref(false)
|
||||
|
||||
// 获取 slot 内容
|
||||
const slots = useSlots()
|
||||
|
||||
// 计算截断后的内容
|
||||
const truncatedContent = computed(() => {
|
||||
const slotContent = getSlotContent()
|
||||
return slotContent.length > props.maxLength
|
||||
? `${slotContent.slice(0, props.maxLength)}...`
|
||||
: slotContent
|
||||
})
|
||||
|
||||
// 获取 slot 内容,确保返回的内容为字符串
|
||||
function getSlotContent() {
|
||||
const slotVNode = slots.default ? slots.default()[0] : null
|
||||
return slotVNode ? slotVNode.children.toString().trim() : '' // 获取并转化为字符串
|
||||
}
|
||||
|
||||
// 切换展开/收起状态
|
||||
function toggleExpand() {
|
||||
isExpanded.value = !isExpanded.value
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<view>
|
||||
<!-- 展开/收起按钮 -->
|
||||
|
||||
<!-- 展开/收起的内容 -->
|
||||
<text v-if="isExpanded">
|
||||
<slot /> <!-- 使用 slot 来展示传递的内容 -->
|
||||
</text>
|
||||
<text v-else>
|
||||
<text>{{ truncatedContent }}</text>
|
||||
</text>
|
||||
<text
|
||||
:title="isExpanded ? '点击收起' : '点击展开'"
|
||||
class="cursor-pointer text-blue-500"
|
||||
@click="toggleExpand"
|
||||
>
|
||||
{{ isExpanded ? '收起' : '展开' }}
|
||||
</text>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
30
src/components/LTabbar.vue
Normal file
30
src/components/LTabbar.vue
Normal file
@ -0,0 +1,30 @@
|
||||
<script setup>
|
||||
const tabbar = ref('index')
|
||||
const menu = reactive([{ title: '首页', icon: 'home', name: 'index' }, { title: 'AI律师', icon: 'chat', name: 'ai' }, { title: '我的', icon: 'user', name: 'me' }])
|
||||
function tabChange({ value }) {
|
||||
uni.switchTab({
|
||||
url: `/pages/${value}`,
|
||||
})
|
||||
}
|
||||
|
||||
onShow(() => {
|
||||
const currentPage = getCurrentPages()[getCurrentPages().length - 1].route
|
||||
const pageName = currentPage.split('/').pop()
|
||||
tabbar.value = pageName
|
||||
})
|
||||
onMounted(() => {
|
||||
uni.hideTabBar()
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<wd-tabbar v-model="tabbar" custom-class="qnc-tabbar" shape="round" safe-area-inset-bottom fixed @change="tabChange">
|
||||
<wd-tabbar-item v-for="(item, index) in menu" :key="index" :name="item.name" :title="item.title" :icon="item.icon" />
|
||||
</wd-tabbar>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
:deep(.qnc-tabbar) {
|
||||
bottom: 16px !important;
|
||||
}
|
||||
</style>
|
98
src/components/LTable.vue
Normal file
98
src/components/LTable.vue
Normal file
@ -0,0 +1,98 @@
|
||||
<script setup>
|
||||
import { computed } from 'vue'
|
||||
|
||||
// 接收表格数据和类型的 props
|
||||
const props = defineProps({
|
||||
data: {
|
||||
type: Array,
|
||||
required: true,
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
default: 'purple-pink', // 默认渐变颜色
|
||||
},
|
||||
})
|
||||
|
||||
// 根据 type 设置不同的渐变颜色(偶数行)
|
||||
const evenClass = computed(() => {
|
||||
switch (props.type) {
|
||||
case 'blue-green':
|
||||
return 'bg-teal-100/40'
|
||||
// return 'bg-gradient-to-r from-blue-50 via-green-50 to-teal-50'
|
||||
case 'orange-yellow':
|
||||
return 'bg-gradient-to-r from-orange-50 via-yellow-50 to-yellow-100'
|
||||
case 'red-purple':
|
||||
return 'bg-gradient-to-r from-red-50 via-purple-50 to-purple-100'
|
||||
default:
|
||||
return 'bg-gradient-to-r from-purple-50 via-pink-50 to-red-50'
|
||||
}
|
||||
})
|
||||
|
||||
// 动态计算表头的背景颜色和文本颜色
|
||||
const headerClass = computed(() => {
|
||||
switch (props.type) {
|
||||
case 'blue-green':
|
||||
return 'bg-teal-200'
|
||||
// return 'bg-gradient-to-r from-blue-200 via-green-200 to-teal-200'
|
||||
case 'orange-yellow':
|
||||
return 'bg-gradient-to-r from-orange-200 via-yellow-200 to-yellow-200'
|
||||
case 'red-purple':
|
||||
return 'bg-gradient-to-r from-red-200 via-purple-200 to-purple-200'
|
||||
default:
|
||||
return 'bg-gradient-to-r from-purple-200 via-pink-200 to-red-200'
|
||||
}
|
||||
})
|
||||
// 斑马纹样式,偶数行带颜色,奇数行没有颜色,且从第二行开始
|
||||
function zebraClass(index) {
|
||||
return index % 2 === 1 ? evenClass.value : ''
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="l-table overflow-x-auto">
|
||||
<table class="min-w-full border-collapse table-auto text-center text-size-xs">
|
||||
<thead :class="headerClass">
|
||||
<tr>
|
||||
<!-- 插槽渲染表头 -->
|
||||
<slot name="header" />
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr
|
||||
v-for="(row, index) in data"
|
||||
:key="index"
|
||||
:class="zebraClass(index)"
|
||||
class="border-t"
|
||||
>
|
||||
<!-- 插槽渲染每一列的内容 -->
|
||||
<slot :row="row" />
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
/* 基础表格样式 */
|
||||
th {
|
||||
font-weight: bold;
|
||||
padding: 12px;
|
||||
text-align: left;
|
||||
border: 1px solid #e5e7eb;
|
||||
}
|
||||
|
||||
/* 表格行样式 */
|
||||
td {
|
||||
padding: 12px;
|
||||
border: 1px solid #e5e7eb;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
border-spacing: 0;
|
||||
}
|
||||
.l-table{
|
||||
@apply rounded-xl;;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
58
src/components/LTitle.vue
Normal file
58
src/components/LTitle.vue
Normal file
@ -0,0 +1,58 @@
|
||||
<script setup>
|
||||
// 接收 props
|
||||
const props = defineProps({
|
||||
title: String,
|
||||
type: {
|
||||
type: String,
|
||||
default: 'purple-pink', // 默认渐变
|
||||
},
|
||||
})
|
||||
|
||||
// 根据type返回不同的背景类名
|
||||
const titleClass = computed(() => {
|
||||
switch (props.type) {
|
||||
case 'blue-green':
|
||||
return 'bg-gradient-to-r from-blue-400 via-green-500 to-teal-500'
|
||||
case 'orange-yellow':
|
||||
return 'bg-gradient-to-r from-orange-400 via-yellow-500 to-yellow-600'
|
||||
case 'red-purple':
|
||||
return 'bg-gradient-to-r from-red-500 via-purple-500 to-purple-600'
|
||||
default:
|
||||
return 'bg-gradient-to-r from-purple-400 via-pink-500 to-red-500'
|
||||
}
|
||||
})
|
||||
|
||||
// 分割线颜色与背景对应
|
||||
const lineClass = computed(() => {
|
||||
switch (props.type) {
|
||||
case 'blue-green':
|
||||
return 'bg-gradient-to-r from-blue-400 via-green-500 to-teal-500'
|
||||
case 'orange-yellow':
|
||||
return 'bg-gradient-to-r from-orange-400 via-yellow-500 to-yellow-600'
|
||||
case 'red-purple':
|
||||
return 'bg-gradient-to-r from-red-500 via-purple-500 to-purple-600'
|
||||
default:
|
||||
return 'bg-gradient-to-r from-purple-400 via-pink-500 to-red-500'
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="relative">
|
||||
<!-- 标题部分 -->
|
||||
<div :class="titleClass" class="inline-block rounded-lg px-2 py-1 text-white font-bold shadow-md">
|
||||
{{ title }}
|
||||
</div>
|
||||
|
||||
<!-- 左上角修饰 -->
|
||||
<div class="absolute left-0 top-0 h-4 w-4 transform rounded-full bg-white shadow-md -translate-x-2 -translate-y-2" />
|
||||
|
||||
<!-- 分割线 -->
|
||||
<div class="relative mt-1.5">
|
||||
<div :class="lineClass" class="h-[2px] w-full rounded" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
</style>
|
@ -1,179 +0,0 @@
|
||||
<template>
|
||||
<wd-popup v-model="show" position="bottom" round close-on-click-modal destroy-on-close>
|
||||
<div class="min-h-[500px] bg-gray-50 text-gray-600">
|
||||
<div class="h-10 bg-white flex items-center justify-center font-semibold text-lg">设置客户查询价
|
||||
</div>
|
||||
<div class="card m-4">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="text-lg">
|
||||
客户查询价 (元)</div>
|
||||
</div>
|
||||
|
||||
<div class="border-b border-gray-200">
|
||||
<wd-input v-model="price" type="number" label="¥" label-width="28px" size="large"
|
||||
:placeholder="`${productConfig.price_range_min} - ${productConfig.price_range_max}`"
|
||||
@blur="onBlurPrice" custom-class="wd-input" />
|
||||
</div>
|
||||
<div class="flex items-center justify-between mt-2">
|
||||
<div>推广收益为<span class="text-orange-500"> {{ promotionRevenue }} </span>元</div>
|
||||
<div>我的成本为<span class="text-orange-500"> {{ costPrice }} </span>元</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card m-4">
|
||||
<div class="text-lg mb-2">收益与成本说明</div>
|
||||
|
||||
<div>推广收益 = 客户查询价 - 我的成本</div>
|
||||
<div>我的成本 = 提价成本 + 底价成本</div>
|
||||
<div class="mt-1">提价成本:超过平台标准定价部分,平台会收取部分成本价</div>
|
||||
<div class="">设定范围:<span class="text-orange-500">{{
|
||||
productConfig.price_range_min }}</span>元 - <span class="text-orange-500">{{
|
||||
productConfig.price_range_max }}</span>元</div>
|
||||
</div>
|
||||
<div class="px-4 pb-4">
|
||||
<wd-button class="w-full" round type="primary" size="large" @click="onConfirm">确认</wd-button>
|
||||
</div>
|
||||
</div>
|
||||
</wd-popup>
|
||||
<wd-toast />
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, watch, toRefs } from 'vue'
|
||||
import { useToast } from 'wot-design-uni'
|
||||
const props = defineProps({
|
||||
defaultPrice: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
productConfig: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
})
|
||||
const { defaultPrice, productConfig } = toRefs(props)
|
||||
const emit = defineEmits(["change"])
|
||||
const show = defineModel("show")
|
||||
const price = ref(null)
|
||||
const toast = useToast()
|
||||
|
||||
watch(show, () => {
|
||||
price.value = defaultPrice.value
|
||||
})
|
||||
|
||||
const costPrice = computed(() => {
|
||||
if (!productConfig.value) return 0.00
|
||||
// 平台定价成本
|
||||
let platformPricing = 0
|
||||
platformPricing += productConfig.value.cost_price
|
||||
if (price.value > productConfig.value.p_pricing_standard) {
|
||||
platformPricing += (price.value - productConfig.value.p_pricing_standard) * productConfig.value.p_overpricing_ratio
|
||||
}
|
||||
|
||||
if (productConfig.value.a_pricing_standard > platformPricing && productConfig.value.a_pricing_end > platformPricing && productConfig.value.a_overpricing_ratio > 0) {
|
||||
if (price.value > productConfig.value.a_pricing_standard) {
|
||||
if (price.value > productConfig.value.a_pricing_end) {
|
||||
platformPricing += (productConfig.value.a_pricing_end - productConfig.value.a_pricing_standard) * productConfig.value.a_overpricing_ratio
|
||||
} else {
|
||||
platformPricing += (price.value - productConfig.value.a_pricing_standard) * productConfig.value.a_overpricing_ratio
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return safeTruncate(platformPricing)
|
||||
})
|
||||
|
||||
const promotionRevenue = computed(() => {
|
||||
return safeTruncate(price.value - costPrice.value)
|
||||
});
|
||||
|
||||
// 价格校验与修正逻辑
|
||||
const validatePrice = (currentPrice) => {
|
||||
const min = productConfig.value.price_range_min;
|
||||
const max = productConfig.value.price_range_max;
|
||||
let newPrice = Number(currentPrice);
|
||||
let message = '';
|
||||
|
||||
// 处理无效输入
|
||||
if (isNaN(newPrice)) {
|
||||
newPrice = defaultPrice.value;
|
||||
return { newPrice, message: '输入无效,请输入价格' };
|
||||
}
|
||||
|
||||
// 处理小数位数(兼容科学计数法)
|
||||
try {
|
||||
const priceString = newPrice.toString()
|
||||
const [_, decimalPart = ""] = priceString.split('.');
|
||||
console.log(priceString, decimalPart)
|
||||
// 当小数位数超过2位时处理
|
||||
if (decimalPart.length > 2) {
|
||||
newPrice = parseFloat(safeTruncate(newPrice));
|
||||
message = '价格已自动格式化为两位小数';
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('价格格式化异常:', e);
|
||||
}
|
||||
|
||||
// 范围校验(基于可能格式化后的值)
|
||||
if (newPrice < min) {
|
||||
message = `价格不能低于 ${min} 元`;
|
||||
newPrice = min;
|
||||
} else if (newPrice > max) {
|
||||
message = `价格不能高于 ${max} 元`;
|
||||
newPrice = max;
|
||||
}
|
||||
console.log(newPrice, message)
|
||||
return { newPrice, message };
|
||||
}
|
||||
function safeTruncate(num, decimals = 2) {
|
||||
if (isNaN(num) || !isFinite(num)) return "0.00";
|
||||
|
||||
const factor = 10 ** decimals;
|
||||
const scaled = Math.trunc(num * factor);
|
||||
const truncated = scaled / factor;
|
||||
|
||||
return truncated.toFixed(decimals);
|
||||
}
|
||||
const isManualConfirm = ref(false)
|
||||
const onConfirm = () => {
|
||||
if (isManualConfirm.value) return
|
||||
const { newPrice, message } = validatePrice(price.value)
|
||||
if (message) {
|
||||
price.value = newPrice
|
||||
toast.show(message)
|
||||
} else {
|
||||
emit("change", price.value)
|
||||
show.value = false
|
||||
}
|
||||
}
|
||||
const onBlurPrice = () => {
|
||||
const { newPrice, message } = validatePrice(price.value)
|
||||
if (message) {
|
||||
isManualConfirm.value = true
|
||||
price.value = newPrice
|
||||
toast.show(message)
|
||||
}
|
||||
setTimeout(() => {
|
||||
isManualConfirm.value = false
|
||||
}, 0)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.wd-input {
|
||||
display: flex !important;
|
||||
align-items: center !important;
|
||||
justify-content: center !important;
|
||||
:deep(.wd-input__label-inner) {
|
||||
font-size: 24px !important; /* 增大label字体 */
|
||||
}
|
||||
|
||||
:deep(.wd-input__inner) {
|
||||
font-size: 24px !important; /* 增大输入框内字体 */
|
||||
}
|
||||
|
||||
:deep(.wd-input) {
|
||||
height: auto !important; /* 确保高度自适应 */
|
||||
padding: 8px 0 !important; /* 增加垂直内边距 */
|
||||
}
|
||||
}
|
||||
</style>
|
@ -51,11 +51,11 @@ onMounted(() => {
|
||||
</view>
|
||||
<view class="modal-message">
|
||||
感谢您使用全能查APP! 我们非常重视您的隐私保护和个人信息保护,在您使用全能查APP前,请您仔细阅读、充分理解
|
||||
<text class="link" @click="openPage('/pages/agreement?type=user')">
|
||||
<text class="link" @click="openPage('/pages/userAgreement')">
|
||||
《用户协议》
|
||||
</text>
|
||||
和
|
||||
<text class="link" @click="openPage('/pages/agreement?type=privacy')">
|
||||
<text class="link" @click="openPage('/pages/privacyPolicy')">
|
||||
《隐私政策》
|
||||
</text>
|
||||
的各项条款。如果您同意,请点击下方按钮开始接受我们的服务。
|
||||
|
@ -1,545 +0,0 @@
|
||||
<template>
|
||||
<wd-popup v-model="show" position="bottom" round>
|
||||
<view class="max-h-[calc(100vh-100px)] m-4">
|
||||
<view class="p-4 flex justify-center">
|
||||
<!-- 添加最大高度限制容器 -->
|
||||
<view class="max-h-[70vh] rounded-xl overflow-hidden">
|
||||
<canvas canvas-id="posterCanvas" id="posterCanvas" class="rounded-xl shadow"
|
||||
:style="{ width: canvasWidth + 'px', height: canvasHeight + 'px' }" ref="posterCanvas"></canvas>
|
||||
</view>
|
||||
</view>
|
||||
<view class="divider">分享到好友</view>
|
||||
|
||||
<view class="flex items-center justify-around">
|
||||
<view class="flex flex-col items-center justify-center" @click="savePoster">
|
||||
<image src="/static/image/icon_share_img.svg" class="w-10 h-10 rounded-full" />
|
||||
<view class="text-center mt-1 text-gray-600 text-xs">保存图片</view>
|
||||
</view>
|
||||
<!-- <view class="flex flex-col items-center justify-center" @click="shareToWechatFriend">
|
||||
<image src="/static/image/icon_share_wechat.svg" class="w-10 h-10 rounded-full" />
|
||||
<view class="text-center mt-1 text-gray-600 text-xs">微信好友</view>
|
||||
</view>
|
||||
<view class="flex flex-col items-center justify-center" @click="shareToWechatMoments">
|
||||
<image src="/static/image/icon_share_friends.svg" class="w-10 h-10 rounded-full" />
|
||||
<view class="text-center mt-1 text-gray-600 text-xs">微信朋友圈</view>
|
||||
</view> -->
|
||||
<view class="flex flex-col items-center justify-center" @click="copyUrl">
|
||||
<image src="/static/image/icon_share_url.svg" class="w-10 h-10 rounded-full" />
|
||||
<view class="text-center mt-1 text-gray-600 text-xs">复制链接</view>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</view>
|
||||
</wd-popup>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, watch, nextTick, computed, onMounted, toRefs, getCurrentInstance } from 'vue';
|
||||
import UQRCode from 'uqrcodejs';
|
||||
|
||||
const props = defineProps({
|
||||
linkIdentifier: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
mode: {
|
||||
type: String,
|
||||
default: "promote", // 例如 "promote" | "invitation"
|
||||
},
|
||||
});
|
||||
|
||||
const { linkIdentifier, mode } = toRefs(props);
|
||||
const posterCanvas = ref(null); // 用于绘制海报的canvas
|
||||
const posterGenerated = ref(false); // 标记海报是否已经生成过
|
||||
const show = defineModel('show');
|
||||
const instance = getCurrentInstance();
|
||||
|
||||
// 添加画布尺寸变量 - 降低默认尺寸
|
||||
const canvasWidth = ref(300); // 画布宽度
|
||||
const canvasHeight = ref(500); // 画布高度
|
||||
|
||||
const url = computed(() => {
|
||||
// 在uniapp中获取当前站点的基础URL
|
||||
const baseUrl = import.meta.env.VITE_APP_SHARE_URL || 'https://www.tianyuandata.com';
|
||||
return mode.value === "promote"
|
||||
? `${baseUrl}/agent/promotionInquire/`
|
||||
: `${baseUrl}/agent/invitationAgentApply/`;
|
||||
});
|
||||
|
||||
const qrcodeImage = ref(null);
|
||||
|
||||
const loadPosterImage = async () => {
|
||||
if (mode.value === "promote") {
|
||||
return '/static/image/tg_qrcode_1.png';
|
||||
} else {
|
||||
return '/static/image/yq_qrcode_1.png';
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(async () => {
|
||||
// 只在挂载时加载图片路径,但不生成海报
|
||||
qrcodeImage.value = await loadPosterImage();
|
||||
});
|
||||
|
||||
// 计算适合屏幕的画布尺寸
|
||||
const calculateCanvasSize = (imgWidth, imgHeight) => {
|
||||
// 获取系统信息
|
||||
const sysInfo = uni.getSystemInfoSync();
|
||||
|
||||
// 计算可用高度(屏幕高度的70%)
|
||||
const maxHeight = sysInfo.windowHeight * 0.6;
|
||||
// 控制最大宽度(屏幕宽度的80%)
|
||||
const maxWidth = sysInfo.windowWidth * 0.8;
|
||||
|
||||
// 初始尺寸
|
||||
let width = 300;
|
||||
let height = width * (imgHeight / imgWidth);
|
||||
|
||||
// 如果高度超出限制,按高度缩放
|
||||
if (height > maxHeight) {
|
||||
height = maxHeight;
|
||||
width = height * (imgWidth / imgHeight);
|
||||
}
|
||||
|
||||
// 如果宽度超出限制,按宽度缩放
|
||||
if (width > maxWidth) {
|
||||
width = maxWidth;
|
||||
height = width * (imgHeight / imgWidth);
|
||||
}
|
||||
|
||||
// 返回最终计算的尺寸
|
||||
return {
|
||||
width: Math.floor(width),
|
||||
height: Math.floor(height)
|
||||
};
|
||||
};
|
||||
|
||||
// 生成海报并合成二维码
|
||||
const generatePoster = async () => {
|
||||
console.log('[DEBUG] generatePoster: 开始生成海报');
|
||||
|
||||
// 如果已经生成过海报,就直接返回
|
||||
if (posterGenerated.value) {
|
||||
console.log('[DEBUG] generatePoster: 海报已生成,跳过');
|
||||
return;
|
||||
}
|
||||
|
||||
// 确保 DOM 已经渲染完成
|
||||
await nextTick();
|
||||
console.log('[DEBUG] generatePoster: DOM已渲染完成');
|
||||
|
||||
try {
|
||||
// 显示加载提示
|
||||
uni.showLoading({ title: '生成海报中...' });
|
||||
|
||||
console.log('[DEBUG] generatePoster: 在APP环境中执行');
|
||||
const canvasContext = uni.createCanvasContext('posterCanvas', instance.proxy);
|
||||
if (!canvasContext) {
|
||||
throw new Error('创建Canvas上下文失败');
|
||||
}
|
||||
console.log('[DEBUG] generatePoster: 创建Canvas上下文成功', !!canvasContext);
|
||||
|
||||
// 加载海报图片 - 确保绝对路径
|
||||
const posterImagePath = mode.value === "promote"
|
||||
? '/static/image/tg_qrcode_1.png'
|
||||
: '/static/image/yq_qrcode_1.png';
|
||||
console.log('[DEBUG] generatePoster: 开始加载海报图片', posterImagePath);
|
||||
|
||||
try {
|
||||
// 加载图片信息
|
||||
const posterImgInfo = await new Promise((resolve, reject) => {
|
||||
uni.getImageInfo({
|
||||
src: posterImagePath,
|
||||
success: res => {
|
||||
console.log('[DEBUG] generatePoster: 海报图片加载成功', res);
|
||||
|
||||
// 计算适合屏幕的尺寸
|
||||
const size = calculateCanvasSize(res.width, res.height);
|
||||
canvasWidth.value = size.width;
|
||||
canvasHeight.value = size.height;
|
||||
console.log('[DEBUG] generatePoster: 计算画布尺寸', size);
|
||||
|
||||
resolve(res);
|
||||
},
|
||||
fail: err => {
|
||||
console.error('[DEBUG] generatePoster: 海报图片加载失败', err);
|
||||
reject(err);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// 完全清除画布
|
||||
canvasContext.clearRect(0, 0, canvasWidth.value, canvasHeight.value);
|
||||
|
||||
// 绘制流程 - 多次测试以查找问题
|
||||
// 先尝试绘制底色确认canvas工作正常
|
||||
canvasContext.setFillStyle('#ffffff');
|
||||
canvasContext.fillRect(0, 0, canvasWidth.value, canvasHeight.value);
|
||||
|
||||
// 先绘制一次确保底色显示
|
||||
console.log('[DEBUG] generatePoster: 绘制白色背景');
|
||||
canvasContext.draw(false, () => {
|
||||
console.log('[DEBUG] generatePoster: 白色背景绘制完成');
|
||||
|
||||
// 第一步完成后,绘制背景图
|
||||
setTimeout(() => {
|
||||
console.log('[DEBUG] generatePoster: 开始绘制背景图片', posterImgInfo.path);
|
||||
canvasContext.drawImage(posterImgInfo.path, 0, 0, canvasWidth.value, canvasHeight.value);
|
||||
console.log('[DEBUG] generatePoster: 背景图片绘制完成');
|
||||
|
||||
canvasContext.draw(true, () => {
|
||||
console.log('[DEBUG] generatePoster: 背景图绘制完成,准备绘制二维码');
|
||||
|
||||
// 背景图绘制完成后,绘制二维码
|
||||
setTimeout(async () => {
|
||||
try {
|
||||
// 计算二维码在海报上的位置和大小 - 使用比例计算
|
||||
const scaleFactor = canvasWidth.value / posterImgInfo.width;
|
||||
|
||||
// 根据海报类型和缩放因子调整二维码尺寸和位置
|
||||
const qrSize = mode.value === "promote"
|
||||
? Math.min(Math.floor(300 * scaleFactor), canvasWidth.value * 0.4) // 控制最大尺寸
|
||||
: Math.min(Math.floor(360 * scaleFactor), canvasWidth.value * 0.4);
|
||||
|
||||
// 计算水平位置,确保在画布内
|
||||
const qrX = mode.value === "promote"
|
||||
? Math.min(Math.floor(180 * scaleFactor), canvasWidth.value - qrSize)
|
||||
: Math.min(Math.floor(360 * scaleFactor), canvasWidth.value - qrSize);
|
||||
|
||||
// 计算垂直位置,确保在画布底部合适位置
|
||||
const qrY = mode.value === "promote"
|
||||
? canvasHeight.value - Math.min(Math.floor(480 * scaleFactor), canvasHeight.value * 0.4)
|
||||
: canvasHeight.value - Math.min(Math.floor(1370 * scaleFactor), canvasHeight.value * 0.8);
|
||||
|
||||
console.log('[DEBUG] generatePoster: 二维码参数', { qrX, qrY, qrSize, mode: mode.value, scaleFactor });
|
||||
|
||||
// 3. 使用UQRCode生成二维码并绘制到画布
|
||||
// 创建uQRCode实例
|
||||
const qr = new UQRCode();
|
||||
// 设置二维码内容
|
||||
qr.data = generalUrl();
|
||||
// 设置二维码大小
|
||||
qr.size = qrSize;
|
||||
// 调用制作二维码方法
|
||||
qr.make();
|
||||
|
||||
// 绘制QR码到指定位置
|
||||
// 获取绘制模块信息
|
||||
const drawModules = qr.getDrawModules();
|
||||
for (const drawModule of drawModules) {
|
||||
if (drawModule.type === 'tile') {
|
||||
canvasContext.setFillStyle(drawModule.color);
|
||||
canvasContext.fillRect(
|
||||
qrX + drawModule.x,
|
||||
qrY + drawModule.y,
|
||||
drawModule.width,
|
||||
drawModule.height
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// 4. 最终绘制,这次保留先前绘制的背景图
|
||||
canvasContext.draw(true, () => {
|
||||
console.log('[DEBUG] generatePoster: 画布完整绘制完成');
|
||||
posterGenerated.value = true;
|
||||
uni.hideLoading();
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('[DEBUG] generatePoster: 二维码生成异常', error);
|
||||
uni.hideLoading();
|
||||
uni.showToast({
|
||||
title: '生成二维码失败',
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
}, 300);
|
||||
});
|
||||
}, 300);
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('[DEBUG] generatePoster: APP环境图片处理失败', error);
|
||||
uni.hideLoading();
|
||||
uni.showToast({
|
||||
title: '生成海报失败',
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('[DEBUG] generatePoster: 生成海报发生未捕获异常', error);
|
||||
uni.hideLoading();
|
||||
uni.showToast({
|
||||
title: '生成海报失败',
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// 监听 show 变化,show 为 true 时生成海报
|
||||
watch(show, (newVal) => {
|
||||
if (newVal && !posterGenerated.value) {
|
||||
generatePoster(); // 当弹窗显示且海报未生成时生成海报
|
||||
}
|
||||
});
|
||||
|
||||
// 保存海报图片
|
||||
const savePoster = () => {
|
||||
if (!posterGenerated.value) {
|
||||
uni.showToast({
|
||||
title: '海报生成中,请稍后再试',
|
||||
icon: 'none'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
uni.canvasToTempFilePath({
|
||||
canvasId: 'posterCanvas',
|
||||
width: canvasWidth.value,
|
||||
height: canvasHeight.value,
|
||||
destWidth: canvasWidth.value * 2, // 输出图片宽度为 canvas 宽度的2倍,提高清晰度
|
||||
destHeight: canvasHeight.value * 2, // 输出图片高度为 canvas 高度的2倍,提高清晰度
|
||||
success: (res) => {
|
||||
// 保存图片到相册
|
||||
uni.saveImageToPhotosAlbum({
|
||||
filePath: res.tempFilePath,
|
||||
success: () => {
|
||||
uni.showToast({
|
||||
title: '保存成功',
|
||||
icon: 'success'
|
||||
});
|
||||
},
|
||||
fail: (err) => {
|
||||
console.error('保存失败:', err);
|
||||
// 如果是用户拒绝授权导致的
|
||||
if (err.errMsg && err.errMsg.includes('auth deny')) {
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: '需要您授权保存图片到相册',
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
uni.openSetting();
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: '保存失败',
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
fail: (err) => {
|
||||
console.error('Canvas转图片失败:', err);
|
||||
uni.showToast({
|
||||
title: '保存失败',
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
}, instance.proxy);
|
||||
};
|
||||
|
||||
// 分享到微信好友
|
||||
const shareToWechatFriend = () => {
|
||||
if (!posterGenerated.value) {
|
||||
uni.showToast({
|
||||
title: '海报生成中,请稍后再试',
|
||||
icon: 'none'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
uni.canvasToTempFilePath({
|
||||
canvasId: 'posterCanvas',
|
||||
width: canvasWidth.value,
|
||||
height: canvasHeight.value,
|
||||
destWidth: canvasWidth.value * 2,
|
||||
destHeight: canvasHeight.value * 2,
|
||||
success: (res) => {
|
||||
// #ifdef APP-PLUS
|
||||
shareWithSystem('WXSceneSession', res.tempFilePath);
|
||||
// #endif
|
||||
|
||||
// #ifndef APP-PLUS
|
||||
uni.showToast({
|
||||
title: '分享功能仅支持APP',
|
||||
icon: 'none'
|
||||
});
|
||||
// #endif
|
||||
},
|
||||
fail: (err) => {
|
||||
console.error('Canvas转图片失败:', err);
|
||||
uni.showToast({
|
||||
title: '分享准备失败',
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
}, instance.proxy);
|
||||
};
|
||||
|
||||
// 分享到微信朋友圈
|
||||
const shareToWechatMoments = () => {
|
||||
if (!posterGenerated.value) {
|
||||
uni.showToast({
|
||||
title: '海报生成中,请稍后再试',
|
||||
icon: 'none'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
uni.canvasToTempFilePath({
|
||||
canvasId: 'posterCanvas',
|
||||
width: canvasWidth.value,
|
||||
height: canvasHeight.value,
|
||||
destWidth: canvasWidth.value * 2,
|
||||
destHeight: canvasHeight.value * 2,
|
||||
success: (res) => {
|
||||
// #ifdef APP-PLUS
|
||||
shareWithSystem('WXSceneTimeline', res.tempFilePath);
|
||||
// #endif
|
||||
|
||||
// #ifndef APP-PLUS
|
||||
uni.showToast({
|
||||
title: '分享功能仅支持APP',
|
||||
icon: 'none'
|
||||
});
|
||||
// #endif
|
||||
},
|
||||
fail: (err) => {
|
||||
console.error('Canvas转图片失败:', err);
|
||||
uni.showToast({
|
||||
title: '分享准备失败',
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
}, instance.proxy);
|
||||
};
|
||||
|
||||
// 通用的分享处理函数
|
||||
const shareWithSystem = (scene, tempFilePath) => {
|
||||
try {
|
||||
// 判断是否安装微信
|
||||
plus.share.getServices((services) => {
|
||||
const wechatService = services.find((s) => s.id === 'weixin');
|
||||
|
||||
if (!wechatService) {
|
||||
uni.showToast({
|
||||
title: '未检测到微信应用',
|
||||
icon: 'none'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// 判断微信是否认证
|
||||
wechatService.authorize(() => {
|
||||
const shareOptions = {
|
||||
provider: 'weixin',
|
||||
scene: scene, // WXSceneSession或WXSceneTimeline
|
||||
type: 2, // 图片类型
|
||||
imageUrl: tempFilePath,
|
||||
title: mode.value === "promote" ? '推广海报' : '邀请海报',
|
||||
href: generalUrl(),
|
||||
success: (res) => {
|
||||
uni.showToast({
|
||||
title: '分享成功',
|
||||
icon: 'success'
|
||||
});
|
||||
},
|
||||
fail: (err) => {
|
||||
console.error('分享失败:', err);
|
||||
uni.showToast({
|
||||
title: '分享失败',
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
wechatService.send(shareOptions, () => {
|
||||
console.log('分享成功');
|
||||
}, (err) => {
|
||||
console.error('分享失败:', err);
|
||||
});
|
||||
}, (err) => {
|
||||
console.error('微信认证失败:', err);
|
||||
uni.showToast({
|
||||
title: '微信认证失败',
|
||||
icon: 'none'
|
||||
});
|
||||
});
|
||||
}, (err) => {
|
||||
console.error('获取分享服务列表失败:', err);
|
||||
|
||||
// 如果获取服务失败,尝试使用系统分享
|
||||
try {
|
||||
plus.share.sendWithSystem({
|
||||
pictures: [tempFilePath]
|
||||
}, () => {
|
||||
uni.showToast({
|
||||
title: '分享成功',
|
||||
icon: 'success'
|
||||
});
|
||||
}, (err) => {
|
||||
uni.showToast({
|
||||
title: '分享失败',
|
||||
icon: 'none'
|
||||
});
|
||||
});
|
||||
} catch (e) {
|
||||
uni.showToast({
|
||||
title: '当前设备不支持分享',
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('分享出错:', error);
|
||||
uni.showToast({
|
||||
title: '分享失败',
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const generalUrl = () => {
|
||||
return url.value + encodeURIComponent(linkIdentifier.value);
|
||||
};
|
||||
|
||||
const copyUrl = () => {
|
||||
uni.setClipboardData({
|
||||
data: generalUrl(),
|
||||
success: () => {
|
||||
uni.showToast({
|
||||
title: '链接已复制!',
|
||||
icon: 'success'
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.divider {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin: 16px 0;
|
||||
color: #969799;
|
||||
font-size: 14px;
|
||||
|
||||
&::before,
|
||||
&::after {
|
||||
content: '';
|
||||
height: 1px;
|
||||
flex: 1;
|
||||
background-color: #ebedf0;
|
||||
}
|
||||
|
||||
&::before {
|
||||
margin-right: 16px;
|
||||
}
|
||||
|
||||
&::after {
|
||||
margin-left: 16px;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -1,36 +0,0 @@
|
||||
<template>
|
||||
<view class="card mb-4 relative overflow-hidden" @click="goToVip">
|
||||
<view class="absolute inset-0 bg-gradient-to-r from-yellow-400 to-yellow-300 opacity-40"></view>
|
||||
<view class="p-2 relative z-10">
|
||||
<view class="flex justify-between items-center">
|
||||
<view>
|
||||
<view class="text-lg font-bold text-yellow-800">会员专享特权</view>
|
||||
<view class="text-sm text-yellow-700 mt-1">升级VIP获得更多收益</view>
|
||||
</view>
|
||||
<view class="bg-yellow-500 px-3 py-1 rounded-full text-white text-sm shadow-sm">
|
||||
立即查看
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 装饰元素 -->
|
||||
<view class="absolute -right-4 -top-4 w-16 h-16 bg-yellow-200 rounded-full opacity-60"></view>
|
||||
<view class="absolute right-5 -bottom-4 w-12 h-12 bg-yellow-100 rounded-full opacity-40"></view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
// 跳转到VIP页面
|
||||
const goToVip = () => {
|
||||
uni.navigateTo({
|
||||
url: '/pages/agentVip'
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.card {
|
||||
border-radius: 12px;
|
||||
background-color: white;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
</style>
|
201
src/components/qiun-data-charts/license.md
Normal file
201
src/components/qiun-data-charts/license.md
Normal file
@ -0,0 +1,201 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
1621
src/components/qiun-data-charts/qiun-data-charts.vue
Normal file
1621
src/components/qiun-data-charts/qiun-data-charts.vue
Normal file
File diff suppressed because it is too large
Load Diff
46
src/components/qiun-error/qiun-error.vue
Normal file
46
src/components/qiun-error/qiun-error.vue
Normal file
File diff suppressed because one or more lines are too long
162
src/components/qiun-loading/loading1.vue
Normal file
162
src/components/qiun-loading/loading1.vue
Normal file
@ -0,0 +1,162 @@
|
||||
<template>
|
||||
<view class="container loading1">
|
||||
<view class="shape shape1"></view>
|
||||
<view class="shape shape2"></view>
|
||||
<view class="shape shape3"></view>
|
||||
<view class="shape shape4"></view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'loading1',
|
||||
data() {
|
||||
return {
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped="true">
|
||||
.container {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
position: relative;
|
||||
}
|
||||
.container.loading1 {
|
||||
-webkit-transform: rotate(45deg);
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
|
||||
.container .shape {
|
||||
position: absolute;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
border-radius: 1px;
|
||||
}
|
||||
.container .shape.shape1 {
|
||||
left: 0;
|
||||
background-color: #1890FF;
|
||||
}
|
||||
.container .shape.shape2 {
|
||||
right: 0;
|
||||
background-color: #91CB74;
|
||||
}
|
||||
.container .shape.shape3 {
|
||||
bottom: 0;
|
||||
background-color: #FAC858;
|
||||
}
|
||||
.container .shape.shape4 {
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
background-color: #EE6666;
|
||||
}
|
||||
|
||||
.loading1 .shape1 {
|
||||
-webkit-animation: animation1shape1 0.5s ease 0s infinite alternate;
|
||||
animation: animation1shape1 0.5s ease 0s infinite alternate;
|
||||
}
|
||||
|
||||
@-webkit-keyframes animation1shape1 {
|
||||
from {
|
||||
-webkit-transform: translate(0, 0);
|
||||
transform: translate(0, 0);
|
||||
}
|
||||
to {
|
||||
-webkit-transform: translate(16px, 16px);
|
||||
transform: translate(16px, 16px);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes animation1shape1 {
|
||||
from {
|
||||
-webkit-transform: translate(0, 0);
|
||||
transform: translate(0, 0);
|
||||
}
|
||||
to {
|
||||
-webkit-transform: translate(16px, 16px);
|
||||
transform: translate(16px, 16px);
|
||||
}
|
||||
}
|
||||
.loading1 .shape2 {
|
||||
-webkit-animation: animation1shape2 0.5s ease 0s infinite alternate;
|
||||
animation: animation1shape2 0.5s ease 0s infinite alternate;
|
||||
}
|
||||
|
||||
@-webkit-keyframes animation1shape2 {
|
||||
from {
|
||||
-webkit-transform: translate(0, 0);
|
||||
transform: translate(0, 0);
|
||||
}
|
||||
to {
|
||||
-webkit-transform: translate(-16px, 16px);
|
||||
transform: translate(-16px, 16px);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes animation1shape2 {
|
||||
from {
|
||||
-webkit-transform: translate(0, 0);
|
||||
transform: translate(0, 0);
|
||||
}
|
||||
to {
|
||||
-webkit-transform: translate(-16px, 16px);
|
||||
transform: translate(-16px, 16px);
|
||||
}
|
||||
}
|
||||
.loading1 .shape3 {
|
||||
-webkit-animation: animation1shape3 0.5s ease 0s infinite alternate;
|
||||
animation: animation1shape3 0.5s ease 0s infinite alternate;
|
||||
}
|
||||
|
||||
@-webkit-keyframes animation1shape3 {
|
||||
from {
|
||||
-webkit-transform: translate(0, 0);
|
||||
transform: translate(0, 0);
|
||||
}
|
||||
to {
|
||||
-webkit-transform: translate(16px, -16px);
|
||||
transform: translate(16px, -16px);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes animation1shape3 {
|
||||
from {
|
||||
-webkit-transform: translate(0, 0);
|
||||
transform: translate(0, 0);
|
||||
}
|
||||
to {
|
||||
-webkit-transform: translate(16px, -16px);
|
||||
transform: translate(16px, -16px);
|
||||
}
|
||||
}
|
||||
.loading1 .shape4 {
|
||||
-webkit-animation: animation1shape4 0.5s ease 0s infinite alternate;
|
||||
animation: animation1shape4 0.5s ease 0s infinite alternate;
|
||||
}
|
||||
|
||||
@-webkit-keyframes animation1shape4 {
|
||||
from {
|
||||
-webkit-transform: translate(0, 0);
|
||||
transform: translate(0, 0);
|
||||
}
|
||||
to {
|
||||
-webkit-transform: translate(-16px, -16px);
|
||||
transform: translate(-16px, -16px);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes animation1shape4 {
|
||||
from {
|
||||
-webkit-transform: translate(0, 0);
|
||||
transform: translate(0, 0);
|
||||
}
|
||||
to {
|
||||
-webkit-transform: translate(-16px, -16px);
|
||||
transform: translate(-16px, -16px);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
</style>
|
170
src/components/qiun-loading/loading2.vue
Normal file
170
src/components/qiun-loading/loading2.vue
Normal file
@ -0,0 +1,170 @@
|
||||
<template>
|
||||
<view class="container loading2">
|
||||
<view class="shape shape1"></view>
|
||||
<view class="shape shape2"></view>
|
||||
<view class="shape shape3"></view>
|
||||
<view class="shape shape4"></view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'loading2',
|
||||
data() {
|
||||
return {
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped="true">
|
||||
.container {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.container.loading2 {
|
||||
-webkit-transform: rotate(10deg);
|
||||
transform: rotate(10deg);
|
||||
}
|
||||
.container.loading2 .shape {
|
||||
border-radius: 5px;
|
||||
}
|
||||
.container.loading2{
|
||||
-webkit-animation: rotation 1s infinite;
|
||||
animation: rotation 1s infinite;
|
||||
}
|
||||
|
||||
.container .shape {
|
||||
position: absolute;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
border-radius: 1px;
|
||||
}
|
||||
.container .shape.shape1 {
|
||||
left: 0;
|
||||
background-color: #1890FF;
|
||||
}
|
||||
.container .shape.shape2 {
|
||||
right: 0;
|
||||
background-color: #91CB74;
|
||||
}
|
||||
.container .shape.shape3 {
|
||||
bottom: 0;
|
||||
background-color: #FAC858;
|
||||
}
|
||||
.container .shape.shape4 {
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
background-color: #EE6666;
|
||||
}
|
||||
|
||||
|
||||
.loading2 .shape1 {
|
||||
-webkit-animation: animation2shape1 0.5s ease 0s infinite alternate;
|
||||
animation: animation2shape1 0.5s ease 0s infinite alternate;
|
||||
}
|
||||
|
||||
@-webkit-keyframes animation2shape1 {
|
||||
from {
|
||||
-webkit-transform: translate(0, 0);
|
||||
transform: translate(0, 0);
|
||||
}
|
||||
to {
|
||||
-webkit-transform: translate(20px, 20px);
|
||||
transform: translate(20px, 20px);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes animation2shape1 {
|
||||
from {
|
||||
-webkit-transform: translate(0, 0);
|
||||
transform: translate(0, 0);
|
||||
}
|
||||
to {
|
||||
-webkit-transform: translate(20px, 20px);
|
||||
transform: translate(20px, 20px);
|
||||
}
|
||||
}
|
||||
.loading2 .shape2 {
|
||||
-webkit-animation: animation2shape2 0.5s ease 0s infinite alternate;
|
||||
animation: animation2shape2 0.5s ease 0s infinite alternate;
|
||||
}
|
||||
|
||||
@-webkit-keyframes animation2shape2 {
|
||||
from {
|
||||
-webkit-transform: translate(0, 0);
|
||||
transform: translate(0, 0);
|
||||
}
|
||||
to {
|
||||
-webkit-transform: translate(-20px, 20px);
|
||||
transform: translate(-20px, 20px);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes animation2shape2 {
|
||||
from {
|
||||
-webkit-transform: translate(0, 0);
|
||||
transform: translate(0, 0);
|
||||
}
|
||||
to {
|
||||
-webkit-transform: translate(-20px, 20px);
|
||||
transform: translate(-20px, 20px);
|
||||
}
|
||||
}
|
||||
.loading2 .shape3 {
|
||||
-webkit-animation: animation2shape3 0.5s ease 0s infinite alternate;
|
||||
animation: animation2shape3 0.5s ease 0s infinite alternate;
|
||||
}
|
||||
|
||||
@-webkit-keyframes animation2shape3 {
|
||||
from {
|
||||
-webkit-transform: translate(0, 0);
|
||||
transform: translate(0, 0);
|
||||
}
|
||||
to {
|
||||
-webkit-transform: translate(20px, -20px);
|
||||
transform: translate(20px, -20px);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes animation2shape3 {
|
||||
from {
|
||||
-webkit-transform: translate(0, 0);
|
||||
transform: translate(0, 0);
|
||||
}
|
||||
to {
|
||||
-webkit-transform: translate(20px, -20px);
|
||||
transform: translate(20px, -20px);
|
||||
}
|
||||
}
|
||||
.loading2 .shape4 {
|
||||
-webkit-animation: animation2shape4 0.5s ease 0s infinite alternate;
|
||||
animation: animation2shape4 0.5s ease 0s infinite alternate;
|
||||
}
|
||||
|
||||
@-webkit-keyframes animation2shape4 {
|
||||
from {
|
||||
-webkit-transform: translate(0, 0);
|
||||
transform: translate(0, 0);
|
||||
}
|
||||
to {
|
||||
-webkit-transform: translate(-20px, -20px);
|
||||
transform: translate(-20px, -20px);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes animation2shape4 {
|
||||
from {
|
||||
-webkit-transform: translate(0, 0);
|
||||
transform: translate(0, 0);
|
||||
}
|
||||
to {
|
||||
-webkit-transform: translate(-20px, -20px);
|
||||
transform: translate(-20px, -20px);
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
173
src/components/qiun-loading/loading3.vue
Normal file
173
src/components/qiun-loading/loading3.vue
Normal file
@ -0,0 +1,173 @@
|
||||
<template>
|
||||
<view class="container loading3">
|
||||
<view class="shape shape1"></view>
|
||||
<view class="shape shape2"></view>
|
||||
<view class="shape shape3"></view>
|
||||
<view class="shape shape4"></view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'loading3',
|
||||
data() {
|
||||
return {
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped="true">
|
||||
.container {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.container.loading3 {
|
||||
-webkit-animation: rotation 1s infinite;
|
||||
animation: rotation 1s infinite;
|
||||
}
|
||||
.container.loading3 .shape1 {
|
||||
border-top-left-radius: 10px;
|
||||
}
|
||||
.container.loading3 .shape2 {
|
||||
border-top-right-radius: 10px;
|
||||
}
|
||||
.container.loading3 .shape3 {
|
||||
border-bottom-left-radius: 10px;
|
||||
}
|
||||
.container.loading3 .shape4 {
|
||||
border-bottom-right-radius: 10px;
|
||||
}
|
||||
|
||||
.container .shape {
|
||||
position: absolute;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
border-radius: 1px;
|
||||
}
|
||||
.container .shape.shape1 {
|
||||
left: 0;
|
||||
background-color: #1890FF;
|
||||
}
|
||||
.container .shape.shape2 {
|
||||
right: 0;
|
||||
background-color: #91CB74;
|
||||
}
|
||||
.container .shape.shape3 {
|
||||
bottom: 0;
|
||||
background-color: #FAC858;
|
||||
}
|
||||
.container .shape.shape4 {
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
background-color: #EE6666;
|
||||
}
|
||||
|
||||
.loading3 .shape1 {
|
||||
-webkit-animation: animation3shape1 0.5s ease 0s infinite alternate;
|
||||
animation: animation3shape1 0.5s ease 0s infinite alternate;
|
||||
}
|
||||
|
||||
@-webkit-keyframes animation3shape1 {
|
||||
from {
|
||||
-webkit-transform: translate(0, 0);
|
||||
transform: translate(0, 0);
|
||||
}
|
||||
to {
|
||||
-webkit-transform: translate(5px, 5px);
|
||||
transform: translate(5px, 5px);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes animation3shape1 {
|
||||
from {
|
||||
-webkit-transform: translate(0, 0);
|
||||
transform: translate(0, 0);
|
||||
}
|
||||
to {
|
||||
-webkit-transform: translate(5px, 5px);
|
||||
transform: translate(5px, 5px);
|
||||
}
|
||||
}
|
||||
.loading3 .shape2 {
|
||||
-webkit-animation: animation3shape2 0.5s ease 0s infinite alternate;
|
||||
animation: animation3shape2 0.5s ease 0s infinite alternate;
|
||||
}
|
||||
|
||||
@-webkit-keyframes animation3shape2 {
|
||||
from {
|
||||
-webkit-transform: translate(0, 0);
|
||||
transform: translate(0, 0);
|
||||
}
|
||||
to {
|
||||
-webkit-transform: translate(-5px, 5px);
|
||||
transform: translate(-5px, 5px);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes animation3shape2 {
|
||||
from {
|
||||
-webkit-transform: translate(0, 0);
|
||||
transform: translate(0, 0);
|
||||
}
|
||||
to {
|
||||
-webkit-transform: translate(-5px, 5px);
|
||||
transform: translate(-5px, 5px);
|
||||
}
|
||||
}
|
||||
.loading3 .shape3 {
|
||||
-webkit-animation: animation3shape3 0.5s ease 0s infinite alternate;
|
||||
animation: animation3shape3 0.5s ease 0s infinite alternate;
|
||||
}
|
||||
|
||||
@-webkit-keyframes animation3shape3 {
|
||||
from {
|
||||
-webkit-transform: translate(0, 0);
|
||||
transform: translate(0, 0);
|
||||
}
|
||||
to {
|
||||
-webkit-transform: translate(5px, -5px);
|
||||
transform: translate(5px, -5px);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes animation3shape3 {
|
||||
from {
|
||||
-webkit-transform: translate(0, 0);
|
||||
transform: translate(0, 0);
|
||||
}
|
||||
to {
|
||||
-webkit-transform: translate(5px, -5px);
|
||||
transform: translate(5px, -5px);
|
||||
}
|
||||
}
|
||||
.loading3 .shape4 {
|
||||
-webkit-animation: animation3shape4 0.5s ease 0s infinite alternate;
|
||||
animation: animation3shape4 0.5s ease 0s infinite alternate;
|
||||
}
|
||||
|
||||
@-webkit-keyframes animation3shape4 {
|
||||
from {
|
||||
-webkit-transform: translate(0, 0);
|
||||
transform: translate(0, 0);
|
||||
}
|
||||
to {
|
||||
-webkit-transform: translate(-5px, -5px);
|
||||
transform: translate(-5px, -5px);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes animation3shape4 {
|
||||
from {
|
||||
-webkit-transform: translate(0, 0);
|
||||
transform: translate(0, 0);
|
||||
}
|
||||
to {
|
||||
-webkit-transform: translate(-5px, -5px);
|
||||
transform: translate(-5px, -5px);
|
||||
}
|
||||
}
|
||||
</style>
|
222
src/components/qiun-loading/loading4.vue
Normal file
222
src/components/qiun-loading/loading4.vue
Normal file
@ -0,0 +1,222 @@
|
||||
<template>
|
||||
<view class="container loading5">
|
||||
<view class="shape shape1"></view>
|
||||
<view class="shape shape2"></view>
|
||||
<view class="shape shape3"></view>
|
||||
<view class="shape shape4"></view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'loading5',
|
||||
data() {
|
||||
return {
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped="true">
|
||||
.container {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.container.loading5 .shape {
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
}
|
||||
|
||||
.container .shape {
|
||||
position: absolute;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
border-radius: 1px;
|
||||
}
|
||||
.container .shape.shape1 {
|
||||
left: 0;
|
||||
background-color: #1890FF;
|
||||
}
|
||||
.container .shape.shape2 {
|
||||
right: 0;
|
||||
background-color: #91CB74;
|
||||
}
|
||||
.container .shape.shape3 {
|
||||
bottom: 0;
|
||||
background-color: #FAC858;
|
||||
}
|
||||
.container .shape.shape4 {
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
background-color: #EE6666;
|
||||
}
|
||||
|
||||
.loading5 .shape1 {
|
||||
animation: animation5shape1 2s ease 0s infinite reverse;
|
||||
}
|
||||
|
||||
@-webkit-keyframes animation5shape1 {
|
||||
0% {
|
||||
-webkit-transform: translate(0, 0);
|
||||
transform: translate(0, 0);
|
||||
}
|
||||
25% {
|
||||
-webkit-transform: translate(0, 15px);
|
||||
transform: translate(0, 15px);
|
||||
}
|
||||
50% {
|
||||
-webkit-transform: translate(15px, 15px);
|
||||
transform: translate(15px, 15px);
|
||||
}
|
||||
75% {
|
||||
-webkit-transform: translate(15px, 0);
|
||||
transform: translate(15px, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes animation5shape1 {
|
||||
0% {
|
||||
-webkit-transform: translate(0, 0);
|
||||
transform: translate(0, 0);
|
||||
}
|
||||
25% {
|
||||
-webkit-transform: translate(0, 15px);
|
||||
transform: translate(0, 15px);
|
||||
}
|
||||
50% {
|
||||
-webkit-transform: translate(15px, 15px);
|
||||
transform: translate(15px, 15px);
|
||||
}
|
||||
75% {
|
||||
-webkit-transform: translate(15px, 0);
|
||||
transform: translate(15px, 0);
|
||||
}
|
||||
}
|
||||
.loading5 .shape2 {
|
||||
animation: animation5shape2 2s ease 0s infinite reverse;
|
||||
}
|
||||
|
||||
@-webkit-keyframes animation5shape2 {
|
||||
0% {
|
||||
-webkit-transform: translate(0, 0);
|
||||
transform: translate(0, 0);
|
||||
}
|
||||
25% {
|
||||
-webkit-transform: translate(-15px, 0);
|
||||
transform: translate(-15px, 0);
|
||||
}
|
||||
50% {
|
||||
-webkit-transform: translate(-15px, 15px);
|
||||
transform: translate(-15px, 15px);
|
||||
}
|
||||
75% {
|
||||
-webkit-transform: translate(0, 15px);
|
||||
transform: translate(0, 15px);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes animation5shape2 {
|
||||
0% {
|
||||
-webkit-transform: translate(0, 0);
|
||||
transform: translate(0, 0);
|
||||
}
|
||||
25% {
|
||||
-webkit-transform: translate(-15px, 0);
|
||||
transform: translate(-15px, 0);
|
||||
}
|
||||
50% {
|
||||
-webkit-transform: translate(-15px, 15px);
|
||||
transform: translate(-15px, 15px);
|
||||
}
|
||||
75% {
|
||||
-webkit-transform: translate(0, 15px);
|
||||
transform: translate(0, 15px);
|
||||
}
|
||||
}
|
||||
.loading5 .shape3 {
|
||||
animation: animation5shape3 2s ease 0s infinite reverse;
|
||||
}
|
||||
|
||||
@-webkit-keyframes animation5shape3 {
|
||||
0% {
|
||||
-webkit-transform: translate(0, 0);
|
||||
transform: translate(0, 0);
|
||||
}
|
||||
25% {
|
||||
-webkit-transform: translate(15px, 0);
|
||||
transform: translate(15px, 0);
|
||||
}
|
||||
50% {
|
||||
-webkit-transform: translate(15px, -15px);
|
||||
transform: translate(15px, -15px);
|
||||
}
|
||||
75% {
|
||||
-webkit-transform: translate(0, -15px);
|
||||
transform: translate(0, -15px);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes animation5shape3 {
|
||||
0% {
|
||||
-webkit-transform: translate(0, 0);
|
||||
transform: translate(0, 0);
|
||||
}
|
||||
25% {
|
||||
-webkit-transform: translate(15px, 0);
|
||||
transform: translate(15px, 0);
|
||||
}
|
||||
50% {
|
||||
-webkit-transform: translate(15px, -15px);
|
||||
transform: translate(15px, -15px);
|
||||
}
|
||||
75% {
|
||||
-webkit-transform: translate(0, -15px);
|
||||
transform: translate(0, -15px);
|
||||
}
|
||||
}
|
||||
.loading5 .shape4 {
|
||||
animation: animation5shape4 2s ease 0s infinite reverse;
|
||||
}
|
||||
|
||||
@-webkit-keyframes animation5shape4 {
|
||||
0% {
|
||||
-webkit-transform: translate(0, 0);
|
||||
transform: translate(0, 0);
|
||||
}
|
||||
25% {
|
||||
-webkit-transform: translate(0, -15px);
|
||||
transform: translate(0, -15px);
|
||||
}
|
||||
50% {
|
||||
-webkit-transform: translate(-15px, -15px);
|
||||
transform: translate(-15px, -15px);
|
||||
}
|
||||
75% {
|
||||
-webkit-transform: translate(-15px, 0);
|
||||
transform: translate(-15px, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes animation5shape4 {
|
||||
0% {
|
||||
-webkit-transform: translate(0, 0);
|
||||
transform: translate(0, 0);
|
||||
}
|
||||
25% {
|
||||
-webkit-transform: translate(0, -15px);
|
||||
transform: translate(0, -15px);
|
||||
}
|
||||
50% {
|
||||
-webkit-transform: translate(-15px, -15px);
|
||||
transform: translate(-15px, -15px);
|
||||
}
|
||||
75% {
|
||||
-webkit-transform: translate(-15px, 0);
|
||||
transform: translate(-15px, 0);
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
229
src/components/qiun-loading/loading5.vue
Normal file
229
src/components/qiun-loading/loading5.vue
Normal file
@ -0,0 +1,229 @@
|
||||
<template>
|
||||
<view class="container loading6">
|
||||
<view class="shape shape1"></view>
|
||||
<view class="shape shape2"></view>
|
||||
<view class="shape shape3"></view>
|
||||
<view class="shape shape4"></view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'loading6',
|
||||
data() {
|
||||
return {
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped="true">
|
||||
.container {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.container.loading6 {
|
||||
-webkit-animation: rotation 1s infinite;
|
||||
animation: rotation 1s infinite;
|
||||
}
|
||||
.container.loading6 .shape {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
border-radius: 2px;
|
||||
}
|
||||
.container .shape {
|
||||
position: absolute;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
border-radius: 1px;
|
||||
}
|
||||
.container .shape.shape1 {
|
||||
left: 0;
|
||||
background-color: #1890FF;
|
||||
}
|
||||
.container .shape.shape2 {
|
||||
right: 0;
|
||||
background-color: #91CB74;
|
||||
}
|
||||
.container .shape.shape3 {
|
||||
bottom: 0;
|
||||
background-color: #FAC858;
|
||||
}
|
||||
.container .shape.shape4 {
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
background-color: #EE6666;
|
||||
}
|
||||
|
||||
|
||||
.loading6 .shape1 {
|
||||
-webkit-animation: animation6shape1 2s linear 0s infinite normal;
|
||||
animation: animation6shape1 2s linear 0s infinite normal;
|
||||
}
|
||||
|
||||
@-webkit-keyframes animation6shape1 {
|
||||
0% {
|
||||
-webkit-transform: translate(0, 0);
|
||||
transform: translate(0, 0);
|
||||
}
|
||||
25% {
|
||||
-webkit-transform: translate(0, 18px);
|
||||
transform: translate(0, 18px);
|
||||
}
|
||||
50% {
|
||||
-webkit-transform: translate(18px, 18px);
|
||||
transform: translate(18px, 18px);
|
||||
}
|
||||
75% {
|
||||
-webkit-transform: translate(18px, 0);
|
||||
transform: translate(18px, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes animation6shape1 {
|
||||
0% {
|
||||
-webkit-transform: translate(0, 0);
|
||||
transform: translate(0, 0);
|
||||
}
|
||||
25% {
|
||||
-webkit-transform: translate(0, 18px);
|
||||
transform: translate(0, 18px);
|
||||
}
|
||||
50% {
|
||||
-webkit-transform: translate(18px, 18px);
|
||||
transform: translate(18px, 18px);
|
||||
}
|
||||
75% {
|
||||
-webkit-transform: translate(18px, 0);
|
||||
transform: translate(18px, 0);
|
||||
}
|
||||
}
|
||||
.loading6 .shape2 {
|
||||
-webkit-animation: animation6shape2 2s linear 0s infinite normal;
|
||||
animation: animation6shape2 2s linear 0s infinite normal;
|
||||
}
|
||||
|
||||
@-webkit-keyframes animation6shape2 {
|
||||
0% {
|
||||
-webkit-transform: translate(0, 0);
|
||||
transform: translate(0, 0);
|
||||
}
|
||||
25% {
|
||||
-webkit-transform: translate(-18px, 0);
|
||||
transform: translate(-18px, 0);
|
||||
}
|
||||
50% {
|
||||
-webkit-transform: translate(-18px, 18px);
|
||||
transform: translate(-18px, 18px);
|
||||
}
|
||||
75% {
|
||||
-webkit-transform: translate(0, 18px);
|
||||
transform: translate(0, 18px);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes animation6shape2 {
|
||||
0% {
|
||||
-webkit-transform: translate(0, 0);
|
||||
transform: translate(0, 0);
|
||||
}
|
||||
25% {
|
||||
-webkit-transform: translate(-18px, 0);
|
||||
transform: translate(-18px, 0);
|
||||
}
|
||||
50% {
|
||||
-webkit-transform: translate(-18px, 18px);
|
||||
transform: translate(-18px, 18px);
|
||||
}
|
||||
75% {
|
||||
-webkit-transform: translate(0, 18px);
|
||||
transform: translate(0, 18px);
|
||||
}
|
||||
}
|
||||
.loading6 .shape3 {
|
||||
-webkit-animation: animation6shape3 2s linear 0s infinite normal;
|
||||
animation: animation6shape3 2s linear 0s infinite normal;
|
||||
}
|
||||
|
||||
@-webkit-keyframes animation6shape3 {
|
||||
0% {
|
||||
-webkit-transform: translate(0, 0);
|
||||
transform: translate(0, 0);
|
||||
}
|
||||
25% {
|
||||
-webkit-transform: translate(18px, 0);
|
||||
transform: translate(18px, 0);
|
||||
}
|
||||
50% {
|
||||
-webkit-transform: translate(18px, -18px);
|
||||
transform: translate(18px, -18px);
|
||||
}
|
||||
75% {
|
||||
-webkit-transform: translate(0, -18px);
|
||||
transform: translate(0, -18px);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes animation6shape3 {
|
||||
0% {
|
||||
-webkit-transform: translate(0, 0);
|
||||
transform: translate(0, 0);
|
||||
}
|
||||
25% {
|
||||
-webkit-transform: translate(18px, 0);
|
||||
transform: translate(18px, 0);
|
||||
}
|
||||
50% {
|
||||
-webkit-transform: translate(18px, -18px);
|
||||
transform: translate(18px, -18px);
|
||||
}
|
||||
75% {
|
||||
-webkit-transform: translate(0, -18px);
|
||||
transform: translate(0, -18px);
|
||||
}
|
||||
}
|
||||
.loading6 .shape4 {
|
||||
-webkit-animation: animation6shape4 2s linear 0s infinite normal;
|
||||
animation: animation6shape4 2s linear 0s infinite normal;
|
||||
}
|
||||
|
||||
@-webkit-keyframes animation6shape4 {
|
||||
0% {
|
||||
-webkit-transform: translate(0, 0);
|
||||
transform: translate(0, 0);
|
||||
}
|
||||
25% {
|
||||
-webkit-transform: translate(0, -18px);
|
||||
transform: translate(0, -18px);
|
||||
}
|
||||
50% {
|
||||
-webkit-transform: translate(-18px, -18px);
|
||||
transform: translate(-18px, -18px);
|
||||
}
|
||||
75% {
|
||||
-webkit-transform: translate(-18px, 0);
|
||||
transform: translate(-18px, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes animation6shape4 {
|
||||
0% {
|
||||
-webkit-transform: translate(0, 0);
|
||||
transform: translate(0, 0);
|
||||
}
|
||||
25% {
|
||||
-webkit-transform: translate(0, -18px);
|
||||
transform: translate(0, -18px);
|
||||
}
|
||||
50% {
|
||||
-webkit-transform: translate(-18px, -18px);
|
||||
transform: translate(-18px, -18px);
|
||||
}
|
||||
75% {
|
||||
-webkit-transform: translate(-18px, 0);
|
||||
transform: translate(-18px, 0);
|
||||
}
|
||||
}
|
||||
</style>
|
36
src/components/qiun-loading/qiun-loading.vue
Normal file
36
src/components/qiun-loading/qiun-loading.vue
Normal file
@ -0,0 +1,36 @@
|
||||
<template>
|
||||
<view>
|
||||
<Loading1 v-if="loadingType==1"/>
|
||||
<Loading2 v-if="loadingType==2"/>
|
||||
<Loading3 v-if="loadingType==3"/>
|
||||
<Loading4 v-if="loadingType==4"/>
|
||||
<Loading5 v-if="loadingType==5"/>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Loading1 from "./loading1.vue";
|
||||
import Loading2 from "./loading2.vue";
|
||||
import Loading3 from "./loading3.vue";
|
||||
import Loading4 from "./loading4.vue";
|
||||
import Loading5 from "./loading5.vue";
|
||||
export default {
|
||||
components:{Loading1,Loading2,Loading3,Loading4,Loading5},
|
||||
name: 'qiun-loading',
|
||||
props: {
|
||||
loadingType: {
|
||||
type: Number,
|
||||
default: 2
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
||||
};
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
422
src/components/u-charts/config-echarts.js
Normal file
422
src/components/u-charts/config-echarts.js
Normal file
@ -0,0 +1,422 @@
|
||||
/*
|
||||
* uCharts®
|
||||
* 高性能跨平台图表库,支持H5、APP、小程序(微信/支付宝/百度/头条/QQ/360)、Vue、Taro等支持canvas的框架平台
|
||||
* Copyright (c) 2021 QIUN®秋云 https://www.ucharts.cn All rights reserved.
|
||||
* Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
* 复制使用请保留本段注释,感谢支持开源!
|
||||
*
|
||||
* uCharts®官方网站
|
||||
* https://www.uCharts.cn
|
||||
*
|
||||
* 开源地址:
|
||||
* https://gitee.com/uCharts/uCharts
|
||||
*
|
||||
* uni-app插件市场地址:
|
||||
* http://ext.dcloud.net.cn/plugin?id=271
|
||||
*
|
||||
*/
|
||||
|
||||
// 通用配置项
|
||||
|
||||
// 主题颜色配置:如每个图表类型需要不同主题,请在对应图表类型上更改color属性
|
||||
const color = ['#1890FF', '#91CB74', '#FAC858', '#EE6666', '#73C0DE', '#3CA272', '#FC8452', '#9A60B4', '#ea7ccc'];
|
||||
|
||||
const cfe = {
|
||||
//demotype为自定义图表类型
|
||||
"type": ["pie", "ring", "rose", "funnel", "line", "column", "area", "radar", "gauge","candle","demotype"],
|
||||
//增加自定义图表类型,如果需要categories,请在这里加入您的图表类型例如最后的"demotype"
|
||||
"categories": ["line", "column", "area", "radar", "gauge", "candle","demotype"],
|
||||
//instance为实例变量承载属性,option为eopts承载属性,不要删除
|
||||
"instance": {},
|
||||
"option": {},
|
||||
//下面是自定义format配置,因除H5端外的其他端无法通过props传递函数,只能通过此属性对应下标的方式来替换
|
||||
"formatter":{
|
||||
"tooltipDemo1":function(res){
|
||||
let result = ''
|
||||
for (let i in res) {
|
||||
if (i == 0) {
|
||||
result += res[i].axisValueLabel + '年销售额'
|
||||
}
|
||||
let value = '--'
|
||||
if (res[i].data !== null) {
|
||||
value = res[i].data
|
||||
}
|
||||
// #ifdef H5
|
||||
result += '\n' + res[i].seriesName + ':' + value + ' 万元'
|
||||
// #endif
|
||||
|
||||
// #ifdef APP-PLUS
|
||||
result += '<br/>' + res[i].marker + res[i].seriesName + ':' + value + ' 万元'
|
||||
// #endif
|
||||
}
|
||||
return result;
|
||||
},
|
||||
legendFormat:function(name){
|
||||
return "自定义图例+"+name;
|
||||
},
|
||||
yAxisFormatDemo:function (value, index) {
|
||||
return value + '元';
|
||||
},
|
||||
seriesFormatDemo:function(res){
|
||||
return res.name + '年' + res.value + '元';
|
||||
}
|
||||
},
|
||||
//这里演示了自定义您的图表类型的option,可以随意命名,之后在组件上 type="demotype" 后,组件会调用这个花括号里的option,如果组件上还存在eopts参数,会将demotype与eopts中option合并后渲染图表。
|
||||
"demotype":{
|
||||
"color": color,
|
||||
//在这里填写echarts的option即可
|
||||
|
||||
},
|
||||
//下面是自定义配置,请添加项目所需的通用配置
|
||||
"column": {
|
||||
"color": color,
|
||||
"title": {
|
||||
"text": ''
|
||||
},
|
||||
"tooltip": {
|
||||
"trigger": 'axis'
|
||||
},
|
||||
"grid": {
|
||||
"top": 30,
|
||||
"bottom": 50,
|
||||
"right": 15,
|
||||
"left": 40
|
||||
},
|
||||
"legend": {
|
||||
"bottom": 'left',
|
||||
},
|
||||
"toolbox": {
|
||||
"show": false,
|
||||
},
|
||||
"xAxis": {
|
||||
"type": 'category',
|
||||
"axisLabel": {
|
||||
"color": '#666666'
|
||||
},
|
||||
"axisLine": {
|
||||
"lineStyle": {
|
||||
"color": '#CCCCCC'
|
||||
}
|
||||
},
|
||||
"boundaryGap": true,
|
||||
"data": []
|
||||
},
|
||||
"yAxis": {
|
||||
"type": 'value',
|
||||
"axisTick": {
|
||||
"show": false,
|
||||
},
|
||||
"axisLabel": {
|
||||
"color": '#666666'
|
||||
},
|
||||
"axisLine": {
|
||||
"lineStyle": {
|
||||
"color": '#CCCCCC'
|
||||
}
|
||||
},
|
||||
},
|
||||
"seriesTemplate": {
|
||||
"name": '',
|
||||
"type": 'bar',
|
||||
"data": [],
|
||||
"barwidth": 20,
|
||||
"label": {
|
||||
"show": true,
|
||||
"color": "#666666",
|
||||
"position": 'top',
|
||||
},
|
||||
},
|
||||
},
|
||||
"line": {
|
||||
"color": color,
|
||||
"title": {
|
||||
"text": ''
|
||||
},
|
||||
"tooltip": {
|
||||
"trigger": 'axis'
|
||||
},
|
||||
"grid": {
|
||||
"top": 30,
|
||||
"bottom": 50,
|
||||
"right": 15,
|
||||
"left": 40
|
||||
},
|
||||
"legend": {
|
||||
"bottom": 'left',
|
||||
},
|
||||
"toolbox": {
|
||||
"show": false,
|
||||
},
|
||||
"xAxis": {
|
||||
"type": 'category',
|
||||
"axisLabel": {
|
||||
"color": '#666666'
|
||||
},
|
||||
"axisLine": {
|
||||
"lineStyle": {
|
||||
"color": '#CCCCCC'
|
||||
}
|
||||
},
|
||||
"boundaryGap": true,
|
||||
"data": []
|
||||
},
|
||||
"yAxis": {
|
||||
"type": 'value',
|
||||
"axisTick": {
|
||||
"show": false,
|
||||
},
|
||||
"axisLabel": {
|
||||
"color": '#666666'
|
||||
},
|
||||
"axisLine": {
|
||||
"lineStyle": {
|
||||
"color": '#CCCCCC'
|
||||
}
|
||||
},
|
||||
},
|
||||
"seriesTemplate": {
|
||||
"name": '',
|
||||
"type": 'line',
|
||||
"data": [],
|
||||
"barwidth": 20,
|
||||
"label": {
|
||||
"show": true,
|
||||
"color": "#666666",
|
||||
"position": 'top',
|
||||
},
|
||||
},
|
||||
},
|
||||
"area": {
|
||||
"color": color,
|
||||
"title": {
|
||||
"text": ''
|
||||
},
|
||||
"tooltip": {
|
||||
"trigger": 'axis'
|
||||
},
|
||||
"grid": {
|
||||
"top": 30,
|
||||
"bottom": 50,
|
||||
"right": 15,
|
||||
"left": 40
|
||||
},
|
||||
"legend": {
|
||||
"bottom": 'left',
|
||||
},
|
||||
"toolbox": {
|
||||
"show": false,
|
||||
},
|
||||
"xAxis": {
|
||||
"type": 'category',
|
||||
"axisLabel": {
|
||||
"color": '#666666'
|
||||
},
|
||||
"axisLine": {
|
||||
"lineStyle": {
|
||||
"color": '#CCCCCC'
|
||||
}
|
||||
},
|
||||
"boundaryGap": true,
|
||||
"data": []
|
||||
},
|
||||
"yAxis": {
|
||||
"type": 'value',
|
||||
"axisTick": {
|
||||
"show": false,
|
||||
},
|
||||
"axisLabel": {
|
||||
"color": '#666666'
|
||||
},
|
||||
"axisLine": {
|
||||
"lineStyle": {
|
||||
"color": '#CCCCCC'
|
||||
}
|
||||
},
|
||||
},
|
||||
"seriesTemplate": {
|
||||
"name": '',
|
||||
"type": 'line',
|
||||
"data": [],
|
||||
"areaStyle": {},
|
||||
"label": {
|
||||
"show": true,
|
||||
"color": "#666666",
|
||||
"position": 'top',
|
||||
},
|
||||
},
|
||||
},
|
||||
"pie": {
|
||||
"color": color,
|
||||
"title": {
|
||||
"text": ''
|
||||
},
|
||||
"tooltip": {
|
||||
"trigger": 'item'
|
||||
},
|
||||
"grid": {
|
||||
"top": 40,
|
||||
"bottom": 30,
|
||||
"right": 15,
|
||||
"left": 15
|
||||
},
|
||||
"legend": {
|
||||
"bottom": 'left',
|
||||
},
|
||||
"seriesTemplate": {
|
||||
"name": '',
|
||||
"type": 'pie',
|
||||
"data": [],
|
||||
"radius": '50%',
|
||||
"label": {
|
||||
"show": true,
|
||||
"color": "#666666",
|
||||
"position": 'top',
|
||||
},
|
||||
},
|
||||
},
|
||||
"ring": {
|
||||
"color": color,
|
||||
"title": {
|
||||
"text": ''
|
||||
},
|
||||
"tooltip": {
|
||||
"trigger": 'item'
|
||||
},
|
||||
"grid": {
|
||||
"top": 40,
|
||||
"bottom": 30,
|
||||
"right": 15,
|
||||
"left": 15
|
||||
},
|
||||
"legend": {
|
||||
"bottom": 'left',
|
||||
},
|
||||
"seriesTemplate": {
|
||||
"name": '',
|
||||
"type": 'pie',
|
||||
"data": [],
|
||||
"radius": ['40%', '70%'],
|
||||
"avoidLabelOverlap": false,
|
||||
"label": {
|
||||
"show": true,
|
||||
"color": "#666666",
|
||||
"position": 'top',
|
||||
},
|
||||
"labelLine": {
|
||||
"show": true
|
||||
},
|
||||
},
|
||||
},
|
||||
"rose": {
|
||||
"color": color,
|
||||
"title": {
|
||||
"text": ''
|
||||
},
|
||||
"tooltip": {
|
||||
"trigger": 'item'
|
||||
},
|
||||
"legend": {
|
||||
"top": 'bottom'
|
||||
},
|
||||
"seriesTemplate": {
|
||||
"name": '',
|
||||
"type": 'pie',
|
||||
"data": [],
|
||||
"radius": "55%",
|
||||
"center": ['50%', '50%'],
|
||||
"roseType": 'area',
|
||||
},
|
||||
},
|
||||
"funnel": {
|
||||
"color": color,
|
||||
"title": {
|
||||
"text": ''
|
||||
},
|
||||
"tooltip": {
|
||||
"trigger": 'item',
|
||||
"formatter": "{b} : {c}%"
|
||||
},
|
||||
"legend": {
|
||||
"top": 'bottom'
|
||||
},
|
||||
"seriesTemplate": {
|
||||
"name": '',
|
||||
"type": 'funnel',
|
||||
"left": '10%',
|
||||
"top": 60,
|
||||
"bottom": 60,
|
||||
"width": '80%',
|
||||
"min": 0,
|
||||
"max": 100,
|
||||
"minSize": '0%',
|
||||
"maxSize": '100%',
|
||||
"sort": 'descending',
|
||||
"gap": 2,
|
||||
"label": {
|
||||
"show": true,
|
||||
"position": 'inside'
|
||||
},
|
||||
"labelLine": {
|
||||
"length": 10,
|
||||
"lineStyle": {
|
||||
"width": 1,
|
||||
"type": 'solid'
|
||||
}
|
||||
},
|
||||
"itemStyle": {
|
||||
"bordercolor": '#fff',
|
||||
"borderwidth": 1
|
||||
},
|
||||
"emphasis": {
|
||||
"label": {
|
||||
"fontSize": 20
|
||||
}
|
||||
},
|
||||
"data": [],
|
||||
},
|
||||
},
|
||||
"gauge": {
|
||||
"color": color,
|
||||
"tooltip": {
|
||||
"formatter": '{a} <br/>{b} : {c}%'
|
||||
},
|
||||
"seriesTemplate": {
|
||||
"name": '业务指标',
|
||||
"type": 'gauge',
|
||||
"detail": {"formatter": '{value}%'},
|
||||
"data": [{"value": 50, "name": '完成率'}]
|
||||
},
|
||||
},
|
||||
"candle": {
|
||||
"xAxis": {
|
||||
"data": []
|
||||
},
|
||||
"yAxis": {},
|
||||
"color": color,
|
||||
"title": {
|
||||
"text": ''
|
||||
},
|
||||
"dataZoom": [{
|
||||
"type": 'inside',
|
||||
"xAxisIndex": [0, 1],
|
||||
"start": 10,
|
||||
"end": 100
|
||||
},
|
||||
{
|
||||
"show": true,
|
||||
"xAxisIndex": [0, 1],
|
||||
"type": 'slider',
|
||||
"bottom": 10,
|
||||
"start": 10,
|
||||
"end": 100
|
||||
}
|
||||
],
|
||||
"seriesTemplate": {
|
||||
"name": '',
|
||||
"type": 'k',
|
||||
"data": [],
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
export default cfe;
|
606
src/components/u-charts/config-ucharts.js
Normal file
606
src/components/u-charts/config-ucharts.js
Normal file
@ -0,0 +1,606 @@
|
||||
/*
|
||||
* uCharts®
|
||||
* 高性能跨平台图表库,支持H5、APP、小程序(微信/支付宝/百度/头条/QQ/360)、Vue、Taro等支持canvas的框架平台
|
||||
* Copyright (c) 2021 QIUN®秋云 https://www.ucharts.cn All rights reserved.
|
||||
* Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
* 复制使用请保留本段注释,感谢支持开源!
|
||||
*
|
||||
* uCharts®官方网站
|
||||
* https://www.uCharts.cn
|
||||
*
|
||||
* 开源地址:
|
||||
* https://gitee.com/uCharts/uCharts
|
||||
*
|
||||
* uni-app插件市场地址:
|
||||
* http://ext.dcloud.net.cn/plugin?id=271
|
||||
*
|
||||
*/
|
||||
|
||||
// 主题颜色配置:如每个图表类型需要不同主题,请在对应图表类型上更改color属性
|
||||
const color = ['#1890FF', '#91CB74', '#FAC858', '#EE6666', '#73C0DE', '#3CA272', '#FC8452', '#9A60B4', '#ea7ccc'];
|
||||
|
||||
//事件转换函数,主要用作格式化x轴为时间轴,根据需求自行修改
|
||||
const formatDateTime = (timeStamp, returnType)=>{
|
||||
var date = new Date();
|
||||
date.setTime(timeStamp * 1000);
|
||||
var y = date.getFullYear();
|
||||
var m = date.getMonth() + 1;
|
||||
m = m < 10 ? ('0' + m) : m;
|
||||
var d = date.getDate();
|
||||
d = d < 10 ? ('0' + d) : d;
|
||||
var h = date.getHours();
|
||||
h = h < 10 ? ('0' + h) : h;
|
||||
var minute = date.getMinutes();
|
||||
var second = date.getSeconds();
|
||||
minute = minute < 10 ? ('0' + minute) : minute;
|
||||
second = second < 10 ? ('0' + second) : second;
|
||||
if(returnType == 'full'){return y + '-' + m + '-' + d + ' '+ h +':' + minute + ':' + second;}
|
||||
if(returnType == 'y-m-d'){return y + '-' + m + '-' + d;}
|
||||
if(returnType == 'h:m'){return h +':' + minute;}
|
||||
if(returnType == 'h:m:s'){return h +':' + minute +':' + second;}
|
||||
return [y, m, d, h, minute, second];
|
||||
}
|
||||
|
||||
const cfu = {
|
||||
//demotype为自定义图表类型,一般不需要自定义图表类型,只需要改根节点上对应的类型即可
|
||||
"type":["pie","ring","rose","word","funnel","map","arcbar","line","column","mount","bar","area","radar","gauge","candle","mix","tline","tarea","scatter","bubble","demotype"],
|
||||
"range":["饼状图","圆环图","玫瑰图","词云图","漏斗图","地图","圆弧进度条","折线图","柱状图","山峰图","条状图","区域图","雷达图","仪表盘","K线图","混合图","时间轴折线","时间轴区域","散点图","气泡图","自定义类型"],
|
||||
//增加自定义图表类型,如果需要categories,请在这里加入您的图表类型,例如最后的"demotype"
|
||||
//自定义类型时需要注意"tline","tarea","scatter","bubble"等时间轴(矢量x轴)类图表,没有categories,不需要加入categories
|
||||
"categories":["line","column","mount","bar","area","radar","gauge","candle","mix","demotype"],
|
||||
//instance为实例变量承载属性,不要删除
|
||||
"instance":{},
|
||||
//option为opts及eopts承载属性,不要删除
|
||||
"option":{},
|
||||
//下面是自定义format配置,因除H5端外的其他端无法通过props传递函数,只能通过此属性对应下标的方式来替换
|
||||
"formatter":{
|
||||
"yAxisDemo1":function(val, index, opts){return val+'元'},
|
||||
"yAxisDemo2":function(val, index, opts){return val.toFixed(2)},
|
||||
"xAxisDemo1":function(val, index, opts){return val+'年';},
|
||||
"xAxisDemo2":function(val, index, opts){return formatDateTime(val,'h:m')},
|
||||
"seriesDemo1":function(val, index, series, opts){return val+'元'},
|
||||
"tooltipDemo1":function(item, category, index, opts){
|
||||
if(index==0){
|
||||
return '随便用'+item.data+'年'
|
||||
}else{
|
||||
return '其他我没改'+item.data+'天'
|
||||
}
|
||||
},
|
||||
"pieDemo":function(val, index, series, opts){
|
||||
if(index !== undefined){
|
||||
return series[index].name+':'+series[index].data+'元'
|
||||
}
|
||||
},
|
||||
},
|
||||
//这里演示了自定义您的图表类型的option,可以随意命名,之后在组件上 type="demotype" 后,组件会调用这个花括号里的option,如果组件上还存在opts参数,会将demotype与opts中option合并后渲染图表。
|
||||
"demotype":{
|
||||
//我这里把曲线图当做了自定义图表类型,您可以根据需要随意指定类型或配置
|
||||
"type": "line",
|
||||
"color": color,
|
||||
"padding": [15,10,0,15],
|
||||
"xAxis": {
|
||||
"disableGrid": true,
|
||||
},
|
||||
"yAxis": {
|
||||
"gridType": "dash",
|
||||
"dashLength": 2,
|
||||
},
|
||||
"legend": {
|
||||
},
|
||||
"extra": {
|
||||
"line": {
|
||||
"type": "curve",
|
||||
"width": 2
|
||||
},
|
||||
}
|
||||
},
|
||||
//下面是自定义配置,请添加项目所需的通用配置
|
||||
"pie":{
|
||||
"type": "pie",
|
||||
"color": color,
|
||||
"padding": [5,5,5,5],
|
||||
"extra": {
|
||||
"pie": {
|
||||
"activeOpacity": 0.5,
|
||||
"activeRadius": 10,
|
||||
"offsetAngle": 0,
|
||||
"labelWidth": 15,
|
||||
"border": true,
|
||||
"borderWidth": 3,
|
||||
"borderColor": "#FFFFFF"
|
||||
},
|
||||
}
|
||||
},
|
||||
"ring":{
|
||||
"type": "ring",
|
||||
"color": color,
|
||||
"padding": [5,5,5,5],
|
||||
"rotate": false,
|
||||
"dataLabel": true,
|
||||
"legend": {
|
||||
"show": true,
|
||||
"position": "right",
|
||||
"lineHeight": 25,
|
||||
},
|
||||
"title": {
|
||||
"name": "收益率",
|
||||
"fontSize": 15,
|
||||
"color": "#666666"
|
||||
},
|
||||
"subtitle": {
|
||||
"name": "70%",
|
||||
"fontSize": 25,
|
||||
"color": "#7cb5ec"
|
||||
},
|
||||
"extra": {
|
||||
"ring": {
|
||||
"ringWidth":30,
|
||||
"activeOpacity": 0.5,
|
||||
"activeRadius": 10,
|
||||
"offsetAngle": 0,
|
||||
"labelWidth": 15,
|
||||
"border": true,
|
||||
"borderWidth": 3,
|
||||
"borderColor": "#FFFFFF"
|
||||
},
|
||||
},
|
||||
},
|
||||
"rose":{
|
||||
"type": "rose",
|
||||
"color": color,
|
||||
"padding": [5,5,5,5],
|
||||
"legend": {
|
||||
"show": true,
|
||||
"position": "left",
|
||||
"lineHeight": 25,
|
||||
},
|
||||
"extra": {
|
||||
"rose": {
|
||||
"type": "area",
|
||||
"minRadius": 50,
|
||||
"activeOpacity": 0.5,
|
||||
"activeRadius": 10,
|
||||
"offsetAngle": 0,
|
||||
"labelWidth": 15,
|
||||
"border": false,
|
||||
"borderWidth": 2,
|
||||
"borderColor": "#FFFFFF"
|
||||
},
|
||||
}
|
||||
},
|
||||
"word":{
|
||||
"type": "word",
|
||||
"color": color,
|
||||
"extra": {
|
||||
"word": {
|
||||
"type": "normal",
|
||||
"autoColors": false
|
||||
}
|
||||
}
|
||||
},
|
||||
"funnel":{
|
||||
"type": "funnel",
|
||||
"color": color,
|
||||
"padding": [15,15,0,15],
|
||||
"extra": {
|
||||
"funnel": {
|
||||
"activeOpacity": 0.3,
|
||||
"activeWidth": 10,
|
||||
"border": true,
|
||||
"borderWidth": 2,
|
||||
"borderColor": "#FFFFFF",
|
||||
"fillOpacity": 1,
|
||||
"labelAlign": "right"
|
||||
},
|
||||
}
|
||||
},
|
||||
"map":{
|
||||
"type": "map",
|
||||
"color": color,
|
||||
"padding": [0,0,0,0],
|
||||
"dataLabel": true,
|
||||
"extra": {
|
||||
"map": {
|
||||
"border": true,
|
||||
"borderWidth": 1,
|
||||
"borderColor": "#666666",
|
||||
"fillOpacity": 0.6,
|
||||
"activeBorderColor": "#F04864",
|
||||
"activeFillColor": "#FACC14",
|
||||
"activeFillOpacity": 1
|
||||
},
|
||||
}
|
||||
},
|
||||
"arcbar":{
|
||||
"type": "arcbar",
|
||||
"color": color,
|
||||
"title": {
|
||||
"name": "百分比",
|
||||
"fontSize": 25,
|
||||
"color": "#00FF00"
|
||||
},
|
||||
"subtitle": {
|
||||
"name": "默认标题",
|
||||
"fontSize": 15,
|
||||
"color": "#666666"
|
||||
},
|
||||
"extra": {
|
||||
"arcbar": {
|
||||
"type": "default",
|
||||
"width": 12,
|
||||
"backgroundColor": "#E9E9E9",
|
||||
"startAngle": 0.75,
|
||||
"endAngle": 0.25,
|
||||
"gap": 2
|
||||
}
|
||||
}
|
||||
},
|
||||
"line":{
|
||||
"type": "line",
|
||||
"color": color,
|
||||
"padding": [15,10,0,15],
|
||||
"xAxis": {
|
||||
"disableGrid": true,
|
||||
},
|
||||
"yAxis": {
|
||||
"gridType": "dash",
|
||||
"dashLength": 2,
|
||||
},
|
||||
"legend": {
|
||||
},
|
||||
"extra": {
|
||||
"line": {
|
||||
"type": "straight",
|
||||
"width": 2,
|
||||
"activeType": "hollow"
|
||||
},
|
||||
}
|
||||
},
|
||||
"tline":{
|
||||
"type": "line",
|
||||
"color": color,
|
||||
"padding": [15,10,0,15],
|
||||
"xAxis": {
|
||||
"disableGrid": false,
|
||||
"boundaryGap":"justify",
|
||||
},
|
||||
"yAxis": {
|
||||
"gridType": "dash",
|
||||
"dashLength": 2,
|
||||
"data":[
|
||||
{
|
||||
"min":0,
|
||||
"max":80
|
||||
}
|
||||
]
|
||||
},
|
||||
"legend": {
|
||||
},
|
||||
"extra": {
|
||||
"line": {
|
||||
"type": "curve",
|
||||
"width": 2,
|
||||
"activeType": "hollow"
|
||||
},
|
||||
}
|
||||
},
|
||||
"tarea":{
|
||||
"type": "area",
|
||||
"color": color,
|
||||
"padding": [15,10,0,15],
|
||||
"xAxis": {
|
||||
"disableGrid": true,
|
||||
"boundaryGap":"justify",
|
||||
},
|
||||
"yAxis": {
|
||||
"gridType": "dash",
|
||||
"dashLength": 2,
|
||||
"data":[
|
||||
{
|
||||
"min":0,
|
||||
"max":80
|
||||
}
|
||||
]
|
||||
},
|
||||
"legend": {
|
||||
},
|
||||
"extra": {
|
||||
"area": {
|
||||
"type": "curve",
|
||||
"opacity": 0.2,
|
||||
"addLine": true,
|
||||
"width": 2,
|
||||
"gradient": true,
|
||||
"activeType": "hollow"
|
||||
},
|
||||
}
|
||||
},
|
||||
"column":{
|
||||
"type": "column",
|
||||
"color": color,
|
||||
"padding": [15,15,0,5],
|
||||
"xAxis": {
|
||||
"disableGrid": true,
|
||||
},
|
||||
"yAxis": {
|
||||
"data":[{"min":0}]
|
||||
},
|
||||
"legend": {
|
||||
},
|
||||
"extra": {
|
||||
"column": {
|
||||
"type": "group",
|
||||
"width": 30,
|
||||
"activeBgColor": "#000000",
|
||||
"activeBgOpacity": 0.08
|
||||
},
|
||||
}
|
||||
},
|
||||
"mount":{
|
||||
"type": "mount",
|
||||
"color": color,
|
||||
"padding": [15,15,0,5],
|
||||
"xAxis": {
|
||||
"disableGrid": true,
|
||||
},
|
||||
"yAxis": {
|
||||
"data":[{"min":0}]
|
||||
},
|
||||
"legend": {
|
||||
},
|
||||
"extra": {
|
||||
"mount": {
|
||||
"type": "mount",
|
||||
"widthRatio": 1.5,
|
||||
},
|
||||
}
|
||||
},
|
||||
"bar":{
|
||||
"type": "bar",
|
||||
"color": color,
|
||||
"padding": [15,30,0,5],
|
||||
"xAxis": {
|
||||
"boundaryGap":"justify",
|
||||
"disableGrid":false,
|
||||
"min":0,
|
||||
"axisLine":false
|
||||
},
|
||||
"yAxis": {
|
||||
},
|
||||
"legend": {
|
||||
},
|
||||
"extra": {
|
||||
"bar": {
|
||||
"type": "group",
|
||||
"width": 30,
|
||||
"meterBorde": 1,
|
||||
"meterFillColor": "#FFFFFF",
|
||||
"activeBgColor": "#000000",
|
||||
"activeBgOpacity": 0.08
|
||||
},
|
||||
}
|
||||
},
|
||||
"area":{
|
||||
"type": "area",
|
||||
"color": color,
|
||||
"padding": [15,15,0,15],
|
||||
"xAxis": {
|
||||
"disableGrid": true,
|
||||
},
|
||||
"yAxis": {
|
||||
"gridType": "dash",
|
||||
"dashLength": 2,
|
||||
},
|
||||
"legend": {
|
||||
},
|
||||
"extra": {
|
||||
"area": {
|
||||
"type": "straight",
|
||||
"opacity": 0.2,
|
||||
"addLine": true,
|
||||
"width": 2,
|
||||
"gradient": false,
|
||||
"activeType": "hollow"
|
||||
},
|
||||
}
|
||||
},
|
||||
"radar":{
|
||||
"type": "radar",
|
||||
"color": color,
|
||||
"padding": [5,5,5,5],
|
||||
"dataLabel": false,
|
||||
"legend": {
|
||||
"show": true,
|
||||
"position": "right",
|
||||
"lineHeight": 25,
|
||||
},
|
||||
"extra": {
|
||||
"radar": {
|
||||
"gridType": "radar",
|
||||
"gridColor": "#CCCCCC",
|
||||
"gridCount": 3,
|
||||
"opacity": 0.2,
|
||||
"max": 200,
|
||||
"labelShow": true
|
||||
},
|
||||
}
|
||||
},
|
||||
"gauge":{
|
||||
"type": "gauge",
|
||||
"color": color,
|
||||
"title": {
|
||||
"name": "66Km/H",
|
||||
"fontSize": 25,
|
||||
"color": "#2fc25b",
|
||||
"offsetY": 50
|
||||
},
|
||||
"subtitle": {
|
||||
"name": "实时速度",
|
||||
"fontSize": 15,
|
||||
"color": "#1890ff",
|
||||
"offsetY": -50
|
||||
},
|
||||
"extra": {
|
||||
"gauge": {
|
||||
"type": "default",
|
||||
"width": 30,
|
||||
"labelColor": "#666666",
|
||||
"startAngle": 0.75,
|
||||
"endAngle": 0.25,
|
||||
"startNumber": 0,
|
||||
"endNumber": 100,
|
||||
"labelFormat": "",
|
||||
"splitLine": {
|
||||
"fixRadius": 0,
|
||||
"splitNumber": 10,
|
||||
"width": 30,
|
||||
"color": "#FFFFFF",
|
||||
"childNumber": 5,
|
||||
"childWidth": 12
|
||||
},
|
||||
"pointer": {
|
||||
"width": 24,
|
||||
"color": "auto"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"candle":{
|
||||
"type": "candle",
|
||||
"color": color,
|
||||
"padding": [15,15,0,15],
|
||||
"enableScroll": true,
|
||||
"enableMarkLine": true,
|
||||
"dataLabel": false,
|
||||
"xAxis": {
|
||||
"labelCount": 4,
|
||||
"itemCount": 40,
|
||||
"disableGrid": true,
|
||||
"gridColor": "#CCCCCC",
|
||||
"gridType": "solid",
|
||||
"dashLength": 4,
|
||||
"scrollShow": true,
|
||||
"scrollAlign": "left",
|
||||
"scrollColor": "#A6A6A6",
|
||||
"scrollBackgroundColor": "#EFEBEF"
|
||||
},
|
||||
"yAxis": {
|
||||
},
|
||||
"legend": {
|
||||
},
|
||||
"extra": {
|
||||
"candle": {
|
||||
"color": {
|
||||
"upLine": "#f04864",
|
||||
"upFill": "#f04864",
|
||||
"downLine": "#2fc25b",
|
||||
"downFill": "#2fc25b"
|
||||
},
|
||||
"average": {
|
||||
"show": true,
|
||||
"name": ["MA5","MA10","MA30"],
|
||||
"day": [5,10,20],
|
||||
"color": ["#1890ff","#2fc25b","#facc14"]
|
||||
}
|
||||
},
|
||||
"markLine": {
|
||||
"type": "dash",
|
||||
"dashLength": 5,
|
||||
"data": [
|
||||
{
|
||||
"value": 2150,
|
||||
"lineColor": "#f04864",
|
||||
"showLabel": true
|
||||
},
|
||||
{
|
||||
"value": 2350,
|
||||
"lineColor": "#f04864",
|
||||
"showLabel": true
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"mix":{
|
||||
"type": "mix",
|
||||
"color": color,
|
||||
"padding": [15,15,0,15],
|
||||
"xAxis": {
|
||||
"disableGrid": true,
|
||||
},
|
||||
"yAxis": {
|
||||
"disabled": false,
|
||||
"disableGrid": false,
|
||||
"splitNumber": 5,
|
||||
"gridType": "dash",
|
||||
"dashLength": 4,
|
||||
"gridColor": "#CCCCCC",
|
||||
"padding": 10,
|
||||
"showTitle": true,
|
||||
"data": []
|
||||
},
|
||||
"legend": {
|
||||
},
|
||||
"extra": {
|
||||
"mix": {
|
||||
"column": {
|
||||
"width": 20
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
"scatter":{
|
||||
"type": "scatter",
|
||||
"color":color,
|
||||
"padding":[15,15,0,15],
|
||||
"dataLabel":false,
|
||||
"xAxis": {
|
||||
"disableGrid": false,
|
||||
"gridType":"dash",
|
||||
"splitNumber":5,
|
||||
"boundaryGap":"justify",
|
||||
"min":0
|
||||
},
|
||||
"yAxis": {
|
||||
"disableGrid": false,
|
||||
"gridType":"dash",
|
||||
},
|
||||
"legend": {
|
||||
},
|
||||
"extra": {
|
||||
"scatter": {
|
||||
},
|
||||
}
|
||||
},
|
||||
"bubble":{
|
||||
"type": "bubble",
|
||||
"color":color,
|
||||
"padding":[15,15,0,15],
|
||||
"xAxis": {
|
||||
"disableGrid": false,
|
||||
"gridType":"dash",
|
||||
"splitNumber":5,
|
||||
"boundaryGap":"justify",
|
||||
"min":0,
|
||||
"max":250
|
||||
},
|
||||
"yAxis": {
|
||||
"disableGrid": false,
|
||||
"gridType":"dash",
|
||||
"data":[{
|
||||
"min":0,
|
||||
"max":150
|
||||
}]
|
||||
},
|
||||
"legend": {
|
||||
},
|
||||
"extra": {
|
||||
"bubble": {
|
||||
"border":2,
|
||||
"opacity": 0.5,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default cfu;
|
201
src/components/u-charts/license.md
Normal file
201
src/components/u-charts/license.md
Normal file
@ -0,0 +1,201 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
5
src/components/u-charts/readme.md
Normal file
5
src/components/u-charts/readme.md
Normal file
@ -0,0 +1,5 @@
|
||||
# uCharts JSSDK说明
|
||||
1、如不使用uCharts组件,可直接引用u-charts.js,打包编译后会`自动压缩`,压缩后体积约为`120kb`。
|
||||
2、如果120kb的体积仍需压缩,请手到uCharts官网通过在线定制选择您需要的图表。
|
||||
3、config-ucharts.js为uCharts组件的用户配置文件,升级前请`自行备份config-ucharts.js`文件,以免被强制覆盖。
|
||||
4、config-echarts.js为ECharts组件的用户配置文件,升级前请`自行备份config-echarts.js`文件,以免被强制覆盖。
|
7706
src/components/u-charts/u-charts.js
Normal file
7706
src/components/u-charts/u-charts.js
Normal file
File diff suppressed because it is too large
Load Diff
18
src/components/u-charts/u-charts.min.js
vendored
Normal file
18
src/components/u-charts/u-charts.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
0
src/components/uCharts
Normal file
0
src/components/uCharts
Normal file
16
src/composables/useCount.ts
Normal file
16
src/composables/useCount.ts
Normal file
@ -0,0 +1,16 @@
|
||||
export function useCount() {
|
||||
const count = ref(Math.round(Math.random() * 20))
|
||||
|
||||
function inc() {
|
||||
count.value += 1
|
||||
}
|
||||
function dec() {
|
||||
count.value -= 1
|
||||
}
|
||||
|
||||
return {
|
||||
count,
|
||||
inc,
|
||||
dec,
|
||||
}
|
||||
}
|
10
src/composables/useQuery.ts
Normal file
10
src/composables/useQuery.ts
Normal file
@ -0,0 +1,10 @@
|
||||
import type { MaybeRef } from '@vueuse/core'
|
||||
|
||||
export function useQuery(key?: MaybeRef<string>) {
|
||||
const query = ref<AnyObject>({})
|
||||
onLoad((q) => {
|
||||
query.value = q || {}
|
||||
})
|
||||
const value = computed(() => (key ? query.value[unref(key)] : null))
|
||||
return { query, value }
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
// 可以将此代码放置于项目src/hooks/useColPickerData.ts中
|
||||
import { useCascaderAreaData } from '@vant/area-data'
|
||||
|
||||
export type CascaderOption = {
|
||||
text: string
|
||||
value: string
|
||||
children?: CascaderOption[]
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用'@vant/area-data'作为数据源,构造ColPicker组件的数据
|
||||
* @returns
|
||||
*/
|
||||
export function useColPickerData() {
|
||||
// '@vant/area-data' 数据源
|
||||
const colPickerData: CascaderOption[] = useCascaderAreaData()
|
||||
|
||||
// 根据code查找子节点,不传code则返回所有节点
|
||||
function findChildrenByCode(data: CascaderOption[], code?: string): CascaderOption[] | null {
|
||||
if (!code) {
|
||||
return data
|
||||
}
|
||||
for (const item of data) {
|
||||
if (item.value === code) {
|
||||
return item.children || null
|
||||
}
|
||||
if (item.children) {
|
||||
const childrenResult = findChildrenByCode(item.children, code)
|
||||
if (childrenResult) {
|
||||
return childrenResult
|
||||
}
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
return { colPickerData, findChildrenByCode }
|
||||
}
|
@ -2,8 +2,8 @@
|
||||
import PrivacyModal from '@/components/PrivacyModel.vue'
|
||||
|
||||
const tabbar = ref('index')
|
||||
const menu = reactive([{ title: '首页', icon: 'home', name: 'index' }, { title: '代理', icon: 'share', name: 'agent' }, { title: 'AI律师', icon: 'user-avatar', name: 'ai' }, { title: '我的', icon: 'user', name: 'me' }])
|
||||
|
||||
const menu = reactive([{ title: '首页', icon: 'home', name: 'index' }, { title: 'AI律师', icon: 'chat', name: 'ai' }, { title: '我的', icon: 'user', name: 'me' }])
|
||||
|
||||
function tabChange({ value }) {
|
||||
uni.switchTab({
|
||||
@ -25,14 +25,9 @@ onMounted(() => {
|
||||
})
|
||||
|
||||
function toComplaint() {
|
||||
// 直接使用plus.runtime.openURL在系统浏览器中打开链接
|
||||
// #ifdef APP-PLUS
|
||||
plus.runtime.openURL('https://work.weixin.qq.com/kfid/kfc5c19b2b93a5e73b9');
|
||||
// #endif
|
||||
|
||||
// #ifdef H5
|
||||
window.location.href = 'https://work.weixin.qq.com/kfid/kfc5c19b2b93a5e73b9';
|
||||
// #endif
|
||||
uni.navigateTo({
|
||||
url: '/pages/complaint',
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
@ -45,18 +40,13 @@ export default {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<view class=" min-h-screen from-blue-100 to-white bg-gradient-to-b min-h-screen flex flex-col flex-1 pb-16 box-border">
|
||||
<slot />
|
||||
</view>
|
||||
<slot />
|
||||
<view>
|
||||
<wd-tabbar v-model="tabbar" custom-class="qnc-tabbar" shape="round" safe-area-inset-bottom fixed
|
||||
@change="tabChange">
|
||||
<wd-tabbar-item v-for="(item, index) in menu" :key="index" :name="item.name" :title="item.title"
|
||||
:icon="item.icon" />
|
||||
<wd-tabbar v-model="tabbar" custom-class="qnc-tabbar" shape="round" safe-area-inset-bottom fixed @change="tabChange">
|
||||
<wd-tabbar-item v-for="(item, index) in menu" :key="index" :name="item.name" :title="item.title" :icon="item.icon" />
|
||||
</wd-tabbar>
|
||||
</view>
|
||||
<view
|
||||
class="fixed bottom-24 right-4 z-1000 flex items-center rounded-3xl from-red-500 to-red-400 bg-gradient-to-b px-2 py-1 text-center text-white shadow-2xl">
|
||||
<view class="fixed bottom-24 right-4 z-1000 flex items-center rounded-3xl from-red-500 to-red-400 bg-gradient-to-b px-2 py-1 text-center text-white shadow-2xl">
|
||||
<wd-icon name="warning" class="mr-1" size="18px" />
|
||||
<view class="text-xs" @click="toComplaint">
|
||||
投诉
|
||||
@ -69,6 +59,4 @@ export default {
|
||||
:deep(.qnc-tabbar) {
|
||||
bottom: 16px !important;
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
|
@ -2,15 +2,10 @@ import { createSSRApp } from 'vue'
|
||||
import App from './App.vue'
|
||||
import 'uno.css'
|
||||
import '@/app.scss'
|
||||
import { setupRouterGuard } from '@/utils/routerGuard'
|
||||
|
||||
export function createApp() {
|
||||
const app = createSSRApp(App)
|
||||
|
||||
// 初始化路由守卫
|
||||
setupRouterGuard()
|
||||
|
||||
return {
|
||||
app
|
||||
app,
|
||||
}
|
||||
}
|
||||
|
@ -16,8 +16,7 @@
|
||||
"delay": 0
|
||||
},
|
||||
"modules": {
|
||||
"Payment": {},
|
||||
"Share": {}
|
||||
"Payment": {}
|
||||
},
|
||||
"distribute": {
|
||||
"android": {
|
||||
@ -112,23 +111,5 @@
|
||||
"h5": {
|
||||
"darkmode": false,
|
||||
"themeLocation": "theme.json"
|
||||
},
|
||||
"uts": {
|
||||
"plugins": {
|
||||
"webview": {
|
||||
"version": "1.0.0",
|
||||
"description": "Web视图插件,支持在App内打开网页",
|
||||
"platforms": {
|
||||
"android": {
|
||||
"appid": "__UNI_WEBVIEW_ANDROID",
|
||||
"autostart": false
|
||||
},
|
||||
"ios": {
|
||||
"appid": "__UNI_WEBVIEW_IOS",
|
||||
"autostart": false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
112
src/pages.json
112
src/pages.json
@ -3,56 +3,42 @@
|
||||
{
|
||||
"path": "pages/index",
|
||||
"type": "home",
|
||||
"layout": "home",
|
||||
"style": {
|
||||
"navigationBarTextStyle": "white",
|
||||
"transparentTitle": "always"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/agent",
|
||||
"type": "page",
|
||||
"layout": "home"
|
||||
},
|
||||
{
|
||||
"path": "pages/agentVip",
|
||||
"type": "page",
|
||||
"layout": "page",
|
||||
"title": "代理会员",
|
||||
"agent": true,
|
||||
"auth": true
|
||||
},
|
||||
{
|
||||
"path": "pages/agentVipConfig",
|
||||
"type": "page",
|
||||
"layout": "page",
|
||||
"title": "会员代理报告配置",
|
||||
"agent": true,
|
||||
"auth": true
|
||||
},
|
||||
{
|
||||
"path": "pages/agreement",
|
||||
"type": "page"
|
||||
},
|
||||
{
|
||||
"path": "pages/ai",
|
||||
"type": "page",
|
||||
"layout": "home"
|
||||
},
|
||||
{
|
||||
"path": "pages/invitation",
|
||||
"path": "pages/authorization",
|
||||
"type": "page",
|
||||
"layout": "page",
|
||||
"title": "邀请下级",
|
||||
"auth": true,
|
||||
"agent": true
|
||||
"title": "授权书"
|
||||
},
|
||||
{
|
||||
"path": "pages/invitationAgentApply",
|
||||
"path": "pages/complaint",
|
||||
"type": "page",
|
||||
"layout": "page",
|
||||
"title": "代理申请",
|
||||
"auth": true
|
||||
"title": "投诉服务"
|
||||
},
|
||||
{
|
||||
"path": "pages/example copy",
|
||||
"type": "page",
|
||||
"layout": "page",
|
||||
"title": "报告示例"
|
||||
},
|
||||
{
|
||||
"path": "pages/example",
|
||||
"type": "page",
|
||||
"layout": "page",
|
||||
"title": "示例报告"
|
||||
},
|
||||
{
|
||||
"path": "pages/inquire",
|
||||
"type": "page",
|
||||
"layout": "page",
|
||||
"title": "报告查询"
|
||||
},
|
||||
{
|
||||
"path": "pages/login",
|
||||
@ -66,55 +52,52 @@
|
||||
"layout": "home"
|
||||
},
|
||||
{
|
||||
"path": "pages/promote",
|
||||
"path": "pages/pay",
|
||||
"type": "page",
|
||||
"layout": "page",
|
||||
"title": "推广",
|
||||
"agent": true,
|
||||
"auth": true
|
||||
"title": "全能查收款"
|
||||
},
|
||||
{
|
||||
"path": "pages/promoteDetails",
|
||||
"path": "pages/payb",
|
||||
"type": "page",
|
||||
"layout": "page",
|
||||
"title": "直推报告",
|
||||
"agent": true,
|
||||
"auth": true
|
||||
"title": "全能查收款"
|
||||
},
|
||||
{
|
||||
"path": "pages/privacyPolicy",
|
||||
"type": "page",
|
||||
"layout": "page",
|
||||
"title": "隐私政策"
|
||||
},
|
||||
{
|
||||
"path": "pages/queryHistory",
|
||||
"type": "page",
|
||||
"layout": "page",
|
||||
"title": "历史报告",
|
||||
"auth": true
|
||||
"title": "历史报告"
|
||||
},
|
||||
{
|
||||
"path": "pages/rewardsDetails",
|
||||
"path": "pages/result copy",
|
||||
"type": "page",
|
||||
"layout": "page",
|
||||
"title": "收益明细",
|
||||
"agent": true,
|
||||
"auth": true
|
||||
"title": "报告结果"
|
||||
},
|
||||
{
|
||||
"path": "pages/vip",
|
||||
"type": "page"
|
||||
},
|
||||
{
|
||||
"path": "pages/withdraw",
|
||||
"path": "pages/result",
|
||||
"type": "page",
|
||||
"layout": "page",
|
||||
"title": "提现",
|
||||
"auth": true,
|
||||
"agent": true
|
||||
"title": "报告结果"
|
||||
},
|
||||
{
|
||||
"path": "pages/withdrawDetails",
|
||||
"path": "pages/service",
|
||||
"type": "page",
|
||||
"layout": "page",
|
||||
"title": "提现记录",
|
||||
"auth": true,
|
||||
"agent": true
|
||||
"title": "客户服务"
|
||||
},
|
||||
{
|
||||
"path": "pages/userAgreement",
|
||||
"type": "page",
|
||||
"layout": "page",
|
||||
"title": "用户协议"
|
||||
}
|
||||
],
|
||||
"globalStyle": {
|
||||
@ -138,11 +121,6 @@
|
||||
"text": "",
|
||||
"visible": false
|
||||
},
|
||||
{
|
||||
"pagePath": "pages/agent",
|
||||
"text": "",
|
||||
"visible": false
|
||||
},
|
||||
{
|
||||
"pagePath": "pages/ai",
|
||||
"text": "",
|
||||
|
@ -1,249 +0,0 @@
|
||||
<script setup>
|
||||
import { ref, computed } from 'vue'
|
||||
import { getAgentRevenue } from '@/api/apis'
|
||||
|
||||
// 日期选项映射
|
||||
const dateRangeMap = {
|
||||
today: 'today',
|
||||
week: 'last7d',
|
||||
month: 'last30d'
|
||||
}
|
||||
|
||||
// 直推报告数据
|
||||
const promoteDateOptions = [
|
||||
{ label: '今日', value: 'today' },
|
||||
{ label: '近7天', value: 'week' },
|
||||
{ label: '近1月', value: 'month' }
|
||||
]
|
||||
const selectedPromoteDate = ref('today')
|
||||
|
||||
// 活跃下级数据
|
||||
const activeDateOptions = [
|
||||
{ label: '今日', value: 'today' },
|
||||
{ label: '近7天', value: 'week' },
|
||||
{ label: '近1月', value: 'month' }
|
||||
]
|
||||
const selectedActiveDate = ref('today')
|
||||
|
||||
const data = ref(null)
|
||||
|
||||
// 计算当前直推数据
|
||||
const currentPromoteData = computed(() => {
|
||||
const range = dateRangeMap[selectedPromoteDate.value]
|
||||
return data.value?.direct_push?.[range] || { commission: 0, report: 0 }
|
||||
})
|
||||
|
||||
// 计算当前活跃数据
|
||||
const currentActiveData = computed(() => {
|
||||
const range = dateRangeMap[selectedActiveDate.value]
|
||||
return data.value?.active_reward?.[range] || {
|
||||
active_reward: 0,
|
||||
sub_promote_reward: 0,
|
||||
sub_upgrade_reward: 0,
|
||||
sub_withdraw_reward: 0
|
||||
}
|
||||
})
|
||||
|
||||
const getData = async () => {
|
||||
try {
|
||||
const res = await getAgentRevenue()
|
||||
if (res.code === 200) {
|
||||
data.value = res.data
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
}
|
||||
}
|
||||
|
||||
onBeforeMount(() => {
|
||||
if (uni.getStorageSync('token')) {
|
||||
getData()
|
||||
}
|
||||
})
|
||||
|
||||
// 路由跳转
|
||||
function goToPromoteDetail() {
|
||||
uni.navigateTo({
|
||||
url: '/pages/promoteDetails'
|
||||
})
|
||||
}
|
||||
|
||||
function goToActiveDetail() {
|
||||
uni.navigateTo({
|
||||
url: '/pages/rewardsDetails'
|
||||
})
|
||||
}
|
||||
|
||||
function toWithdraw() {
|
||||
uni.navigateTo({
|
||||
url: '/pages/withdraw'
|
||||
})
|
||||
}
|
||||
|
||||
function toWithdrawDetails() {
|
||||
uni.navigateTo({
|
||||
url: '/pages/withdrawDetails'
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<view class="safe-area-top p-4 min-h-screen">
|
||||
|
||||
<!-- 资产卡片 -->
|
||||
<view class="rounded-xl shadow-lg mb-4 bg-gradient-to-r from-blue-50/70 to-blue-100/50 p-6">
|
||||
<view class="flex justify-between items-center mb-3">
|
||||
<view class="flex items-center">
|
||||
<wd-icon name="balance-pay" class="text-blue-500 text-xl mr-2" />
|
||||
<text class="text-lg font-bold text-gray-800">余额</text>
|
||||
</view>
|
||||
<text class="text-3xl text-blue-600 font-bold">¥ {{ (data?.balance || 0).toFixed(2) }}</text>
|
||||
</view>
|
||||
<view class="text-sm text-gray-500 mb-2">累计收益:¥ {{ (data?.total_earnings || 0).toFixed(2) }}</view>
|
||||
<view class="text-sm text-gray-500 mb-6">冻结余额:¥ {{ (data?.frozen_balance || 0).toFixed(2) }}</view>
|
||||
<view class="grid grid-cols-2 gap-3">
|
||||
<view @click="toWithdraw"
|
||||
class="bg-gradient-to-r from-blue-500 to-blue-400 text-white rounded-full py-2 px-4 shadow-md flex items-center justify-center">
|
||||
<wd-icon name="gold-coin" class="mr-1" />
|
||||
<text>提现</text>
|
||||
</view>
|
||||
<view @click="toWithdrawDetails"
|
||||
class="bg-white/90 text-gray-600 border border-gray-200/50 rounded-full py-2 px-4 shadow-sm flex items-center justify-center">
|
||||
<wd-icon name="notes" class="mr-1" />
|
||||
<text>提现记录</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 直推报告收益 -->
|
||||
<view class="rounded-xl shadow-lg mb-4 bg-gradient-to-r from-blue-50/40 to-cyan-50/50 p-6">
|
||||
<view class="flex justify-between items-center mb-4">
|
||||
<view class="flex items-center">
|
||||
<wd-icon name="balance-list" class="text-blue-400 text-xl mr-2" />
|
||||
<text class="text-lg font-bold text-gray-800">直推报告收益</text>
|
||||
</view>
|
||||
<view class="text-right">
|
||||
<text class="text-2xl text-blue-600 font-bold">¥ {{ (data?.direct_push?.total_commission || 0).toFixed(2)
|
||||
}}</text>
|
||||
<view class="text-sm text-gray-500 mt-1">有效报告 {{ data?.direct_push?.total_report || 0 }} 份</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 日期选择 -->
|
||||
<view class="grid grid-cols-3 gap-2 mb-6">
|
||||
<view v-for="item in promoteDateOptions" :key="item.value" @click="selectedPromoteDate = item.value" :class="[
|
||||
'rounded-full transition-all py-1 px-4 text-sm',
|
||||
selectedPromoteDate === item.value
|
||||
? 'bg-blue-500 text-white shadow-md'
|
||||
: 'bg-white/90 text-gray-600 border border-gray-200/50'
|
||||
]">
|
||||
{{ item.label }}
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="grid grid-cols-2 gap-4 mb-6">
|
||||
<view class="bg-blue-50/60 p-3 rounded-lg backdrop-blur-sm">
|
||||
<view class="flex items-center text-sm text-gray-500">
|
||||
<wd-icon name="gold-coin" class="mr-1" />
|
||||
<text>本日收益</text>
|
||||
</view>
|
||||
<text class="text-xl text-blue-600 font-bold mt-1">¥ {{ currentPromoteData.commission?.toFixed(2) || '0.00'
|
||||
}}</text>
|
||||
</view>
|
||||
<view class="bg-blue-50/60 p-3 rounded-lg backdrop-blur-sm">
|
||||
<view class="flex items-center text-sm text-gray-500">
|
||||
<wd-icon name="description" class="mr-1" />
|
||||
<text>有效报告</text>
|
||||
</view>
|
||||
<text class="text-xl text-blue-600 font-bold mt-1">{{ currentPromoteData.report || 0 }} 份</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="flex items-center justify-between text-blue-500 text-sm font-semibold" @click="goToPromoteDetail">
|
||||
<text>查看收益明细</text>
|
||||
<text class="text-lg">→</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 活跃下级奖励 -->
|
||||
<view class="rounded-xl shadow-lg bg-gradient-to-r from-green-50/40 to-cyan-50/30 p-6">
|
||||
<view class="flex justify-between items-center mb-4">
|
||||
<view class="flex items-center">
|
||||
<wd-icon name="friends" class="text-green-500 text-xl mr-2" />
|
||||
<text class="text-lg font-bold text-gray-800">活跃下级奖励</text>
|
||||
</view>
|
||||
<view class="text-right">
|
||||
<text class="text-2xl text-green-600 font-bold">¥ {{ (data?.active_reward?.total_reward || 0).toFixed(2)
|
||||
}}</text>
|
||||
<view class="text-sm text-gray-500 mt-1">活跃下级 0 位</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 日期选择 -->
|
||||
<view class="grid grid-cols-3 gap-2 mb-6">
|
||||
<view v-for="item in activeDateOptions" :key="item.value" @click="selectedActiveDate = item.value" :class="[
|
||||
'rounded-full transition-all py-1 px-4 text-sm',
|
||||
selectedActiveDate === item.value
|
||||
? 'bg-green-500 text-white shadow-md'
|
||||
: 'bg-white/90 text-gray-600 border border-gray-200/50'
|
||||
]">
|
||||
{{ item.label }}
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="grid grid-cols-2 gap-2 mb-6">
|
||||
<view class="bg-green-50/60 p-3 rounded-lg backdrop-blur-sm">
|
||||
<view class="flex items-center text-sm text-gray-500">
|
||||
<wd-icon name="medal" class="mr-1" />
|
||||
<text>本日奖励</text>
|
||||
</view>
|
||||
<text class="text-xl text-green-600 font-bold mt-1">¥ {{ (currentActiveData.active_reward || 0).toFixed(2)
|
||||
}}</text>
|
||||
</view>
|
||||
<view class="bg-green-50/60 p-3 rounded-lg backdrop-blur-sm">
|
||||
<view class="flex items-center text-sm text-gray-500">
|
||||
<wd-icon name="discount" class="mr-1" />
|
||||
<text>下级推广奖励</text>
|
||||
</view>
|
||||
<text class="text-xl text-green-600 font-bold mt-1">¥ {{ (currentActiveData.sub_promote_reward ||
|
||||
0).toFixed(2) }}</text>
|
||||
</view>
|
||||
<view class="bg-green-50/60 p-3 rounded-lg backdrop-blur-sm">
|
||||
<view class="flex items-center text-sm text-gray-500">
|
||||
<wd-icon name="contact" class="mr-1" />
|
||||
<text>新增活跃奖励</text>
|
||||
</view>
|
||||
<text class="text-xl text-green-600 font-bold mt-1">¥ {{ (currentActiveData.sub_upgrade_reward ||
|
||||
0).toFixed(2) }}</text>
|
||||
</view>
|
||||
<view class="bg-green-50/60 p-3 rounded-lg backdrop-blur-sm">
|
||||
<view class="flex items-center text-sm text-gray-500">
|
||||
<wd-icon name="fire" class="mr-1" />
|
||||
<text>下级转化奖励</text>
|
||||
</view>
|
||||
<text class="text-xl text-green-600 font-bold mt-1">¥ {{ (currentActiveData.sub_withdraw_reward ||
|
||||
0).toFixed(2) }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="flex items-center justify-between text-green-500 text-sm font-semibold" @click="goToActiveDetail">
|
||||
<text>查看奖励明细</text>
|
||||
<text class="text-lg">→</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
button {
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
</style>
|
||||
|
||||
<route lang="json">{
|
||||
"layout": "home"
|
||||
}</route>
|
@ -1,63 +0,0 @@
|
||||
<template>
|
||||
<view class="relative">
|
||||
<image class="w-full" src="/static/image/vip_bg.png" mode="widthFix" />
|
||||
<view @click="toService" class="service-btn">
|
||||
点击马上报名
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
function toService() {
|
||||
// 直接使用plus.runtime.openURL在系统浏览器中打开链接
|
||||
// #ifdef APP-PLUS
|
||||
plus.runtime.openURL('https://work.weixin.qq.com/kfid/kfc5c19b2b93a5e73b9');
|
||||
// #endif
|
||||
|
||||
// #ifdef H5
|
||||
window.location.href = 'https://work.weixin.qq.com/kfid/kfc5c19b2b93a5e73b9';
|
||||
// #endif
|
||||
|
||||
// #ifdef MP
|
||||
uni.navigateTo({
|
||||
url: '/pages/agreement?url=' + encodeURIComponent('https://work.weixin.qq.com/kfid/kfc5c19b2b93a5e73b9')
|
||||
});
|
||||
// #endif
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.relative {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.service-btn {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
bottom: 600rpx;
|
||||
transform: translateX(-50%);
|
||||
background: linear-gradient(to right, #2d3748, #000000, #2d3748);
|
||||
padding: 10rpx 20rpx;
|
||||
border-radius: 16rpx;
|
||||
color: #ffffff;
|
||||
font-size: 48rpx;
|
||||
font-weight: bold;
|
||||
box-shadow: 0 0 30rpx rgba(255, 255, 255, 0.3);
|
||||
transition: transform 0.3s;
|
||||
|
||||
&:active {
|
||||
transform: translateX(-50%) scale(1.05);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<route lang="json">
|
||||
{
|
||||
"layout": "page",
|
||||
"title": "代理会员",
|
||||
"agent": true,
|
||||
"auth": true
|
||||
}
|
||||
</route>
|
@ -1,504 +0,0 @@
|
||||
<template>
|
||||
<view class="p-4 mx-auto min-h-screen">
|
||||
<!-- 标题部分 -->
|
||||
<view class="card mb-4 p-4 bg-gradient-to-r from-blue-500 to-blue-600 rounded-lg shadow-lg text-white">
|
||||
<text class="text-2xl font-extrabold mb-2 block">专业报告定价配置</text>
|
||||
<text class="opacity-90 block">请选择报告类型并设置定价策略,助您实现精准定价</text>
|
||||
</view>
|
||||
|
||||
<view class="mb-4 bg-white rounded-lg overflow-hidden px-4 flex items-center justify-between">
|
||||
<span class="text-blue-600 font-medium text-sm">📝 选择报告</span>
|
||||
<wd-picker custom-class="flex-1" v-model="selectedReportText" :columns="reportOptions" title="选择报告类型"
|
||||
@confirm="onConfirm" />
|
||||
</view>
|
||||
|
||||
<view v-if="selectedReportText" class="space-y-6">
|
||||
<!-- 配置卡片 -->
|
||||
<view class="card">
|
||||
<!-- 当前报告标题 -->
|
||||
<view class="flex items-center mb-6">
|
||||
<text class="text-xl font-semibold text-gray-800">
|
||||
{{ selectedReportText }}配置
|
||||
</text>
|
||||
</view>
|
||||
|
||||
<!-- 显示当前产品的基础成本信息 -->
|
||||
<view v-if="productConfigData && productConfigData.cost_price"
|
||||
class="px-4 py-2 mb-4 bg-gray-50 border border-gray-200 rounded-lg shadow-sm">
|
||||
<text class="text-lg font-semibold text-gray-700 block">报告基础配置信息</text>
|
||||
<view class="mt-1 text-sm text-gray-600">
|
||||
<text class="block">基础成本价:<text class="font-medium">{{ productConfigData.cost_price }}</text> 元</text>
|
||||
<text class="block">最高设定金额上限:<text class="font-medium">{{ productConfigData.price_range_max }}</text>
|
||||
元</text>
|
||||
<text class="block">最高设定比例上限:<text class="font-medium">{{ priceRatioMax }}</text> %</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 分隔线 -->
|
||||
<view class="my-6 flex items-center justify-center">
|
||||
<view class="bg-gray-200 h-px flex-1"></view>
|
||||
<text class="mx-2 text-gray-400 text-sm">成本策略配置</text>
|
||||
<view class="bg-gray-200 h-px flex-1"></view>
|
||||
</view>
|
||||
<!-- 表单部分 -->
|
||||
<wd-form>
|
||||
<!-- 加价金额 -->
|
||||
|
||||
<wd-form-item label="加价金额" prop="price_increase_amount">
|
||||
<wd-input v-model="configData.price_increase_amount" type="number" placeholder="0"
|
||||
@blur="validateDecimal('price_increase_amount')" />
|
||||
</wd-form-item>
|
||||
<view class="text-xs text-gray-400 mt-1">
|
||||
<text class="block">提示:最大加价金额为{{ priceIncreaseAmountMax }}元</text>
|
||||
<text class="block">说明:加价金额是在基础成本价上增加的额外费用,决定下级报告的最低定价,您将获得所有输入的金额利润。</text>
|
||||
</view>
|
||||
|
||||
<!-- 分隔线 -->
|
||||
<view class="my-6 flex items-center justify-center">
|
||||
<view class="bg-gray-200 h-px flex-1"></view>
|
||||
<text class="mx-2 text-gray-400 text-sm">定价策略配置</text>
|
||||
<view class="bg-gray-200 h-px flex-1"></view>
|
||||
</view>
|
||||
|
||||
<!-- 定价区间最低 -->
|
||||
<wd-form-item label="定价区间最低" prop="price_range_from">
|
||||
<wd-input v-model="configData.price_range_from" type="number" placeholder="0"
|
||||
@blur="() => { validateDecimal('price_range_from'); validateRange(); }" />
|
||||
</wd-form-item>
|
||||
<view class="text-xs text-gray-400 mt-1">
|
||||
<text class="block">提示:定价区间最低金额不能低于(基础最低 {{ productConfigData?.price_range_min || 0 }}元 + 加价金额)</text>
|
||||
<text class="block">说明:设定的定价区间最低金额为定价区间的起始值,若下级设定的报告金额在区间内,则区间内部分将按比例获得收益。</text>
|
||||
</view>
|
||||
|
||||
<!-- 定价区间最高 -->
|
||||
<wd-form-item label="定价区间最高" prop="price_range_to">
|
||||
<wd-input v-model="configData.price_range_to" type="number" placeholder="0"
|
||||
@blur="() => { validateDecimal('price_range_to'); validateRange(); }" />
|
||||
</wd-form-item>
|
||||
<view class="text-xs text-gray-400 mt-1">
|
||||
<text class="block">提示:定价区间最高金额不能超过上限({{ productConfigData?.price_range_max || 0 }}元)和大于定价区间最低金额({{
|
||||
priceIncreaseMax
|
||||
}}元)</text>
|
||||
<text class="block">说明:设定的定价区间最高金额为定价区间的结束值,若下级设定的报告金额在区间内,则区间内部分将按比例获得收益。</text>
|
||||
</view>
|
||||
|
||||
<!-- 收取比例 -->
|
||||
<wd-form-item label="收取比例" prop="price_ratio">
|
||||
<wd-input v-model="configData.price_ratio" type="number" placeholder="0" @blur="validateRatio" />
|
||||
</wd-form-item>
|
||||
<view class="text-xs text-gray-400 mt-1">
|
||||
<text class="block">提示:最大收取比例为{{ priceRatioMax }}%</text>
|
||||
<text class="block">说明:收取比例表示对定价区间内(即报告金额超过最低金额,小于最高金额的部分)的金额,按此比例进行利润分成。</text>
|
||||
</view>
|
||||
</wd-form>
|
||||
</view>
|
||||
|
||||
<!-- 保存按钮 -->
|
||||
<button type="primary" class="bg-blue-500 text-white py-1 rounded-xl w-full" @click="handleSubmit">
|
||||
保存当前报告配置
|
||||
</button>
|
||||
</view>
|
||||
|
||||
<!-- 未选择提示 -->
|
||||
<view v-else class="text-center py-12">
|
||||
<text class="text-gray-400 text-4xl block mb-4">⚠️</text>
|
||||
<text class="text-gray-500 block">请先选择需要配置的报告类型</text>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, computed, onMounted, watch } from 'vue'
|
||||
import { getAgentMembershipUserConfig, saveAgentMembershipUserConfig } from '@/apis/agent'
|
||||
|
||||
// 报告类型选项
|
||||
const reportOptions = [
|
||||
{ label: '人事背调', value: 1 },
|
||||
{ label: '老板企业报告', value: 2 },
|
||||
{ label: '家政风险', value: 3 },
|
||||
{ label: '婚恋风险', value: 4 },
|
||||
{ label: '贷前背调', value: 5 },
|
||||
{ label: '租赁风险', value: 6 },
|
||||
{ label: '个人风险', value: 7 },
|
||||
]
|
||||
|
||||
// 状态管理
|
||||
const showPicker = ref(false)
|
||||
const selectedReportId = ref(1)
|
||||
const selectedReportText = ref('人事背调')
|
||||
|
||||
const configData = ref({})
|
||||
const productConfigData = ref({})
|
||||
const priceIncreaseMax = ref(null)
|
||||
const priceIncreaseAmountMax = ref(null)
|
||||
const priceRatioMax = ref(null)
|
||||
const rangeError = ref(false)
|
||||
const ratioError = ref(false)
|
||||
const increaseError = ref(false)
|
||||
|
||||
// 金额输入格式验证:确保最多两位小数
|
||||
const validateDecimal = (field) => {
|
||||
console.log(`validateDecimal开始: field=${field}, 值=${configData.value[field]}`)
|
||||
const value = configData.value[field]
|
||||
if (value === null || value === undefined) {
|
||||
console.log(`validateDecimal: ${field}为空,退出验证`)
|
||||
return
|
||||
}
|
||||
|
||||
const numValue = Number(value)
|
||||
if (isNaN(numValue)) {
|
||||
console.log(`validateDecimal: ${field}无法转换为数字,设置为null`)
|
||||
configData.value[field] = null
|
||||
return
|
||||
}
|
||||
|
||||
const fixedValue = parseFloat(numValue.toFixed(2))
|
||||
console.log(`validateDecimal: ${field}原值=${numValue},处理后=${fixedValue}`)
|
||||
configData.value[field] = fixedValue
|
||||
|
||||
if (field === 'price_increase_amount') {
|
||||
console.log(`validateDecimal: 检查加价金额上限 ${fixedValue} vs ${priceIncreaseAmountMax.value}`)
|
||||
if (fixedValue > priceIncreaseAmountMax.value) {
|
||||
configData.value[field] = priceIncreaseAmountMax.value
|
||||
console.log(`validateDecimal: 加价金额超过上限,已修正为${priceIncreaseAmountMax.value}`)
|
||||
uni.showToast({
|
||||
title: `加价金额最大为${priceIncreaseAmountMax.value}元`,
|
||||
icon: 'none'
|
||||
})
|
||||
increaseError.value = true
|
||||
setTimeout(() => {
|
||||
increaseError.value = false
|
||||
}, 2000)
|
||||
} else {
|
||||
increaseError.value = false
|
||||
}
|
||||
// 当加价金额改变后,重新验证价格区间
|
||||
validateRange()
|
||||
}
|
||||
console.log(`validateDecimal结束: ${field}最终值=${configData.value[field]}`)
|
||||
}
|
||||
|
||||
// 价格区间验证
|
||||
const validateRange = () => {
|
||||
console.log('validateRange开始:',
|
||||
`最低=${configData.value.price_range_from}`,
|
||||
`最高=${configData.value.price_range_to}`)
|
||||
|
||||
// if (configData.value.price_range_from === null || configData.value.price_range_to === null) {
|
||||
// console.log('validateRange: 价格区间值为null,退出验证')
|
||||
// rangeError.value = false
|
||||
// return
|
||||
// }
|
||||
|
||||
if (isNaN(configData.value.price_range_from) || isNaN(configData.value.price_range_to)) {
|
||||
console.log('validateRange: 价格区间值非数字,退出验证')
|
||||
return
|
||||
}
|
||||
|
||||
const additional = configData.value.price_increase_amount || 0
|
||||
console.log(`validateRange: 加价金额=${additional}`)
|
||||
|
||||
const minAllowed = parseFloat(
|
||||
(Number(productConfigData.value.cost_price) + Number(additional)).toFixed(2)
|
||||
) // 使用成本价作为最小值
|
||||
const maxAllowed = productConfigData.value.price_range_max // 使用产品配置中的最大价格作为最大值
|
||||
|
||||
console.log(`validateRange: 最低允许=${minAllowed}, 最高允许=${maxAllowed}`)
|
||||
|
||||
// 检查最低金额
|
||||
if (configData.value.price_range_from < minAllowed) {
|
||||
console.log(`validateRange: 定价区间最低金额(${configData.value.price_range_from})小于允许最低值(${minAllowed}),进行修正`)
|
||||
configData.value.price_range_from = minAllowed
|
||||
uni.showToast({
|
||||
title: `定价区间最低金额不能低于成本价 ${minAllowed}元`,
|
||||
icon: 'none'
|
||||
})
|
||||
rangeError.value = true
|
||||
closeRangeError()
|
||||
|
||||
configData.value.price_range_to = parseFloat(
|
||||
(Number(configData.value.price_range_from) + Number(priceIncreaseMax.value)).toFixed(2)
|
||||
)
|
||||
console.log(`validateRange: 已调整最高金额为 ${configData.value.price_range_to}`)
|
||||
return
|
||||
}
|
||||
|
||||
// 检查最高金额是否小于最低金额
|
||||
if (configData.value.price_range_to < configData.value.price_range_from) {
|
||||
console.log(`validateRange: 定价区间最高金额(${configData.value.price_range_to})小于最低金额(${configData.value.price_range_from}),进行修正`)
|
||||
uni.showToast({
|
||||
title: '定价区间最高金额不能低于定价区间最低金额',
|
||||
icon: 'none'
|
||||
})
|
||||
if (configData.value.price_range_from + priceIncreaseMax.value > maxAllowed) {
|
||||
configData.value.price_range_to = maxAllowed
|
||||
console.log(`validateRange: 最高值已修正为最大允许值 ${maxAllowed}`)
|
||||
} else {
|
||||
configData.value.price_range_to = configData.value.price_range_from + priceIncreaseMax.value
|
||||
console.log(`validateRange: 最高值已修正为最低金额+最大增加值 ${configData.value.price_range_to}`)
|
||||
}
|
||||
rangeError.value = true
|
||||
closeRangeError()
|
||||
return
|
||||
}
|
||||
|
||||
// 检查差值
|
||||
const diff = parseFloat(
|
||||
(configData.value.price_range_to - configData.value.price_range_from).toFixed(2)
|
||||
)
|
||||
console.log(`validateRange: 价格区间差值=${diff}, 最大允许差值=${priceIncreaseMax.value}`)
|
||||
|
||||
if (diff > priceIncreaseMax.value) {
|
||||
console.log(`validateRange: 价格区间差值超过最大允许值,进行修正`)
|
||||
uni.showToast({
|
||||
title: `价格区间最大差值为${priceIncreaseMax.value}元`,
|
||||
icon: 'none'
|
||||
})
|
||||
configData.value.price_range_to = parseFloat(
|
||||
(Number(configData.value.price_range_from) + Number(priceIncreaseMax.value)).toFixed(2)
|
||||
)
|
||||
console.log(`validateRange: 已调整最高金额为 ${configData.value.price_range_to}`)
|
||||
closeRangeError()
|
||||
return
|
||||
}
|
||||
|
||||
// 检查最高金额是否超过上限
|
||||
if (configData.value.price_range_to > maxAllowed) {
|
||||
console.log(`validateRange: 定价区间最高金额(${configData.value.price_range_to})超过上限(${maxAllowed}),进行修正`)
|
||||
configData.value.price_range_to = maxAllowed
|
||||
uni.showToast({
|
||||
title: `定价区间最高金额不能超过 ${maxAllowed}元`,
|
||||
icon: 'none'
|
||||
})
|
||||
closeRangeError()
|
||||
}
|
||||
|
||||
if (!rangeError.value) {
|
||||
rangeError.value = false
|
||||
}
|
||||
|
||||
console.log('validateRange结束:',
|
||||
`最终最低=${configData.value.price_range_from}`,
|
||||
`最终最高=${configData.value.price_range_to}`)
|
||||
}
|
||||
|
||||
// 收取比例验证(修改为保留两位小数,不再四舍五入取整)
|
||||
const validateRatio = () => {
|
||||
console.log(`validateRatio开始: 值=${configData.value.price_ratio}`)
|
||||
let value = configData.value.price_ratio
|
||||
if (value === null || value === undefined) {
|
||||
console.log('validateRatio: 值为空,退出验证')
|
||||
return
|
||||
}
|
||||
|
||||
const numValue = Number(value)
|
||||
if (isNaN(numValue)) {
|
||||
console.log('validateRatio: 值无法转换为数字,设置为null')
|
||||
configData.value.price_ratio = null
|
||||
ratioError.value = true
|
||||
return
|
||||
}
|
||||
|
||||
console.log(`validateRatio: 检查比例范围 ${numValue} vs 最大值${priceRatioMax.value}`)
|
||||
if (numValue > priceRatioMax.value) {
|
||||
console.log(`validateRatio: 比例超过最大值,已修正为${priceRatioMax.value}`)
|
||||
configData.value.price_ratio = priceRatioMax.value
|
||||
uni.showToast({
|
||||
title: `收取比例最大为${priceRatioMax.value}%`,
|
||||
icon: 'none'
|
||||
})
|
||||
ratioError.value = true
|
||||
setTimeout(() => {
|
||||
ratioError.value = false
|
||||
}, 1000)
|
||||
} else if (numValue < 0) {
|
||||
console.log('validateRatio: 比例小于0,已修正为0')
|
||||
configData.value.price_ratio = 0
|
||||
ratioError.value = true
|
||||
} else {
|
||||
configData.value.price_ratio = parseFloat(numValue.toFixed(2))
|
||||
ratioError.value = false
|
||||
}
|
||||
|
||||
console.log(`validateRatio结束: 最终值=${configData.value.price_ratio}`)
|
||||
}
|
||||
|
||||
// 获取配置
|
||||
const getConfig = async () => {
|
||||
try {
|
||||
console.log(`getConfig开始: 获取产品ID=${selectedReportId.value}的配置`)
|
||||
const res = await getAgentMembershipUserConfig({ product_id: selectedReportId.value })
|
||||
if (res.code === 200) {
|
||||
const respConfigData = res.data.agent_membership_user_config
|
||||
console.log("respConfigData", respConfigData)
|
||||
configData.value = {
|
||||
id: respConfigData.product_id,
|
||||
price_range_from: respConfigData.price_range_from || null,
|
||||
price_range_to: respConfigData.price_range_to || null,
|
||||
price_ratio: respConfigData.price_ratio * 100 || null, // 转换为百分比
|
||||
price_increase_amount: respConfigData.price_increase_amount || null,
|
||||
}
|
||||
|
||||
productConfigData.value = res.data.product_config
|
||||
// 设置动态限制值
|
||||
priceIncreaseMax.value = res.data.price_increase_max
|
||||
priceIncreaseAmountMax.value = res.data.price_increase_amount
|
||||
priceRatioMax.value = res.data.price_ratio * 100
|
||||
|
||||
console.log('getConfig: 配置加载成功',
|
||||
`最大差值=${priceIncreaseMax.value}`,
|
||||
`最大加价=${priceIncreaseAmountMax.value}`,
|
||||
`最大比例=${priceRatioMax.value}%`)
|
||||
console.log('getConfig: 当前配置', configData.value)
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("getConfig错误:", error)
|
||||
uni.showToast({
|
||||
title: '配置加载失败',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 提交处理
|
||||
const handleSubmit = async () => {
|
||||
try {
|
||||
if (!finalValidation()) {
|
||||
return
|
||||
}
|
||||
// 前端数据转换
|
||||
const submitData = {
|
||||
product_id: configData.value.id,
|
||||
price_range_from: configData.value.price_range_from || 0,
|
||||
price_range_to: configData.value.price_range_to || 0,
|
||||
price_ratio: (configData.value.price_ratio || 0) / 100, // 转换为小数
|
||||
price_increase_amount: configData.value.price_increase_amount || 0,
|
||||
}
|
||||
|
||||
const res = await saveAgentMembershipUserConfig(submitData)
|
||||
|
||||
if (res.code === 200) {
|
||||
uni.showToast({
|
||||
title: '保存成功',
|
||||
icon: 'success'
|
||||
})
|
||||
getConfig()
|
||||
}
|
||||
} catch (error) {
|
||||
uni.showToast({
|
||||
title: '保存失败,请稍后重试',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 最终验证函数
|
||||
const finalValidation = () => {
|
||||
// 校验最低金额:不能为空且大于0
|
||||
if (!configData.value.price_range_from || configData.value.price_range_from <= 0) {
|
||||
uni.showToast({
|
||||
title: "定价区间最低金额不能为空",
|
||||
icon: 'none'
|
||||
})
|
||||
return false
|
||||
}
|
||||
// 校验最高金额:不能为空且大于0
|
||||
if (!configData.value.price_range_to || configData.value.price_range_to <= 0) {
|
||||
uni.showToast({
|
||||
title: "定价区间最高金额不能为空",
|
||||
icon: 'none'
|
||||
})
|
||||
return false
|
||||
}
|
||||
// 校验收取比例:不能为空且大于0
|
||||
if (!configData.value.price_ratio || configData.value.price_ratio <= 0) {
|
||||
uni.showToast({
|
||||
title: "收取比例不能为空",
|
||||
icon: 'none'
|
||||
})
|
||||
return false
|
||||
}
|
||||
// 验证最低金额必须小于最高金额
|
||||
if (configData.value.price_range_from >= configData.value.price_range_to) {
|
||||
uni.showToast({
|
||||
title: "定价区间最低金额必须小于定价区间最高金额",
|
||||
icon: 'none'
|
||||
})
|
||||
return false
|
||||
}
|
||||
// 验证价格区间差值不能超过最大允许差值
|
||||
const finalDiff = parseFloat(
|
||||
(configData.value.price_range_to - configData.value.price_range_from).toFixed(2)
|
||||
)
|
||||
if (finalDiff > priceIncreaseMax.value) {
|
||||
uni.showToast({
|
||||
title: `价格区间最大差值为${priceIncreaseMax.value}元`,
|
||||
icon: 'none'
|
||||
})
|
||||
return false
|
||||
}
|
||||
// 验证最高金额不能超过产品配置中设定的上限
|
||||
if (configData.value.price_range_to > productConfigData.value.price_range_max) {
|
||||
uni.showToast({
|
||||
title: `定价区间最高金额不能超过${productConfigData.value.price_range_max}元`,
|
||||
icon: 'none'
|
||||
})
|
||||
return false
|
||||
}
|
||||
// 验证最低金额不能低于成本价+加价金额(加价金额允许为空)
|
||||
const additional = configData.value.price_increase_amount || 0
|
||||
if (configData.value.price_range_from < productConfigData.value.cost_price + additional) {
|
||||
uni.showToast({
|
||||
title: `定价区间最低金额不能低于成本价${productConfigData.value.cost_price + additional}元`,
|
||||
icon: 'none'
|
||||
})
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// 选择器确认
|
||||
const onConfirm = (e) => {
|
||||
const { selectedItems } = e
|
||||
selectedReportId.value = selectedItems.value
|
||||
selectedReportText.value = selectedItems.label
|
||||
showPicker.value = false
|
||||
|
||||
// 重置错误状态
|
||||
rangeError.value = false
|
||||
ratioError.value = false
|
||||
increaseError.value = false
|
||||
|
||||
getConfig()
|
||||
}
|
||||
|
||||
const closeRangeError = () => {
|
||||
setTimeout(() => {
|
||||
rangeError.value = false
|
||||
}, 2000)
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getConfig()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.card {
|
||||
border-radius: 12px;
|
||||
background-color: white;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
|
||||
padding: 16px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.space-y-6>* {
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
</style>
|
||||
<route type="page" lang="json">{
|
||||
"layout": "page",
|
||||
"title": "会员代理报告配置",
|
||||
"agent": true,
|
||||
"auth": true
|
||||
}</route>
|
@ -1,63 +0,0 @@
|
||||
<script setup>
|
||||
const webviewStyles = ref({
|
||||
top: `${uni.getSystemInfoSync().statusBarHeight + 44}px`, // 距离顶部的距离
|
||||
height: `${uni.getSystemInfoSync().windowHeight - uni.getSystemInfoSync().statusBarHeight - 44}px`, // 高度
|
||||
position: 'absolute', // 绝对定位
|
||||
dock: 'bottom', // 停靠在底部
|
||||
bounce: 'vertical', // 垂直方向的回弹效果
|
||||
})
|
||||
|
||||
// 从环境变量获取基础URL
|
||||
const BASE_URL = import.meta.env.VITE_APP_BASE_URL || 'https://www.quannengcha.com'
|
||||
|
||||
// 协议路径和标题的映射
|
||||
const agreementMap = {
|
||||
user: {
|
||||
path: '/app/userAgreement',
|
||||
title: '用户协议'
|
||||
},
|
||||
privacy: {
|
||||
path: '/app/privacyPolicy',
|
||||
title: '隐私政策'
|
||||
},
|
||||
authorization: {
|
||||
path: '/app/authorization',
|
||||
title: '授权书'
|
||||
},
|
||||
service: {
|
||||
path: '/app/agentSerivceAgreement',
|
||||
title: '信息技术服务合同'
|
||||
},
|
||||
manage: {
|
||||
path: '/app/agentManageAgreement',
|
||||
title: '推广方管理制度协议'
|
||||
}
|
||||
}
|
||||
|
||||
const agreementUrl = ref('')
|
||||
const pageTitle = ref('协议')
|
||||
|
||||
// 使用 uniapp 的 onLoad 生命周期钩子获取页面参数
|
||||
onLoad((option) => {
|
||||
const type = option.type || 'user'
|
||||
if (agreementMap[type]) {
|
||||
agreementUrl.value = `${BASE_URL}${agreementMap[type].path}`
|
||||
pageTitle.value = agreementMap[type].title
|
||||
|
||||
// 设置标题 - 此标题会传递给 page 布局中的 wd-navbar
|
||||
uni.setNavigationBarTitle({
|
||||
title: pageTitle.value
|
||||
})
|
||||
}
|
||||
})
|
||||
function handleClickLeft() {
|
||||
uni.navigateBack()
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<view>
|
||||
<wd-navbar :title="pageTitle" left-text="返回" placeholder left-arrow safe-area-inset-top fixed @click-left="handleClickLeft" />
|
||||
<web-view :webview-styles="webviewStyles" :src="agreementUrl" />
|
||||
</view>
|
||||
</template>
|
306
src/pages/ai.vue
306
src/pages/ai.vue
@ -1,254 +1,72 @@
|
||||
<template>
|
||||
<view class="safe-area-top flex flex-col box-border from-blue-100 to-white bg-gradient-to-b pt-4 flex-1 pb-4">
|
||||
<!-- 角色切换部分 -->
|
||||
<view class="flex border-blue-300 mx-4 p-1 bg-white rounded-xl">
|
||||
<view class="flex items-center flex-1 p-2 box-border rounded-xl cursor-pointer"
|
||||
:class="selectedRole === 'legal' ? 'bg-blue-300 text-white' : ''" @click="selectRole('legal')">
|
||||
<image src="/static/image/ai_picture.webp" class="w-10 h-10 rounded-xl mr-2" alt="AI律师" />
|
||||
法律咨询
|
||||
</view>
|
||||
<view class="flex items-center flex-1 p-2 box-border rounded-xl cursor-pointer"
|
||||
:class="selectedRole === 'emotional' ? 'bg-blue-300 text-white' : ''" @click="selectRole('emotional')">
|
||||
<image src="/static/image/ai_qinggan.png" class="w-10 h-10 rounded-xl mr-2" alt="AI心理咨询师" />
|
||||
情感咨询
|
||||
</view>
|
||||
</view>
|
||||
<script setup>
|
||||
import { onMounted, ref } from 'vue'
|
||||
|
||||
<!-- 聊天窗口 -->
|
||||
<view class="mx-4 flex flex-col flex-1 rounded-xl shadow-lg">
|
||||
<view class="flex flex-col flex-1 p-4">
|
||||
<view class="flex-1 overflow-y-auto">
|
||||
<view v-for="(message, index) in currentMessages" :key="index" class="mb-4">
|
||||
<view v-if="message.sender === 'ai'" class="flex justify-start items-start">
|
||||
<!-- 根据角色显示不同的AI形象 -->
|
||||
<image :src="selectedRole === 'legal' ? '/static/image/ai_picture.webp' : '/static/image/ai_qinggan.png'"
|
||||
class=" flex-shrink-0 w-10 h-10 rounded-xl mr-2" :alt="selectedRole === 'legal' ? 'AI律师' : 'AI心理咨询师'" />
|
||||
<view class="inline-block max-w-max rounded-xl bg-white p-2 text-left"
|
||||
:class="selectedRole === 'legal' ? 'text-green-600' : 'text-purple-600'">
|
||||
<!-- 如果是AI消息,显示加载中或文本 -->
|
||||
<view v-if="message.loading" class="flex justify-center items-center">
|
||||
<view class="loader"></view> <!-- 加载动画 -->
|
||||
</view>
|
||||
<view v-else>
|
||||
{{ message.text }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-else class="flex justify-end">
|
||||
<view class="ml-auto inline-block max-w-max rounded-xl from-sky-300 via-sky-300 to-sky-300
|
||||
bg-gradient-to-r p-2 text-right text-white font-medium shadow-md">
|
||||
{{ message.text }}
|
||||
</view>
|
||||
</view>
|
||||
const userMessage = ref('')
|
||||
const messages = ref([
|
||||
{ sender: 'ai', text: '欢迎!请问有什么可以帮助您的吗?' },
|
||||
])
|
||||
|
||||
function sendMessage() {
|
||||
if (userMessage.value.trim() === '')
|
||||
return
|
||||
|
||||
messages.value.push({ sender: 'user', text: userMessage.value })
|
||||
|
||||
// AI 统一回复(中文套话)
|
||||
setTimeout(() => {
|
||||
messages.value.push({
|
||||
sender: 'ai',
|
||||
text: '感谢您的提问!我们会尽力为您提供帮助。',
|
||||
})
|
||||
}, 1000)
|
||||
|
||||
userMessage.value = ''
|
||||
}
|
||||
const safeAreaTop = ref(44)
|
||||
onShow(() => {
|
||||
uni.getSystemInfo({
|
||||
success: (res) => {
|
||||
if (res.safeArea && res.safeArea.top) {
|
||||
safeAreaTop.value = res.safeArea.top // 设置安全区顶部距离
|
||||
}
|
||||
},
|
||||
})
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<view
|
||||
class="box-border min-h-screen from-blue-100 to-white bg-gradient-to-b" style="paddingTop:44px"
|
||||
>
|
||||
<view class="chat-page mx-4 flex flex-col rounded-xl shadow-lg">
|
||||
<view class="chat-window flex-1 overflow-auto border p-4">
|
||||
<view v-for="(message, index) in messages" :key="index" class="mb-2">
|
||||
<view v-if="message.sender === 'ai'" class="inline-block max-w-max rounded-xl bg-white p-2 text-left text-green-600 font-medium shadow-md">
|
||||
{{ message.text }}
|
||||
</view>
|
||||
<view v-else class="ml-auto inline-block max-w-max rounded-xl from-sky-300 via-sky-300 to-sky-300 bg-gradient-to-r p-2 text-right text-white font-medium shadow-md">
|
||||
{{ message.text }}
|
||||
</view>
|
||||
</view>
|
||||
<!-- 输入区域 -->
|
||||
<view class="p-2 w-full input-area flex items-center gap-2">
|
||||
<input v-model="userMessage" :placeholder="selectedRole === 'legal' ? '请输入您的法律问题...' : '请输入您的情感问题...'"
|
||||
class="flex-1 p-2 border rounded-lg" type="text" @confirm="sendMessage" />
|
||||
<button class="shadow p-2 bg-blue-500 text-white rounded-lg" @click="sendMessage">
|
||||
发送
|
||||
</button>
|
||||
</view>
|
||||
</view>
|
||||
<view class="input-area mx-2 flex items-center gap-2 p-4">
|
||||
<wd-input v-model="userMessage" placeholder="请输入您的问题..." class="flex-1" size="large" />
|
||||
<wd-button custom-class="shadow" type="primary" @click="sendMessage">
|
||||
发送
|
||||
</wd-button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onBeforeUnmount, computed } from 'vue'
|
||||
import chatEncrypt from "@/utils/chatEncrypt"
|
||||
|
||||
// 当前选中的角色,默认是法律咨询
|
||||
const selectedRole = ref('legal')
|
||||
|
||||
// 用户输入的消息
|
||||
const userMessage = ref('')
|
||||
|
||||
// 存储每个角色的消息记录
|
||||
const messages = ref({
|
||||
legal: [
|
||||
{ sender: 'ai', text: '欢迎!请问有什么法律问题需要帮助?' },
|
||||
],
|
||||
emotional: [
|
||||
{ sender: 'ai', text: '欢迎!请问有什么情感问题需要帮助?' },
|
||||
]
|
||||
})
|
||||
|
||||
// 存储每个角色的 sessionID
|
||||
const sessionID = ref({
|
||||
legal: "",
|
||||
emotional: ""
|
||||
})
|
||||
|
||||
let reader = {
|
||||
legal: null,
|
||||
emotional: null
|
||||
}
|
||||
|
||||
// 计算当前选中的角色的消息
|
||||
const currentMessages = computed(() => messages.value[selectedRole.value])
|
||||
|
||||
// 选择角色
|
||||
function selectRole(role) {
|
||||
if (selectedRole.value !== role) {
|
||||
selectedRole.value = role
|
||||
// 如果该角色还没有消息记录,初始化欢迎消息
|
||||
if (!messages.value[role]) {
|
||||
messages.value[role] = [
|
||||
{ sender: 'ai', text: role === 'legal' ? '欢迎!请问有什么法律问题需要帮助?' : '欢迎!请问有什么情感问题需要帮助?' },
|
||||
]
|
||||
sessionID.value[role] = ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function sendMessage() {
|
||||
if (userMessage.value.trim() === '') return;
|
||||
|
||||
// 获取当前角色
|
||||
const role = selectedRole.value
|
||||
|
||||
// 用户消息推入对应角色的消息列表
|
||||
messages.value[role].push({ sender: 'user', text: userMessage.value })
|
||||
|
||||
const t = Date.now()
|
||||
const x = chatEncrypt(String(t))
|
||||
|
||||
// 在消息列表中添加一个 AI 消息并标记为加载状态
|
||||
const aiMessage = { sender: 'ai', text: '', loading: true }
|
||||
messages.value[role].push(aiMessage)
|
||||
console.log("import.meta.env.VITE_APP_BASE_URL", import.meta.env.VITE_APP_BASE_URL)
|
||||
// 发起请求
|
||||
try {
|
||||
const response = await uni.request({
|
||||
url: import.meta.env.VITE_APP_BASE_URL + '/api/v1/chat/send',
|
||||
method: 'POST',
|
||||
header: {
|
||||
'Content-Type': 'application/json',
|
||||
'x': x,
|
||||
't': t,
|
||||
},
|
||||
data: {
|
||||
prompt: userMessage.value,
|
||||
platform_id: 2,
|
||||
// roleid: role === 'legal' ? 1 : 2, // 根据角色选择不同的 roleid
|
||||
role_id: 1, // 根据角色选择不同的 roleid
|
||||
openid: 'openid' + uni.getStorageSync("token"),
|
||||
userid: 'userid' + uni.getStorageSync("token"),
|
||||
sessionid: sessionID.value[role] // 使用对应角色的 sessionID
|
||||
},
|
||||
responseType: 'text',
|
||||
enableChunked: true, // 启用分块传输
|
||||
enableStream: true, // 启用流式传输
|
||||
success: (streamRes) => {
|
||||
if (streamRes.statusCode === 200) {
|
||||
aiMessage.loading = false;
|
||||
|
||||
// 处理流式响应
|
||||
const chunks = streamRes.data.split('\n');
|
||||
for (const chunk of chunks) {
|
||||
if (chunk.trim()) {
|
||||
let message = chunk;
|
||||
if (message.startsWith('data:')) {
|
||||
message = message.replace('data:', '').trim();
|
||||
}
|
||||
console.log("message", message);
|
||||
try {
|
||||
const parsedMessage = JSON.parse(message);
|
||||
console.log("parsedMessage", parsedMessage);
|
||||
|
||||
if (parsedMessage?.output?.session_id) {
|
||||
// 存储 session_id
|
||||
sessionID.value[role] = parsedMessage?.output?.session_id;
|
||||
}
|
||||
|
||||
// 获取 AI 回复的文本
|
||||
const aiText = parsedMessage.output.text || '';
|
||||
|
||||
// 模拟打字机效果(逐字添加文本)
|
||||
const addTextWithTypingEffect = (text) => {
|
||||
if (!text) return;
|
||||
|
||||
// 直接添加到消息中(实时更新)
|
||||
aiMessage.text += text;
|
||||
// 强制更新视图
|
||||
messages.value[role] = [...messages.value[role]];
|
||||
};
|
||||
|
||||
// 执行打字机效果
|
||||
addTextWithTypingEffect(aiText);
|
||||
} catch (e) {
|
||||
console.error('Failed to parse message:', e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
fail: (err) => {
|
||||
console.error('Request failed:', err);
|
||||
aiMessage.loading = false;
|
||||
aiMessage.text = '抱歉,请求失败,请重试';
|
||||
messages.value[role] = [...messages.value[role]];
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Request error:', error);
|
||||
}
|
||||
|
||||
userMessage.value = ''; // 清空输入框
|
||||
}
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
// 在UniApp中,不需要特别取消流读取,UniApp会自动处理
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
input {
|
||||
padding: 0.5rem;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 0.5rem;
|
||||
}
|
||||
|
||||
button {
|
||||
padding: 0.5rem 1rem;
|
||||
background-color: #007bff;
|
||||
border: none;
|
||||
border-radius: 0.5rem;
|
||||
color: white;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
background-color: #0056b3;
|
||||
}
|
||||
|
||||
.loader {
|
||||
border: 4px solid #f3f3f3;
|
||||
/* Light gray */
|
||||
border-top: 4px solid #3498db;
|
||||
/* Blue */
|
||||
border-radius: 50%;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
animation: spin 2s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
/* Tab Styles */
|
||||
.flex.border-blue-300>view {
|
||||
transition: all 0.3s;
|
||||
<style lang="scss" scoped>
|
||||
.chat-page {
|
||||
height: calc(100vh - 108px);
|
||||
}
|
||||
</style>
|
||||
<route lang="json">{
|
||||
"layout": "home"
|
||||
}</route>
|
||||
|
||||
<route lang="json">
|
||||
{
|
||||
"layout": "home"
|
||||
}
|
||||
</route>
|
||||
|
54
src/pages/authorization.vue
Normal file
54
src/pages/authorization.vue
Normal file
@ -0,0 +1,54 @@
|
||||
<script setup>
|
||||
const webviewStyles = ref({
|
||||
top: `${uni.getSystemInfoSync().statusBarHeight + 44}px`, // 距离顶部的距离
|
||||
height: `${uni.getSystemInfoSync().windowHeight - uni.getSystemInfoSync().statusBarHeight - 44}px`, // 高度
|
||||
position: 'absolute', // 绝对定位
|
||||
dock: 'bottom', // 停靠在底部
|
||||
bounce: 'vertical', // 垂直方向的回弹效果
|
||||
})
|
||||
const id = ref(null)
|
||||
|
||||
function handleMessage(event) {
|
||||
const data = event.detail.data[0]
|
||||
if (data.loaded) {
|
||||
onWebViewLoaded()
|
||||
}
|
||||
else if (data.action === 'agreed') {
|
||||
uni.redirectTo({ url: `/pages/pay?id=${id.value}` })
|
||||
}
|
||||
else if (data.action === 'cancelled') {
|
||||
uni.showModal({
|
||||
title: '注意',
|
||||
content: '是否确认取消,退出当前页面',
|
||||
success(res) {
|
||||
if (res.confirm) {
|
||||
uni.navigateBack()
|
||||
}
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function onWebViewLoaded() {
|
||||
}
|
||||
const src = ref('https://app.quannengcha.com/authorization')
|
||||
onLoad((option) => {
|
||||
if (option.id) {
|
||||
src.value = `${src.value}?id=${encodeURIComponent(option.id)}&token=${encodeURIComponent(uni.getStorageSync('token'))}`
|
||||
id.value = option.id
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<view>
|
||||
<web-view :webview-styles="webviewStyles" :src="src" @message="handleMessage" />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<route lang="json">
|
||||
{
|
||||
"layout": "page",
|
||||
"title": "授权书"
|
||||
}
|
||||
</route>
|
22
src/pages/complaint.vue
Normal file
22
src/pages/complaint.vue
Normal file
@ -0,0 +1,22 @@
|
||||
<script setup>
|
||||
const webviewStyles = ref({
|
||||
top: `${uni.getSystemInfoSync().statusBarHeight + 44}px`, // 距离顶部的距离
|
||||
height: `${uni.getSystemInfoSync().windowHeight - uni.getSystemInfoSync().statusBarHeight - 44}px`, // 高度
|
||||
position: 'absolute', // 绝对定位
|
||||
dock: 'bottom', // 停靠在底部
|
||||
bounce: 'vertical', // 垂直方向的回弹效果
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<view>
|
||||
<web-view :webview-styles="webviewStyles" src="https://app.quannengcha.com/complaint" />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<route lang="json">
|
||||
{
|
||||
"layout": "page",
|
||||
"title": "投诉服务"
|
||||
}
|
||||
</route>
|
204
src/pages/example copy.vue
Normal file
204
src/pages/example copy.vue
Normal file
@ -0,0 +1,204 @@
|
||||
<script setup>
|
||||
import CBad from '@/ui/CBad.vue'
|
||||
import CBankLoanApplication from '@/ui/CBankLoanApplication.vue'
|
||||
import CBankLoanBehavior from '@/ui/CBankLoanBehavior.vue'
|
||||
import CLawsuit from '@/ui/CLawsuit.vue'
|
||||
import CRelatedEnterprises from '@/ui/CRelatedEnterprises.vue'
|
||||
import CSpecialList from '@/ui/CSpecialList.vue'
|
||||
import CTabs from '@/ui/CTabs.vue'
|
||||
import { queryExample } from '@/api/apis'
|
||||
import CMarriage from '@/ui/CMarriage.vue'
|
||||
|
||||
const productMap = {
|
||||
1: '背景调查',
|
||||
2: '企业报告',
|
||||
3: '家政服务',
|
||||
4: '婚姻状态',
|
||||
5: '贷前背景调查',
|
||||
6: '租赁服务',
|
||||
7: '个人风险评估',
|
||||
}
|
||||
|
||||
// 根据 product_id 获取产品名称
|
||||
function getProductName(productId) {
|
||||
return productMap[productId] || '未知类型'
|
||||
}
|
||||
const productId = ref(null)
|
||||
const isDone = ref(false)
|
||||
const entData = ref(null)
|
||||
const lawsuitData = ref(null)
|
||||
const badData = ref(null)
|
||||
const specialData = ref(null)
|
||||
const bankLoanApplicationData = ref(null)
|
||||
const marriageData = ref(null)
|
||||
const bankLoanBehavior = ref(null)
|
||||
const tabs = ref([
|
||||
{ label: '报告概述', value: 'overview' },
|
||||
])
|
||||
const reportItems = ref([
|
||||
|
||||
])
|
||||
const sortedReportItems = computed(() => {
|
||||
return reportItems.value.slice().sort((a, b) => a.sort - b.sort)
|
||||
})
|
||||
const sortedTabs = computed(() => {
|
||||
return tabs.value.slice().sort((a, b) => a.sort - b.sort)
|
||||
})
|
||||
onLoad((option) => {
|
||||
console.log('option', option)
|
||||
const { feature } = option
|
||||
if (feature) {
|
||||
queryExample({ feature }).then((res) => {
|
||||
console.log('res', res)
|
||||
if (res.code === 200) {
|
||||
productId.value = res.data.product_id
|
||||
res.data.query_data.forEach((item) => {
|
||||
if (item.success) {
|
||||
switch (item.apiID) {
|
||||
case 'G09SC02':
|
||||
marriageData.value = item.data
|
||||
tabs.value.push({ label: '婚姻状态', value: 'marriage', sort: 1 })
|
||||
reportItems.value.push({ label: '婚姻状态', value: 'marriage', sort: 1 })
|
||||
break
|
||||
case 'G27BJ05':
|
||||
bankLoanApplicationData.value = item.data
|
||||
tabs.value.push({ label: '借贷申请记录', value: 'netloan', sort: 7 })
|
||||
reportItems.value.push({ label: '借贷申请记录', value: 'netloan', sort: 7 })
|
||||
break
|
||||
case 'G28BJ05':
|
||||
bankLoanBehavior.value = item.data
|
||||
tabs.value.push({ label: '借贷记录', value: 'loan', sort: 6 })
|
||||
reportItems.value.push({ label: '借贷记录', value: 'loan', sort: 6 })
|
||||
|
||||
break
|
||||
case 'G26BJ05':
|
||||
specialData.value = item.data
|
||||
tabs.value.push({ label: '异常名单', value: 'special', sort: 5 })
|
||||
reportItems.value.push({ label: '异常名单', value: 'special', sort: 5 })
|
||||
|
||||
break
|
||||
case 'G05HZ01':
|
||||
entData.value = item.data
|
||||
tabs.value.push({ label: '关联企业', value: 'ent', sort: 4 })
|
||||
reportItems.value.push({ label: '关联企业', value: 'ent', sort: 4 })
|
||||
break
|
||||
case 'G34BJ03':
|
||||
badData.value = item.data
|
||||
tabs.value.push({ label: '不良风险评估', value: 'bad', sort: 3 })
|
||||
reportItems.value.push({ label: '不良风险评估', value: 'bad', sort: 3 })
|
||||
break
|
||||
case 'G35SC01':
|
||||
lawsuitData.value = item.data
|
||||
tabs.value.push({ label: '涉诉案件', value: 'lawsuit', sort: 2 })
|
||||
reportItems.value.push({ label: '涉诉案件', value: 'lawsuit', sort: 2 })
|
||||
break
|
||||
default:
|
||||
console.log(`未知的apiID: ${item.apiID}`)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}).finally(() => {
|
||||
isDone.value = true
|
||||
})
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="min-h-full from-blue-100 to-white bg-gradient-to-b">
|
||||
<CTabs
|
||||
:tabs="sortedTabs"
|
||||
type="blue-green"
|
||||
/>
|
||||
<template v-if="isDone">
|
||||
<div class="flex flex-col gap-y-4 p-4 pt-12">
|
||||
<div id="overview" class="title">
|
||||
报告概述
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="flex flex-col gap-y-2">
|
||||
<div class="flex justify-between">
|
||||
<span class="text-gray-700 font-bold">报告时间:</span>
|
||||
<span class="text-gray-600">2024年11月18日 23:11:23</span>
|
||||
</div>
|
||||
<div class="flex justify-between">
|
||||
<span class="text-gray-700 font-bold">报告项目:</span>
|
||||
<span class="text-gray-600">{{ getProductName(productId) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<LTitle class="my-4" title="报告内容" type="blue-green" />
|
||||
<div class="flex flex-col gap-y-2">
|
||||
<div v-for="item in sortedReportItems" :key="item.value" class="flex justify-between">
|
||||
<span class="text-gray-700 font-bold">{{ item.label }}:</span>
|
||||
<span class="text-green-500 font-bold">已解锁</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<template v-if="marriageData">
|
||||
<div id="marriage" class="title">
|
||||
婚姻状态
|
||||
</div>
|
||||
<CMarriage :data="marriageData" />
|
||||
</template>
|
||||
<template v-if="lawsuitData">
|
||||
<div id="lawsuit" class="title">
|
||||
涉诉案件
|
||||
</div>
|
||||
<CLawsuit :data="lawsuitData" />
|
||||
</template>
|
||||
<template v-if="badData">
|
||||
<div id="bad" class="title">
|
||||
不良风险评估
|
||||
</div>
|
||||
<CBad :data="badData" />
|
||||
</template>
|
||||
<template v-if="entData">
|
||||
<div id="ent" class="title">
|
||||
关联企业
|
||||
</div>
|
||||
<CRelatedEnterprises :data="entData" />
|
||||
</template>
|
||||
<template v-if="specialData">
|
||||
<div id="special" class="title">
|
||||
异常名单
|
||||
</div>
|
||||
<CSpecialList :data="specialData" />
|
||||
</template>
|
||||
<template v-if="bankLoanBehavior">
|
||||
<div id="loan" class="title">
|
||||
借贷记录
|
||||
</div>
|
||||
<CBankLoanBehavior :data="bankLoanBehavior" />
|
||||
</template>
|
||||
<template v-if="bankLoanApplicationData">
|
||||
<div id="netloan" class="title">
|
||||
贷款申请记录
|
||||
</div>
|
||||
<CBankLoanApplication :data="bankLoanApplicationData" />
|
||||
</template>
|
||||
<view class="card">
|
||||
<view>
|
||||
<view class="text-blue-500 font-bold">
|
||||
报告说明
|
||||
</view>
|
||||
<view>本报告的数据由用户本人明确授权后,我们才向相关合法存有用户个人数据的机构调取本报告相关内容,本平台只做大数据的获取与分析,仅向用户个人展示参考。</view><p> 报告有效期<strong>30天</strong>,过期自动删除。 </p><p> 若您的数据不全面,可能是数据具有延迟性或者合作信息机构未获取到您的数据。若数据有错误请联系客服</p>
|
||||
</view>
|
||||
</view>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
</style>
|
||||
|
||||
<route lang="json">
|
||||
{
|
||||
"layout": "page",
|
||||
"title": "报告示例"
|
||||
}
|
||||
</route>
|
41
src/pages/example.vue
Normal file
41
src/pages/example.vue
Normal file
@ -0,0 +1,41 @@
|
||||
<script setup>
|
||||
const webviewStyles = ref({
|
||||
top: `${uni.getSystemInfoSync().statusBarHeight + 44}px`, // 距离顶部的距离
|
||||
height: `${uni.getSystemInfoSync().windowHeight - uni.getSystemInfoSync().statusBarHeight - 44}px`, // 高度
|
||||
position: 'absolute', // 绝对定位
|
||||
dock: 'bottom', // 停靠在底部
|
||||
bounce: 'vertical', // 垂直方向的回弹效果
|
||||
})
|
||||
const feature = ref(null)
|
||||
const token = ref(null)
|
||||
const webviewSrc = ref('')
|
||||
|
||||
onLoad((option) => {
|
||||
if (option.feature) {
|
||||
feature.value = option.feature
|
||||
}
|
||||
|
||||
token.value = uni.getStorageSync('token') || ''
|
||||
|
||||
const baseUrl = 'https://app.quannengcha.com/example'
|
||||
webviewSrc.value = `${baseUrl}?feature=${encodeURIComponent(feature.value)}&token=${encodeURIComponent(token.value)}`
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<view>
|
||||
<!-- 使用动态构造的 WebView src -->
|
||||
<web-view :webview-styles="webviewStyles" :src="webviewSrc" />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
</style>
|
||||
|
||||
<route lang="json">
|
||||
{
|
||||
"layout": "page",
|
||||
"title": "示例报告"
|
||||
}
|
||||
</route>
|
@ -1,166 +1,65 @@
|
||||
<script setup>
|
||||
|
||||
import indexIcon1 from '/static/image/index_icon_1.png'
|
||||
import indexIcon2 from '/static/image/index_icon_2.png'
|
||||
import indexIcon3 from '/static/image/index_icon_3.png'
|
||||
import indexIcon4 from '/static/image/index_icon_4.png'
|
||||
import indexIcon5 from '/static/image/index_icon_5.png'
|
||||
import indexIcon6 from '/static/image/index_icon_6.png'
|
||||
import indexIcon7 from '/static/image/index_icon_7.png'
|
||||
|
||||
// 引入 WebView 插件
|
||||
// @ts-ignore
|
||||
import { urlLaunch } from '@/uni_modules/lz-url_launch';
|
||||
|
||||
|
||||
const services = ref(
|
||||
[
|
||||
{
|
||||
title: '个人风险',
|
||||
name: 'riskassessment',
|
||||
subtitle: '一查全知',
|
||||
bg: indexIcon2,
|
||||
bgColor: 'bg-indigo-400',
|
||||
position: 'rounded-tl-[35px] rounded-bl-[35px] rounded-tr-lg rounded-br-lg'
|
||||
},
|
||||
{
|
||||
title: '婚恋风险',
|
||||
name: 'marriage',
|
||||
subtitle: '查婚姻状态让爱无忧',
|
||||
bg: indexIcon1,
|
||||
bgColor: ' bg-pink-400 ',
|
||||
position: 'rounded-tr-[35px] rounded-br-[35px] rounded-tl-lg rounded-bl-lg'
|
||||
},
|
||||
{
|
||||
title: '家政服务',
|
||||
name: 'homeservice',
|
||||
subtitle: '用人有保障',
|
||||
bg: indexIcon3,
|
||||
bgColor: ' bg-teal-500 ',
|
||||
position: 'rounded-tl-[35px] rounded-bl-[35px] rounded-tr-lg rounded-br-lg'
|
||||
},
|
||||
{
|
||||
title: '租赁风险',
|
||||
name: 'rentalinfo',
|
||||
subtitle: '一查明了',
|
||||
bg: indexIcon4,
|
||||
bgColor: ' bg-sky-500 ',
|
||||
position: 'rounded-tl-[35px] rounded-bl-[35px] rounded-tr-lg rounded-br-lg'
|
||||
},
|
||||
{
|
||||
title: '企业报告',
|
||||
name: 'companyinfo',
|
||||
subtitle: '合作更安心',
|
||||
bg: indexIcon5,
|
||||
bgColor: ' bg-blue-400 ',
|
||||
position: 'rounded-tr-[35px] rounded-br-[35px] rounded-tl-lg rounded-bl-lg'
|
||||
},
|
||||
{
|
||||
title: '人事背调',
|
||||
name: 'backgroundcheck',
|
||||
subtitle: '招聘有保障,选人更放心',
|
||||
bg: indexIcon6,
|
||||
bgColor: ' bg-orange-400 ',
|
||||
position: 'rounded-tl-[35px] rounded-bl-[35px] rounded-tr-lg rounded-br-lg'
|
||||
},
|
||||
{
|
||||
title: '贷前背调',
|
||||
name: 'preloanbackgroundcheck',
|
||||
subtitle: '招聘有保障,选人更放心',
|
||||
bg: indexIcon7,
|
||||
bgColor: ' bg-orange-400 ',
|
||||
position: 'rounded-tr-[35px] rounded-br-[35px] rounded-tl-lg rounded-bl-lg'
|
||||
},
|
||||
]
|
||||
)
|
||||
|
||||
function toInquire(name) {
|
||||
// 使用服务名称构建URL
|
||||
console.log('使用服务:', name);
|
||||
|
||||
// 判断环境,在 App 环境中使用 UTS 插件打开,非 App 环境使用普通导航
|
||||
try {
|
||||
// 构建服务的URL
|
||||
urlLaunch(`https://www.quannengcha.com/inquire/${name}`)
|
||||
} catch (error) {
|
||||
console.error('打开URL失败:', error);
|
||||
}
|
||||
uni.navigateTo({
|
||||
url: `/pages/inquire?feature=${name}`,
|
||||
})
|
||||
}
|
||||
|
||||
const services = ref([
|
||||
{ title: '个人风险', name: 'riskassessment', subtitle: '一查全知', bg: '/static/image/index_icon_2.png', bgColor: 'bg-indigo-400', position: 'rounded-tl-[35px] rounded-bl-[35px] rounded-tr-lg rounded-br-lg' },
|
||||
{ title: '婚恋风险', name: 'marriage', subtitle: '查婚姻状态让爱无忧', bg: '/static/image/index_icon_1.png', bgColor: ' bg-pink-400 ', position: 'rounded-tr-[35px] rounded-br-[35px] rounded-tl-lg rounded-bl-lg' },
|
||||
{ title: '家政服务', name: 'homeservice', subtitle: '用人有保障', bg: '/static/image/index_icon_3.png', bgColor: ' bg-teal-500 ', position: 'rounded-tl-[35px] rounded-bl-[35px] rounded-tr-lg rounded-br-lg' },
|
||||
{ title: '租赁风险', name: 'rentalinfo', subtitle: '一查明了', bg: '/static/image/index_icon_4.png', bgColor: ' bg-sky-500 ', position: 'rounded-tl-[35px] rounded-bl-[35px] rounded-tr-lg rounded-br-lg' },
|
||||
{ title: '企业报告', name: 'companyinfo', subtitle: '合作更安心', bg: '/static/image/index_icon_5.png', bgColor: ' bg-blue-400 ', position: 'rounded-tr-[35px] rounded-br-[35px] rounded-tl-lg rounded-bl-lg' },
|
||||
{ title: '人事背调', name: 'backgroundcheck', subtitle: '招聘有保障,选人更放心', bg: '/static/image/index_icon_6.png', bgColor: ' bg-orange-400 ', position: 'rounded-[35px] col-span-2' },
|
||||
])
|
||||
|
||||
const noticeText = ref([])
|
||||
|
||||
function toHistory() {
|
||||
uni.navigateTo({
|
||||
url: '/pages/queryHistory',
|
||||
})
|
||||
}
|
||||
function toInvitation() {
|
||||
uni.navigateTo({
|
||||
url: '/pages/invitation',
|
||||
})
|
||||
}
|
||||
function toPromote() {
|
||||
uni.navigateTo({
|
||||
url: '/pages/promote',
|
||||
})
|
||||
}
|
||||
function toHelp() {
|
||||
uni.navigateTo({
|
||||
url: '/pages/help',
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<view class="box-border">
|
||||
<view class="box-border min-h-screen from-blue-100 to-white bg-gradient-to-b">
|
||||
<view class="relative h-[190px]">
|
||||
<image class="h-full w-full" src="/static/image/banner2.png" />
|
||||
<image class="absolute bottom-[-70px] right-0 w-38" src="/static/image/banner_a.png" mode="aspectFit" />
|
||||
</view>
|
||||
<view class="mt-4">
|
||||
<view class="flex items-center justify-around gap-2 px-4 pb-1">
|
||||
<view class="" @click="toPromote">
|
||||
<view
|
||||
class="h-12 w-12 p-2 bg-gradient-to-b from-white to-blue-100/10 rounded-full shadow-lg flex items-center justify-center">
|
||||
<image src="/static/image/icon_tg.svg" alt="直推报告" class="w-12 h-12" mode="aspectFit" />
|
||||
</view>
|
||||
<view class="text-center mt-1 font-bold">直推报告</view>
|
||||
</view>
|
||||
<view class="" @click="toInvitation">
|
||||
<view
|
||||
class="h-12 w-12 p-2 bg-gradient-to-b from-white to-blue-100/10 rounded-full shadow-lg flex items-center justify-center">
|
||||
<image src="/static/image/icon_xj.svg" alt="邀请下级" class="w-12 h-12" mode="aspectFit" />
|
||||
</view>
|
||||
<view class="text-center mt-1 font-bold">邀请下级</view>
|
||||
</view>
|
||||
<view class="" @click="toHelp">
|
||||
<view
|
||||
class="h-12 w-12 p-2 bg-gradient-to-b from-white to-blue-100/10 rounded-full shadow-lg flex items-center justify-center">
|
||||
<image src="/static/image/icon_bz.svg" alt="帮助中心" class="w-12 h-12" mode="aspectFit" />
|
||||
</view>
|
||||
<view class="text-center mt-1 font-bold">帮助中心</view>
|
||||
</view>
|
||||
<view class="" @click="toHistory">
|
||||
<view
|
||||
class="h-12 w-12 p-2 bg-gradient-to-b from-white to-blue-100/10 rounded-full shadow-lg flex items-center justify-center">
|
||||
<image src="/static/image/icon_bg.svg" alt="我的报告" class="w-12 h-12" mode="aspectFit" />
|
||||
</view>
|
||||
<view class="text-center mt-1 font-bold">我的报告</view>
|
||||
</view>
|
||||
</view>
|
||||
<image
|
||||
class="absolute bottom-[-70px] right-0 w-38"
|
||||
src="/static/image/banner_a.png"
|
||||
mode="aspectFit"
|
||||
/>
|
||||
</view>
|
||||
<view class="relative p-4 pb-4 pt-2">
|
||||
<view class="mb-1 flex items-center">
|
||||
<view class="flex-shrink-0 pl-2 font-bold">
|
||||
在线信息
|
||||
</view>
|
||||
<wd-notice-bar
|
||||
:text="noticeText" direction="vertical" :delay="5" color="#4c4c4c"
|
||||
background-color="#00000000"
|
||||
/>
|
||||
</view>
|
||||
<view class="grid grid-cols-2 gap-3">
|
||||
<template v-for="(service, index) in services" :key="index">
|
||||
<view class="relative flex flex-col px-4 py-2 shadow-lg " :class="[
|
||||
service.position,
|
||||
service.bgColor,
|
||||
service.title === '婚恋风险' ? 'row-span-2' : '',
|
||||
]"
|
||||
:style="`background: url(${service.bg}) no-repeat; background-size: cover; background-position: center;`"
|
||||
@click="toInquire(service.name)">
|
||||
<view
|
||||
class="relative flex flex-col px-4 py-2 shadow-lg" :class="[
|
||||
service.position,
|
||||
service.bgColor,
|
||||
service.title === '婚恋风险' ? 'row-span-2' : '',
|
||||
]" :style="`background: url(${service.bg}) no-repeat; background-size: cover; background-position: center;`"
|
||||
@click="toInquire(service.name)"
|
||||
>
|
||||
<view class="min-h-18 flex flex-col items-start px-1">
|
||||
<view class="mt-1 max-w-max text-left text-gray-600 font-bold">
|
||||
{{ service.title }}
|
||||
</view>
|
||||
<view class="max-w-max text-left text-xs text-gray-600">
|
||||
<rich-text :nodes="service.subtitle" />
|
||||
</view>
|
||||
<view class="mt-2 rounded-2xl px-2 text-xs text-white" :class="[service.bgColor]">
|
||||
GO >
|
||||
</view>
|
||||
@ -168,9 +67,15 @@ function toHelp() {
|
||||
</view>
|
||||
</template>
|
||||
</view>
|
||||
<view class="mt-4 box-border h-14 w-full flex items-center rounded-xl bg-white px-4 text-gray-700 shadow-xl"
|
||||
@click="toHistory">
|
||||
<image class="mr-4 h-10 w-10" src="/static/image/bg_icon.png" mode="widthFix" />
|
||||
<view
|
||||
class="mt-4 box-border h-14 w-full flex items-center rounded-xl bg-white px-4 text-gray-700 shadow-xl"
|
||||
@click="toHistory"
|
||||
>
|
||||
<image
|
||||
class="mr-4 h-10 w-10"
|
||||
src="/static/image/bg_icon.png"
|
||||
mode="widthFix"
|
||||
/>
|
||||
<view class="">
|
||||
<view class="font-bold">
|
||||
我的历史查询记录
|
||||
@ -181,7 +86,8 @@ function toHelp() {
|
||||
</view>
|
||||
</view>
|
||||
<view
|
||||
class="mb-16 mt-6 h-12 w-full flex items-center justify-center rounded-3xl from-blue-500 to-sky-400 bg-gradient-to-b text-center text-lg text-white line-height-12 shadow-xl">
|
||||
class="mb-16 mt-6 h-12 w-full flex items-center justify-center rounded-3xl from-blue-500 to-sky-400 bg-gradient-to-b text-center text-lg text-white line-height-12 shadow-xl"
|
||||
>
|
||||
<view>全能查邀您共赢,共享数据新价值!</view>
|
||||
</view>
|
||||
</view>
|
||||
@ -198,10 +104,8 @@ function toHelp() {
|
||||
}
|
||||
</style>
|
||||
|
||||
<route type="home" lang="json">{
|
||||
"layout": "home",
|
||||
"style": {
|
||||
"navigationBarTextStyle": "white",
|
||||
"transparentTitle": "always"
|
||||
}
|
||||
}</route>
|
||||
<route type="home" lang="json">
|
||||
{
|
||||
"layout": "home"
|
||||
}
|
||||
</route>
|
||||
|
294
src/pages/inquire.vue
Normal file
294
src/pages/inquire.vue
Normal file
@ -0,0 +1,294 @@
|
||||
<script setup>
|
||||
import { aesEncrypt } from '@/utils/crypto'
|
||||
import { getCode, getProduct, queryMarriage, querybackgroundCheck, querycompanyInfo, queryhomeService, querypreLoanBackgroundCheck, queryrentalInfo, queryriskAssessment } from '@/api/apis'
|
||||
|
||||
const name = ref('')
|
||||
const idCard = ref('')
|
||||
const phoneNumber = ref('')
|
||||
const verificationCode = ref('')
|
||||
const agreeToTerms = ref(false)
|
||||
const isCountingDown = ref(false)
|
||||
const countdown = ref(60)
|
||||
const feature = ref('')
|
||||
const timer = null
|
||||
const featureData = ref({})
|
||||
const services = reactive([
|
||||
{ title: '个人风险报告', name: 'riskassessment', subtitle: '一查全知', bg: '/static/image/index_icon_2.png', bgColor: 'bg-indigo-400', api: queryriskAssessment },
|
||||
{ title: '婚恋报告', name: 'marriage', subtitle: '查婚姻状态让爱无忧', bg: '/static/image/index_icon_1.png', bgColor: ' bg-pink-400 ', api: queryMarriage },
|
||||
{ title: '家政服务报告', name: 'homeservice', subtitle: '用人有保障', bg: '/static/image/index_icon_3.png', bgColor: ' bg-teal-500 ', api: queryhomeService },
|
||||
{ title: '租赁服务报告', name: 'rentalinfo', subtitle: '一查明了', bg: '/static/image/index_icon_4.png', bgColor: ' bg-sky-500 ', api: queryrentalInfo },
|
||||
{ title: '贷前调查报告', name: 'preloanbackgroundcheck', subtitle: '放心借贷', bg: '/static/image/index_icon_7.png', bgColor: ' bg-red-400 ', api: querypreLoanBackgroundCheck },
|
||||
{ title: '人事背调报告', name: 'backgroundcheck', subtitle: '选人更放心', bg: '/static/image/index_icon_6.png', bgColor: ' bg-orange-400 ', api: querybackgroundCheck },
|
||||
{ title: '企业报告', name: 'companyinfo', subtitle: '合作更安心', bg: '/static/image/index_icon_5.png', bgColor: ' bg-blue-400 ', api: querycompanyInfo },
|
||||
])
|
||||
const service = ref({})
|
||||
onLoad((options) => {
|
||||
console.log('options', options)
|
||||
if (options.feature) {
|
||||
feature.value = options.feature
|
||||
}
|
||||
else {
|
||||
feature.value = 'marrige'
|
||||
}
|
||||
getService()
|
||||
getProduct(feature.value).then((res) => {
|
||||
if (res.code === 200) {
|
||||
featureData.value = res.data
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
const isPhoneNumberValid = computed(() => {
|
||||
return /^1[3-9]\d{9}$/.test(phoneNumber.value)
|
||||
})
|
||||
const isIdCardValid = computed(() => /^\d{17}[\dX]$/i.test(idCard.value))
|
||||
|
||||
function handleSubmit() {
|
||||
if (!agreeToTerms.value) {
|
||||
uni.showToast({ title: '请阅读并同意用户协议和隐私政策', icon: 'none' })
|
||||
return
|
||||
}
|
||||
if (!name.value) {
|
||||
uni.showToast({ title: '请输入姓名', icon: 'none' })
|
||||
return
|
||||
}
|
||||
if (!isPhoneNumberValid.value) {
|
||||
uni.showToast({ title: '请输入有效的手机号', icon: 'none' })
|
||||
return
|
||||
}
|
||||
if (!isIdCardValid.value) {
|
||||
uni.showToast({ title: '请输入有效的身份证号码', icon: 'none' })
|
||||
return
|
||||
}
|
||||
if (!verificationCode.value) {
|
||||
uni.showToast({ title: '请输入验证码', icon: 'none' })
|
||||
return
|
||||
}
|
||||
submit()
|
||||
}
|
||||
function getService() {
|
||||
for (const i of services) {
|
||||
if (i.name === feature.value) {
|
||||
service.value = i
|
||||
}
|
||||
}
|
||||
}
|
||||
function sendVerificationCode() {
|
||||
if (isCountingDown.value || !isPhoneNumberValid.value)
|
||||
return
|
||||
if (!isPhoneNumberValid.value) {
|
||||
uni.showToast({ title: '请输入有效的手机号', icon: 'none' })
|
||||
return
|
||||
}
|
||||
getCode({
|
||||
mobile: phoneNumber.value,
|
||||
actionType: 'query',
|
||||
}).then((res) => {
|
||||
if (res.code === 200) {
|
||||
uni.showToast({ title: '获取成功', icon: 'none' })
|
||||
|
||||
startCountdown()
|
||||
}
|
||||
})
|
||||
}
|
||||
function startCountdown() {
|
||||
isCountingDown.value = true
|
||||
countdown.value = 60
|
||||
timer = setInterval(() => {
|
||||
if (countdown.value > 0) {
|
||||
countdown.value--
|
||||
}
|
||||
else {
|
||||
clearInterval(timer)
|
||||
isCountingDown.value = false
|
||||
}
|
||||
}, 1000)
|
||||
}
|
||||
|
||||
function toExample() {
|
||||
uni.navigateTo({
|
||||
url: `/pages/example?feature=${feature.value}`,
|
||||
})
|
||||
}
|
||||
|
||||
function submit() {
|
||||
const req = {
|
||||
name: name.value,
|
||||
id_card: idCard.value,
|
||||
mobile: phoneNumber.value,
|
||||
code: verificationCode.value,
|
||||
}
|
||||
const data = JSON.stringify(req)
|
||||
const encodeData = aesEncrypt(data, 'ff83609b2b24fc73196aac3d3dfb874f')
|
||||
service.value.api({ data: encodeData }).then((res) => {
|
||||
if (res.code === 200) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/authorization?id=${res.data.id}`,
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
function toUserAgreement() {
|
||||
uni.navigateTo({
|
||||
url: '/pages/userAgreement',
|
||||
})
|
||||
}
|
||||
function toPrivacyPolicy() {
|
||||
uni.navigateTo({
|
||||
url: '/pages/privacyPolicy',
|
||||
})
|
||||
}
|
||||
onUnmounted(() => {
|
||||
if (timer) {
|
||||
clearInterval(timer)
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<view class="inquire-bg min-h-screen rounded-lg p-6 shadow-lg">
|
||||
<view class="mb-6 text-center text-blue-800 font-extrabold">
|
||||
<view class="text-blue-600">
|
||||
<text class="text-2xl font-bold">
|
||||
{{ service.title }}
|
||||
</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="card-p-0 px-4 py-6">
|
||||
<view class="mb-4 text-xl text-gray-800 font-semibold">
|
||||
基本信息
|
||||
</view>
|
||||
<wd-input
|
||||
v-model="name" label="姓名" type="text" label-width="60px" placeholder="请输入正确的姓名"
|
||||
class="mb-6 border-b border-gray-200 border-b-solid"
|
||||
/>
|
||||
<wd-input
|
||||
v-model="idCard" label="身份证号" label-width="60px" placeholder="请输入准确的身份证号码"
|
||||
class="mb-6 border-b border-gray-200 border-b-solid"
|
||||
/>
|
||||
<wd-input
|
||||
v-model="phoneNumber" label="手机号" type="tel" label-width="60px" placeholder="输入手机号"
|
||||
class="mb-6 border-b border-gray-200 border-b-solid"
|
||||
/>
|
||||
<view class="mb-6 flex items-center">
|
||||
<wd-input
|
||||
v-model="verificationCode" label="验证码" type="number" label-width="60px" placeholder="输入验证码"
|
||||
class="flex-1 border-b border-gray-200 border-b-solid"
|
||||
/>
|
||||
<view
|
||||
class="ml-2 flex-shrink-0 rounded-lg border-none px-2 py-2 text-sm font-bold outline-none ring-none transition duration-300"
|
||||
:class="isCountingDown || !isPhoneNumberValid ? 'cursor-not-allowed bg-gray-300 text-gray-500' : 'bg-blue-500 text-white hover:bg-blue-600'"
|
||||
@click="sendVerificationCode"
|
||||
>
|
||||
{{ isCountingDown ? `${countdown}s重新获取` : '获取验证码' }}
|
||||
</view>
|
||||
</view>
|
||||
<view class="mb-6 flex items-center">
|
||||
<wd-checkbox v-model="agreeToTerms" />
|
||||
<view class="ml-1 text-xs text-gray-400">
|
||||
我已阅读并同意<text class="text-blue-500 hover:underline" @click="toUserAgreement">
|
||||
《用户协议》
|
||||
</text><text class="text-blue-500 hover:underline" @click="toPrivacyPolicy">
|
||||
《隐私政策》
|
||||
</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="flex">
|
||||
<wd-button
|
||||
custom-style="border-top-right-radius: 0;
|
||||
border-bottom-right-radius: 0;" plain class="w-10 py-3 text-lg font-bold" @click="toExample"
|
||||
>
|
||||
示例报告
|
||||
</wd-button>
|
||||
<wd-button
|
||||
custom-style="border-top-left-radius: 0;
|
||||
border-bottom-left-radius: 0;" type="primary" class="flex-1 py-3 text-lg font-bold" @click="handleSubmit"
|
||||
>
|
||||
立即查询 ¥ {{ featureData.sell_price }}
|
||||
</wd-button>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<wd-divider class="my-4" />
|
||||
<view class="card">
|
||||
<!-- 报告标题 -->
|
||||
<view class="mb-6 text-xl text-gray-800 font-bold">
|
||||
{{ featureData.product_name }}
|
||||
</view>
|
||||
|
||||
<!-- 报告介绍 -->
|
||||
<view class="mb-4 text-gray-600 leading-relaxed">
|
||||
{{ featureData.description }}
|
||||
</view>
|
||||
|
||||
<!-- 报价信息 -->
|
||||
<view class="mb-6 flex items-center justify-between">
|
||||
<view class="text-lg text-gray-500">
|
||||
价格:
|
||||
</view>
|
||||
<view class="text-lg text-blue-600 font-semibold">
|
||||
¥{{ featureData.sell_price }}
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 报告主要内容 -->
|
||||
<view class="mb-4 text-lg text-gray-800 font-semibold">
|
||||
报告主要内容
|
||||
</view>
|
||||
<view class="grid grid-cols-2 gap-4">
|
||||
<view
|
||||
v-for="(feature, index) in featureData.features"
|
||||
:key="feature.id"
|
||||
class="rounded-lg py-2 text-center text-sm text-gray-700 font-medium"
|
||||
:class="[
|
||||
(Math.floor(index / 2) + (index % 2)) % 2 === 0
|
||||
? 'bg-gradient-to-r from-blue-200 via-blue-200 to-blue-100'
|
||||
: 'bg-gradient-to-r from-sky-200 via-sky-200 to-sky-100',
|
||||
]"
|
||||
>
|
||||
{{ feature.name }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.icon-company,
|
||||
.icon-transaction,
|
||||
.icon-judicial,
|
||||
.icon-penalty {
|
||||
font-size: 2rem;
|
||||
}
|
||||
|
||||
.inquire-bg {
|
||||
background: url("/static/image/bg_2.png") no-repeat;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.inquire-bg::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: rgba(255, 255, 255, 0.4);
|
||||
/* 使用白色的半透明覆盖层,0.5 可调整为其他透明度值 */
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.inquire-bg>* {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
/* 确保子元素在覆盖层之上 */
|
||||
}
|
||||
</style>
|
||||
|
||||
<route lang="json">
|
||||
{
|
||||
"layout": "page",
|
||||
"title": "报告查询"
|
||||
}
|
||||
</route>
|
@ -1,51 +0,0 @@
|
||||
<template>
|
||||
<view>
|
||||
<image src="/static/image/invitation.png" alt="邀请下级" mode="widthFix" class="w-full" />
|
||||
<view @click="showQRcode = true"
|
||||
class="bg-gradient-to-t from-orange-500 to-orange-300 fixed bottom-0 h-12 w-full shadow-xl text-white rounded-t-xl flex items-center justify-center font-bold">
|
||||
立即邀请好友
|
||||
</view>
|
||||
|
||||
<QRcode v-model:show="showQRcode" mode="invitation" :linkIdentifier="linkIdentifier" />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onBeforeMount } from 'vue'
|
||||
import { aesEncrypt } from "@/utils/crypto"
|
||||
import QRcode from '@/components/QRcode.vue'
|
||||
|
||||
const showQRcode = ref(false)
|
||||
const linkIdentifier = ref("")
|
||||
const mobile = ref("")
|
||||
const agentID = ref("")
|
||||
|
||||
onBeforeMount(() => {
|
||||
// 从UniApp缓存获取用户信息
|
||||
const userInfo = uni.getStorageSync('userInfo') || {}
|
||||
mobile.value = userInfo.mobile || ''
|
||||
agentID.value = userInfo.agentID || ''
|
||||
|
||||
encryptIdentifire(agentID.value, mobile.value)
|
||||
})
|
||||
|
||||
const encryptIdentifire = (agentID, mobile) => {
|
||||
const linkIdentifierJSON = {
|
||||
agentID,
|
||||
mobile
|
||||
}
|
||||
const linkIdentifierStr = JSON.stringify(linkIdentifierJSON)
|
||||
const encodeData = aesEncrypt(linkIdentifierStr, "8e3e7a2f60edb49221e953b9c029ed10")
|
||||
linkIdentifier.value = encodeURIComponent(encodeData)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
/* 自定义样式 */
|
||||
</style>
|
||||
<route type="page" lang="json">{
|
||||
"layout": "page",
|
||||
"title": "邀请下级",
|
||||
"auth": true,
|
||||
"agent": true
|
||||
}</route>
|
@ -1,199 +0,0 @@
|
||||
<template>
|
||||
<view class="min-h-screen bg-[#D1D6FF]">
|
||||
<image src="/static/image/invitation_agent_apply.png" alt="邀请代理申请" mode="widthFix" class="w-full" />
|
||||
|
||||
<!-- 统一状态处理容器 -->
|
||||
<view class="flex flex-col items-center justify-center">
|
||||
<!-- 审核中状态 -->
|
||||
<view v-if="displayStatus === 0" class="text-center">
|
||||
<text class="text-xs text-gray-500 block">您的申请正在审核中</text>
|
||||
<view class="bg-gray-200 p-1 rounded-3xl shadow-xl mt-1">
|
||||
<view class="text-xl font-bold px-8 py-2 bg-gray-400 text-white rounded-3xl shadow-lg cursor-not-allowed">
|
||||
审核进行中
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 审核通过状态 -->
|
||||
<view v-if="displayStatus === 1" class="text-center">
|
||||
<text class="text-xs text-gray-500 block">您已成为认证代理方</text>
|
||||
<view class="bg-green-100 p-1 rounded-3xl shadow-xl mt-1" @click="goToHome">
|
||||
<view
|
||||
class="text-xl font-bold px-8 py-2 bg-gradient-to-t from-green-500 to-green-300 text-white rounded-3xl shadow-lg cursor-pointer">
|
||||
进入应用首页
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 审核未通过状态 -->
|
||||
<view v-if="displayStatus === 2" class="text-center">
|
||||
<text class="text-xs text-red-500 block">审核未通过,请重新提交</text>
|
||||
<view class="bg-red-100 p-1 rounded-3xl shadow-xl mt-1" @click="agentApply">
|
||||
<view
|
||||
class="text-xl font-bold px-8 py-2 bg-gradient-to-t from-red-500 to-red-300 text-white rounded-3xl shadow-lg cursor-pointer">
|
||||
重新提交申请
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 未申请状态(包含邀请状态) -->
|
||||
<view v-if="displayStatus === 3" class="text-center">
|
||||
<text class="text-xs text-gray-500 block">{{ isSelf ? '立即申请成为代理人' : '邀您注册代理人' }}</text>
|
||||
<view class="bg-gray-100 p-1 rounded-3xl shadow-xl mt-1" @click="agentApply">
|
||||
<view
|
||||
class="text-xl font-bold px-8 py-2 bg-gradient-to-t from-blue-500 to-blue-300 text-white rounded-3xl shadow-lg cursor-pointer">
|
||||
立即成为代理方
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<AgentApplicationForm v-model:show="showApplyPopup" @submit="submitApplication" @close="showApplyPopup = false"
|
||||
:ancestor="ancestor" />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, onBeforeMount } from 'vue'
|
||||
import { getAgentInfo, applyAgent } from '@/apis/agent'
|
||||
import AgentApplicationForm from '@/components/AgentApplicationForm.vue'
|
||||
|
||||
const showApplyPopup = ref(false)
|
||||
const status = ref(3) // 默认为未申请状态
|
||||
const ancestor = ref("")
|
||||
const isSelf = ref(true)
|
||||
let intervalId = null // 保存定时器 ID
|
||||
|
||||
// 计算显示状态(当isSelf为false时强制显示为3)
|
||||
const displayStatus = computed(() => {
|
||||
return !isSelf.value ? 3 : status.value
|
||||
})
|
||||
|
||||
// 打开申请表单
|
||||
const agentApply = () => {
|
||||
showApplyPopup.value = true
|
||||
}
|
||||
|
||||
// 跳转到首页
|
||||
const goToHome = () => {
|
||||
clearInterval(intervalId)
|
||||
uni.switchTab({
|
||||
url: '/pages/index'
|
||||
})
|
||||
}
|
||||
|
||||
const getAgentInformation = async () => {
|
||||
const token = uni.getStorageSync("token")
|
||||
if (!token) {
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
const res = await getAgentInfo()
|
||||
if (res.code === 200 && res.data) {
|
||||
// 将代理信息存入缓存
|
||||
uni.setStorageSync("agentInfo", {
|
||||
level: res.data.level,
|
||||
isAgent: res.data.is_agent, // 判断是否是代理
|
||||
status: res.data.status, // 获取代理状态 0=待审核,1=审核通过,2=审核未通过,3=未申请
|
||||
agentID: res.data.agent_id,
|
||||
mobile: res.data.mobile
|
||||
})
|
||||
status.value = res.data.status
|
||||
console.log('代理信息已获取并存入缓存')
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取代理信息失败', error)
|
||||
}
|
||||
}
|
||||
// 提交代理申请
|
||||
const submitApplication = async (formData) => {
|
||||
try {
|
||||
const { region, mobile, wechat_id, code } = formData
|
||||
let postData = {
|
||||
region,
|
||||
mobile,
|
||||
wechat_id,
|
||||
code,
|
||||
}
|
||||
|
||||
if (!isSelf.value) {
|
||||
postData.ancestor = ancestor.value
|
||||
}
|
||||
|
||||
const res = await applyAgent(postData)
|
||||
|
||||
if (res.code === 200) {
|
||||
showApplyPopup.value = false
|
||||
uni.showToast({
|
||||
title: "已提交申请",
|
||||
icon: 'success'
|
||||
})
|
||||
|
||||
if (res.data.accessToken) {
|
||||
uni.setStorageSync('token', res.data.accessToken)
|
||||
uni.setStorageSync('refreshAfter', res.data.refreshAfter)
|
||||
uni.setStorageSync('accessExpire', res.data.accessExpire)
|
||||
refreshAgentStatus()
|
||||
}
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: res.msg || '申请失败',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
} catch (error) {
|
||||
uni.showToast({
|
||||
title: '网络错误',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 定时刷新代理状态
|
||||
const refreshAgentStatus = () => {
|
||||
if (status.value === 3) {
|
||||
if (intervalId) clearInterval(intervalId)
|
||||
|
||||
intervalId = setInterval(() => {
|
||||
if (status.value !== 3) {
|
||||
clearInterval(intervalId)
|
||||
intervalId = null
|
||||
return
|
||||
}
|
||||
getAgentInformation()
|
||||
}, 2000)
|
||||
} else {
|
||||
if (intervalId) {
|
||||
clearInterval(intervalId)
|
||||
intervalId = null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onLoad(() => {
|
||||
const token = uni.getStorageSync('token')
|
||||
if (token) {
|
||||
// 从缓存中获取代理信息
|
||||
const agentInfo = uni.getStorageSync('agentInfo')
|
||||
if (agentInfo) {
|
||||
status.value = agentInfo.status || 3
|
||||
}
|
||||
getAgentInformation()
|
||||
}
|
||||
})
|
||||
|
||||
// 页面卸载时清除定时器
|
||||
onUnload(() => {
|
||||
if (intervalId) {
|
||||
clearInterval(intervalId)
|
||||
intervalId = null
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<route type="page" lang="json">{
|
||||
"layout": "page",
|
||||
"title": "代理申请",
|
||||
"auth": true
|
||||
}</route>
|
@ -1,6 +1,6 @@
|
||||
<script setup>
|
||||
import { getCode, login, getUserInfo } from '@/api/apis'
|
||||
import { getAgentInfo } from '@/apis/agent'
|
||||
import { getCode, login } from '@/api/apis'
|
||||
|
||||
const phoneNumber = ref('')
|
||||
const verificationCode = ref('')
|
||||
const password = ref('')
|
||||
@ -72,13 +72,10 @@ function handleLogin() {
|
||||
return
|
||||
}
|
||||
login({ mobile: phoneNumber.value, code: verificationCode.value }).then((res) => {
|
||||
console.log('res.data.AccessToken', res.data.accessToken)
|
||||
if (res.code === 200) {
|
||||
uni.setStorageSync('token', res.data.accessToken)
|
||||
uni.setStorageSync('refreshAfter', res.data.refreshAfter)
|
||||
uni.setStorageSync('accessExpire', res.data.accessExpire)
|
||||
uni.showToast({ title: '登录成功', icon: 'none' })
|
||||
getUser()
|
||||
getAgentInformation()
|
||||
uni.reLaunch({
|
||||
url: '/pages/index',
|
||||
})
|
||||
@ -91,50 +88,14 @@ function handleLogin() {
|
||||
|
||||
function toUserAgreement() {
|
||||
uni.navigateTo({
|
||||
url: '/pages/agreement?type=user',
|
||||
url: '/pages/userAgreement',
|
||||
})
|
||||
}
|
||||
function toPrivacyPolicy() {
|
||||
uni.navigateTo({
|
||||
url: '/pages/agreement?type=privacy',
|
||||
url: '/pages/privacyPolicy',
|
||||
})
|
||||
}
|
||||
const getAgentInformation = async () => {
|
||||
const token = uni.getStorageSync("token")
|
||||
if (!token) {
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
const res = await getAgentInfo()
|
||||
if (res.code === 200 && res.data) {
|
||||
// 将代理信息存入缓存
|
||||
uni.setStorageSync("agentInfo", {
|
||||
level: res.data.level,
|
||||
isAgent: res.data.is_agent, // 判断是否是代理
|
||||
status: res.data.status, // 获取代理状态 0=待审核,1=审核通过,2=审核未通过,3=未申请
|
||||
agentID: res.data.agent_id,
|
||||
mobile: res.data.mobile
|
||||
})
|
||||
|
||||
console.log('代理信息已获取并存入缓存')
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取代理信息失败', error)
|
||||
}
|
||||
}
|
||||
|
||||
const getUser = async () => {
|
||||
const token = uni.getStorageSync("token")
|
||||
if (!token) {
|
||||
return
|
||||
}
|
||||
const res = await getUserInfo()
|
||||
if (res.code === 200) {
|
||||
console.log(res.data)
|
||||
uni.setStorageSync("userInfo", res.data.userInfo)
|
||||
}
|
||||
}
|
||||
onUnmounted(() => {
|
||||
if (timer) {
|
||||
clearInterval(timer)
|
||||
@ -146,32 +107,47 @@ onUnmounted(() => {
|
||||
<view class="login px-8">
|
||||
<view class="mb-8 pt-8 text-left">
|
||||
<view class="flex flex-col items-center">
|
||||
<image class="h-18 w-18 rounded-full shadow" src="/static/image/logo.png" mode="scaleToFill" />
|
||||
<image class="mt-4 h-10" src="/static/image/logo_title.png" mode="aspectFit" />
|
||||
<image
|
||||
class="h-18 w-18 rounded-full shadow"
|
||||
src="/static/image/logo.png"
|
||||
mode="scaleToFill"
|
||||
/>
|
||||
<image
|
||||
class="mt-4 h-10"
|
||||
src="/static/image/logo_title.png"
|
||||
mode="aspectFit"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="space-y-5">
|
||||
<view class="input-container bg-blue-300/20" :class="[phoneFocused ? 'focused' : '']">
|
||||
<input v-model="phoneNumber" class="input-field" type="number" placeholder="请输入手机号" maxlength="11"
|
||||
@focus="phoneFocused = true" @blur="phoneFocused = false">
|
||||
<input
|
||||
v-model="phoneNumber" class="input-field" type="number" placeholder="请输入手机号" maxlength="11"
|
||||
@focus="phoneFocused = true" @blur="phoneFocused = false"
|
||||
>
|
||||
</view>
|
||||
<view v-if="!isPasswordLogin">
|
||||
<view class="flex items-center justify-between">
|
||||
<view class="input-container bg-blue-300/20" :class="[codeFocused ? 'focused' : '']">
|
||||
<input v-model="verificationCode" class="input-field" type="number" placeholder="请输入验证码" maxlength="6"
|
||||
@focus="codeFocused = true" @blur="codeFocused = false">
|
||||
<input
|
||||
v-model="verificationCode" class="input-field" type="number" placeholder="请输入验证码" maxlength="6"
|
||||
@focus="codeFocused = true" @blur="codeFocused = false"
|
||||
>
|
||||
</view>
|
||||
<view
|
||||
class="ml-2 flex-shrink-0 rounded-lg px-4 py-2 text-sm font-bold transition duration-300 focus:outline-none"
|
||||
:class="isCountingDown || !isPhoneNumberValid ? 'cursor-not-allowed bg-gray-300 text-gray-500' : 'bg-blue-500 text-white hover:bg-blue-600'"
|
||||
@click="sendVerificationCode">
|
||||
@click="sendVerificationCode"
|
||||
>
|
||||
{{ isCountingDown ? `${countdown}s重新获取` : '获取验证码' }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="isPasswordLogin" class="input-container" :class="[passwordFocused ? 'focused' : '']">
|
||||
<input v-model="password" class="input-field" type="password" placeholder="请输入密码"
|
||||
@focus="passwordFocused = true" @blur="passwordFocused = false">
|
||||
<input
|
||||
v-model="password" class="input-field" type="password" placeholder="请输入密码"
|
||||
@focus="passwordFocused = true" @blur="passwordFocused = false"
|
||||
>
|
||||
</view>
|
||||
<view class="flex items-start space-x-2">
|
||||
<wd-checkbox v-model="isAgreed" class="mt-1" />
|
||||
@ -189,15 +165,17 @@ onUnmounted(() => {
|
||||
</view>
|
||||
<button
|
||||
class="mt-20 block w-full flex-shrink-0 rounded-full bg-blue-500 py-3 text-lg text-white font-bold transition duration-300"
|
||||
@click="handleLogin">
|
||||
@click="handleLogin"
|
||||
>
|
||||
登录
|
||||
</button>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.login {}
|
||||
.login{
|
||||
|
||||
}
|
||||
.input-container {
|
||||
border: 2px solid rgba(125, 211, 252, 0.0);
|
||||
border-radius: 1rem;
|
||||
@ -217,7 +195,9 @@ onUnmounted(() => {
|
||||
}
|
||||
</style>
|
||||
|
||||
<route lang="json">{
|
||||
<route lang="json">
|
||||
{
|
||||
"layout": "login",
|
||||
"title": "登录"
|
||||
}</route>
|
||||
}
|
||||
</route>
|
||||
|
335
src/pages/me.vue
335
src/pages/me.vue
@ -1,246 +1,125 @@
|
||||
<template>
|
||||
<view class="safe-area-top box-border min-h-screen">
|
||||
<view class="flex flex-col p-4 space-y-6">
|
||||
<!-- 用户信息卡片 -->
|
||||
<view
|
||||
class="profile-section group relative flex items-center gap-4 rounded-xl bg-white p-6 shadow-lg transition-all hover:shadow-xl"
|
||||
@click="!isLoggedIn ? redirectToLogin() : null">
|
||||
<view class="relative">
|
||||
<!-- 头像容器添加overflow-hidden解决边框问题 -->
|
||||
<view class="flex items-center justify-center overflow-hidden rounded-full p-0.5"
|
||||
:class="levelGradient.border">
|
||||
<image :src="userAvatar || headShot" alt="User Avatar" class="h-24 w-24 rounded-full border-4 border-white">
|
||||
</image>
|
||||
</view>
|
||||
<script setup>
|
||||
import { getUserInfo } from '@/api/apis'
|
||||
|
||||
<!-- 代理标识 -->
|
||||
<view v-if="isAgent" class="absolute -bottom-2 -right-2">
|
||||
<view class="flex items-center justify-center rounded-full px-3 py-1 text-xs font-bold text-white shadow-sm"
|
||||
:class="levelGradient.badge">
|
||||
{{ levelNames[level] }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="space-y-1">
|
||||
<view class="text-2xl font-bold text-gray-800">
|
||||
{{ isLoggedIn ? maskName(userName) : '点击登录' }}
|
||||
</view>
|
||||
<view v-if="isAgent" class="text-sm font-medium" :class="levelGradient.text">
|
||||
🎖️ {{ levelText[level] }}
|
||||
</view>
|
||||
const userName = ref('点击登录')
|
||||
const userAvatar = ref('https://img0.baidu.com/it/u=1240274933,2284862568&fm=253&fmt=auto&app=138&f=PNG?w=180&h=180')
|
||||
const isLoggedIn = ref(false)
|
||||
const features = ref([
|
||||
{ title: '我的报告', icon: 'list', action: () => toHistory() },
|
||||
{ title: '联系客服', icon: 'service', action: () => toService() },
|
||||
{ title: '用户协议', icon: 'file', action: () => toUserAgreement() },
|
||||
{ title: '退出登录', icon: 'logout', action: () => handleLogout() },
|
||||
])
|
||||
function toHistory() {
|
||||
uni.navigateTo({
|
||||
url: '/pages/queryHistory',
|
||||
})
|
||||
}
|
||||
function toUserAgreement() {
|
||||
uni.navigateTo({
|
||||
url: '/pages/userAgreement',
|
||||
})
|
||||
}
|
||||
|
||||
function redirectToLogin() {
|
||||
uni.reLaunch({ url: '/pages/login' }) // 使用 uni-app 路由跳转到登录页
|
||||
}
|
||||
|
||||
function handleLogout() {
|
||||
uni.removeStorageSync('token')
|
||||
isLoggedIn.value = false
|
||||
userName.value = '点击登录'
|
||||
userAvatar.value = 'https://img0.baidu.com/it/u=1240274933,2284862568&fm=253&fmt=auto&app=138&f=PNG?w=180&h=180'
|
||||
}
|
||||
function toService() {
|
||||
uni.navigateTo({
|
||||
url: '/pages/service',
|
||||
})
|
||||
}
|
||||
async function fetchUserInfo() {
|
||||
try {
|
||||
// 假设通过 API 获取用户信息
|
||||
getUserInfo().then((res) => {
|
||||
if (res.code === 200) {
|
||||
console.log('res', res)
|
||||
const userinfo = res.data.userInfo
|
||||
userName.value = userinfo.nickName || ''
|
||||
userAvatar.value = userinfo.userAvatar || 'https://img0.baidu.com/it/u=1240274933,2284862568&fm=253&fmt=auto&app=138&f=PNG?w=180&h=180'
|
||||
isLoggedIn.value = true
|
||||
}
|
||||
})
|
||||
}
|
||||
catch (error) {
|
||||
console.error('获取用户信息失败', error)
|
||||
}
|
||||
}
|
||||
const safeAreaTop = ref(0)
|
||||
onMounted(() => {
|
||||
const token = uni.getStorageSync('token')
|
||||
if (token) {
|
||||
isLoggedIn.value = true
|
||||
fetchUserInfo()
|
||||
}
|
||||
else {
|
||||
isLoggedIn.value = false
|
||||
}
|
||||
uni.getSystemInfo({
|
||||
success: (res) => {
|
||||
if (res.safeArea) {
|
||||
safeAreaTop.value = res.safeArea.top
|
||||
}
|
||||
},
|
||||
})
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<view
|
||||
class="box-border min-h-screen from-blue-100 to-white bg-gradient-to-b" style="paddingTop:44px"
|
||||
>
|
||||
<view class="flex flex-col p-4">
|
||||
<view class="profile-section mb-4 flex items-center gap-4 rounded-md bg-white p-4 shadow-md" @click="!isLoggedIn ? redirectToLogin() : null">
|
||||
<wd-img :src="userAvatar" round width="100" height="100" />
|
||||
<view>
|
||||
<h2 class="text-lg font-bold">
|
||||
{{ isLoggedIn ? userName : '点击登录' }}
|
||||
</h2>
|
||||
</view>
|
||||
</view>
|
||||
<VipBanner v-if="isAgent && level === 'normal'" />
|
||||
<!-- 功能菜单 -->
|
||||
<view class="features-section space-y-3">
|
||||
<template v-if="isAgent && ['VIP', 'SVIP'].includes(level)">
|
||||
<button
|
||||
class="feature-item bg-gradient-to-r from-purple-200/80 to-pink-200/80 hover:from-purple-300/80 hover:to-pink-300/80 text-purple-700"
|
||||
@click="toVipConfig">
|
||||
⚙️ 代理报告配置
|
||||
</button>
|
||||
</template>
|
||||
|
||||
<button class="feature-item hover:bg-blue-50" @click="toHistory">
|
||||
📃 我的报告
|
||||
</button>
|
||||
<button class="feature-item hover:bg-blue-50" @click="toUserAgreement">
|
||||
📜 用户协议
|
||||
</button>
|
||||
<button class="feature-item hover:bg-blue-50" @click="toService">
|
||||
💬 联系客服
|
||||
</button>
|
||||
<button class="feature-item hover:bg-red-50 text-red-600" @click="handleLogout">
|
||||
⏏️ 退出登录
|
||||
</button>
|
||||
<Wdviewider />
|
||||
|
||||
<view class="features-section flex flex-col gap-2">
|
||||
<WdCell
|
||||
v-for="(feature, index) in features"
|
||||
:key="index"
|
||||
:title="feature.title"
|
||||
:icon="feature.icon"
|
||||
class="feature-item rounded-md bg-white p-3 shadow-sm"
|
||||
clickable
|
||||
@click="feature.action"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, onBeforeMount } from 'vue'
|
||||
import headShot from "@/static/image/head_shot.webp"
|
||||
|
||||
// 用户数据
|
||||
const userName = ref('')
|
||||
const userAvatar = ref('')
|
||||
const isLoggedIn = ref(false)
|
||||
|
||||
// 代理数据
|
||||
const isAgent = ref(false)
|
||||
const level = ref('normal')
|
||||
|
||||
|
||||
// 检查平台环境
|
||||
onBeforeMount(() => {
|
||||
// 从缓存获取用户信息
|
||||
const token = uni.getStorageSync('token')
|
||||
if (token) {
|
||||
isLoggedIn.value = true
|
||||
// 从缓存获取用户信息
|
||||
const userInfo = uni.getStorageSync('userInfo')
|
||||
console.log("userInfo", userInfo)
|
||||
if (userInfo) {
|
||||
userName.value = userInfo.nickName || '用户'
|
||||
userAvatar.value = userInfo.avatar || ''
|
||||
}
|
||||
|
||||
// 从缓存获取代理信息
|
||||
const agentInfo = uni.getStorageSync('agentInfo')
|
||||
if (agentInfo?.isAgent) {
|
||||
isAgent.value = agentInfo.isAgent
|
||||
level.value = agentInfo.level || 'normal'
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const levelNames = {
|
||||
normal: '普通代理',
|
||||
VIP: 'VIP代理',
|
||||
SVIP: 'SVIP代理'
|
||||
}
|
||||
|
||||
const levelText = {
|
||||
normal: '基础代理特权',
|
||||
VIP: '高级代理特权',
|
||||
SVIP: '尊享代理特权'
|
||||
}
|
||||
|
||||
const levelGradient = computed(() => ({
|
||||
border: {
|
||||
'normal': 'bg-green-300',
|
||||
'VIP': 'bg-gradient-to-r from-yellow-400 to-amber-500',
|
||||
'SVIP': 'bg-gradient-to-r from-purple-400 to-pink-400 shadow-[0_0_15px_rgba(163,51,200,0.2)]'
|
||||
}[level.value],
|
||||
|
||||
badge: {
|
||||
'normal': 'bg-green-500',
|
||||
'VIP': 'bg-gradient-to-r from-yellow-500 to-amber-600',
|
||||
'SVIP': 'bg-gradient-to-r from-purple-500 to-pink-500'
|
||||
}[level.value],
|
||||
|
||||
text: {
|
||||
'normal': 'text-green-600',
|
||||
'VIP': 'text-amber-600',
|
||||
'SVIP': 'text-purple-600'
|
||||
}[level.value]
|
||||
}))
|
||||
|
||||
function maskName(name) {
|
||||
if (!name || name.length < 11) return name
|
||||
return name.substring(0, 3) + "****" + name.substring(7)
|
||||
}
|
||||
|
||||
function toHistory() {
|
||||
uni.navigateTo({
|
||||
url: '/pages/queryHistory'
|
||||
})
|
||||
}
|
||||
|
||||
function toUserAgreement() {
|
||||
uni.navigateTo({
|
||||
url: '/pages/agreement?type=user'
|
||||
})
|
||||
}
|
||||
|
||||
function redirectToLogin() {
|
||||
uni.navigateTo({
|
||||
url: '/pages/login'
|
||||
})
|
||||
}
|
||||
|
||||
function handleLogout() {
|
||||
uni.removeStorageSync('token')
|
||||
uni.removeStorageSync('refreshAfter')
|
||||
uni.removeStorageSync('accessExpire')
|
||||
uni.removeStorageSync('userInfo')
|
||||
uni.removeStorageSync('agentInfo')
|
||||
|
||||
// 重置状态
|
||||
isLoggedIn.value = false
|
||||
userName.value = ''
|
||||
userAvatar.value = ''
|
||||
isAgent.value = false
|
||||
level.value = 'normal'
|
||||
|
||||
uni.reLaunch({
|
||||
url: '/pages/index'
|
||||
})
|
||||
}
|
||||
|
||||
function toService() {
|
||||
// #ifdef APP-PLUS
|
||||
plus.runtime.openURL('https://work.weixin.qq.com/kfid/kfc5c19b2b93a5e73b9')
|
||||
// #endif
|
||||
|
||||
// #ifdef H5
|
||||
window.location.href = 'https://work.weixin.qq.com/kfid/kfc5c19b2b93a5e73b9'
|
||||
// #endif
|
||||
|
||||
// #ifdef MP
|
||||
uni.setClipboardData({
|
||||
data: 'https://work.weixin.qq.com/kfid/kfc5c19b2b93a5e73b9',
|
||||
success: function () {
|
||||
uni.showToast({
|
||||
title: '客服链接已复制,请在浏览器中打开',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
})
|
||||
// #endif
|
||||
}
|
||||
|
||||
function toVipConfig() {
|
||||
uni.navigateTo({
|
||||
url: '/pages/agentVipConfig'
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
<style lang="scss" scoped>
|
||||
.profile-section {
|
||||
background: linear-gradient(135deg, #ffffff 50%, rgba(236, 253, 245, 0.3));
|
||||
border: 1px solid rgba(209, 213, 219, 0.2);
|
||||
@apply flex items-center gap-4 p-4 bg-white rounded-md shadow-md mb-4;
|
||||
}
|
||||
|
||||
.profile-section .relative>view:first-child {
|
||||
transition: all 0.3s ease;
|
||||
.features-section {
|
||||
@apply flex flex-col gap-2;
|
||||
}
|
||||
|
||||
.feature-item {
|
||||
transition:
|
||||
transform 0.2s ease,
|
||||
background 0.3s ease,
|
||||
box-shadow 0.3s ease;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
align-items: center;
|
||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
|
||||
margin-right: 0.75rem;
|
||||
border-radius: 0.75rem;
|
||||
background-color: #ffffff;
|
||||
padding: 1rem 1.5rem;
|
||||
text-align: left;
|
||||
color: #4b5563;
|
||||
transition-property: all;
|
||||
transition-duration: 300ms;
|
||||
}
|
||||
|
||||
.feature-item:active {
|
||||
transform: scale(1.02);
|
||||
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
|
||||
}
|
||||
|
||||
.border-gradient-to-r {
|
||||
border-image: linear-gradient(to right, var(--tw-gradient-from), var(--tw-gradient-to)) 1;
|
||||
}
|
||||
|
||||
.shadow-glow {
|
||||
box-shadow: 0 0 8px rgba(163, 51, 200, 0.2);
|
||||
@apply bg-white p-3 rounded-md shadow-sm;
|
||||
}
|
||||
</style>
|
||||
|
||||
<route lang="json">{
|
||||
"layout": "home"
|
||||
}</route>
|
||||
<route lang="json">
|
||||
{
|
||||
"layout": "home"
|
||||
}
|
||||
</route>
|
||||
|
98
src/pages/pay.vue
Normal file
98
src/pages/pay.vue
Normal file
@ -0,0 +1,98 @@
|
||||
<script setup>
|
||||
import { payment, queryProvisionalOrder } from '@/api/apis'
|
||||
|
||||
const selectedPaymentMethod = ref('alipay')
|
||||
const id = ref(null)
|
||||
const order = ref({
|
||||
productName: '',
|
||||
price: null,
|
||||
})
|
||||
function handlePayment() {
|
||||
if (selectedPaymentMethod.value === 'alipay') {
|
||||
payment({ id: id.value, pay_method: selectedPaymentMethod.value }).then((res) => {
|
||||
if (res.code === 200) {
|
||||
uni.requestPayment({
|
||||
provider: 'alipay', // 支付宝
|
||||
orderInfo: res.data.prepay_id, // 后台返回的orderInfo
|
||||
success: () => {
|
||||
handlePaySuccess(res.data.order_id)
|
||||
},
|
||||
fail: (err) => {
|
||||
console.log('支付失败:', err)
|
||||
},
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
function handlePaySuccess(orderID) {
|
||||
uni.redirectTo({
|
||||
url: `/pages/result?id=${orderID}`,
|
||||
})
|
||||
}
|
||||
onLoad((option) => {
|
||||
if (option.id) {
|
||||
id.value = option.id
|
||||
queryProvisionalOrder(option.id).then((res) => {
|
||||
console.log('res', res)
|
||||
if (res.code === 200) {
|
||||
order.value.productName = res.data.product.product_name
|
||||
order.value.price = res.data.product.sell_price
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<view class="min-h-screen from-blue-200 via-sky-200 to-sky-100 bg-gradient-to-b p-6">
|
||||
<view class="card">
|
||||
<h1 class="mb-4 text-xl font-bold">
|
||||
订单支付
|
||||
</h1>
|
||||
<view class="my-10 text-center">
|
||||
<view class="text-2xl font-bold">
|
||||
¥{{ order.price }}
|
||||
</view>
|
||||
<view class="text-gray-600">
|
||||
{{ order.productName }}
|
||||
</view>
|
||||
</view>
|
||||
<view class="mb-4">
|
||||
<label class="mb-2 block text-sm text-gray-600">支付方式</label>
|
||||
<wd-radio-group v-model="selectedPaymentMethod" shape="dot" size="large">
|
||||
<view class="border-3 border-blue-500 rounded-lg border-solid px-4 py-2">
|
||||
<wd-radio value="alipay">
|
||||
<view class="flex" items-center>
|
||||
<image
|
||||
src="/static/image/alipay_icon.svg"
|
||||
mode="aspectFit"
|
||||
class="mr-1 h-5 w-5"
|
||||
/> 支付宝
|
||||
</view>
|
||||
</wd-radio>
|
||||
</view>
|
||||
</wd-radio-group>
|
||||
</view>
|
||||
<button
|
||||
class="w-full rounded-xl from-blue-500 via-blue-500 to-blue-400 bg-gradient-to-b px-4 py-2 text-white"
|
||||
@click="handlePayment"
|
||||
>
|
||||
立即支付
|
||||
</button>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
:deep(.wd-radio){
|
||||
margin-top: 0;
|
||||
}
|
||||
</style>
|
||||
|
||||
<route lang="json">
|
||||
{
|
||||
"layout": "page",
|
||||
"title": "全能查收款"
|
||||
}
|
||||
</route>
|
164
src/pages/payb.vue
Normal file
164
src/pages/payb.vue
Normal file
@ -0,0 +1,164 @@
|
||||
<script setup>
|
||||
import { iapPaymentCallback, payment, queryProvisionalOrder } from '@/api/apis'
|
||||
|
||||
const selectedPaymentMethod = ref('appleiap')
|
||||
const id = ref(null)
|
||||
const order = ref({
|
||||
productName: '',
|
||||
price: null,
|
||||
})
|
||||
|
||||
async function handlePayment() {
|
||||
try {
|
||||
if (selectedPaymentMethod.value === 'appleiap') {
|
||||
const paymentResponse = await payment({ id: id.value, pay_method: selectedPaymentMethod.value })
|
||||
if (paymentResponse.code === 200) {
|
||||
uni.showLoading({ title: '加载中' })
|
||||
const productID = paymentResponse.data.prepay_id
|
||||
const orderID = paymentResponse.data.order_id
|
||||
const iapChannel = await getIapChannel()
|
||||
const products = await requestProduct(iapChannel, [productID])
|
||||
|
||||
if (products.length > 0) {
|
||||
const product = products[0]
|
||||
uni.requestPayment({
|
||||
provider: 'appleiap',
|
||||
orderInfo: { productid: product.productid },
|
||||
success: async (iapRes) => {
|
||||
const callbackResponse = await iapPaymentCallback({
|
||||
order_id: orderID,
|
||||
transaction_receipt: iapRes.transactionReceipt,
|
||||
})
|
||||
if (callbackResponse.code === 200) {
|
||||
handlePaySuccess(orderID)
|
||||
}
|
||||
else {
|
||||
console.error('支付回调处理失败:', callbackResponse)
|
||||
}
|
||||
},
|
||||
fail: (err) => {
|
||||
console.error('支付失败:', err)
|
||||
},
|
||||
})
|
||||
}
|
||||
else {
|
||||
console.error('未找到对应的产品信息')
|
||||
}
|
||||
}
|
||||
else {
|
||||
console.error('支付请求失败:', paymentResponse)
|
||||
}
|
||||
}
|
||||
else {
|
||||
console.error('未选择 Apple IAP 支付方式')
|
||||
}
|
||||
}
|
||||
catch (error) {
|
||||
console.error('支付流程中发生错误:', error)
|
||||
}
|
||||
finally {
|
||||
uni.hideLoading()
|
||||
}
|
||||
}
|
||||
|
||||
async function getIapChannel() {
|
||||
return new Promise((resolve, reject) => {
|
||||
uni.showLoading({ title: '加载中' })
|
||||
plus.payment.getChannels((channels) => {
|
||||
const iapChannel = channels.find(channel => channel.id === 'appleiap')
|
||||
if (iapChannel) {
|
||||
resolve(iapChannel)
|
||||
}
|
||||
else {
|
||||
reject(new Error('未找到 Apple IAP 支付通道'))
|
||||
}
|
||||
}, (error) => {
|
||||
reject(new Error(`获取支付通道失败:${error.message}`))
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
async function requestProduct(iapChannel, productIds) {
|
||||
return new Promise((resolve, reject) => {
|
||||
uni.showLoading({ title: '加载中' })
|
||||
console.log('请求的产品 ID 列表:', productIds)
|
||||
iapChannel.requestOrder(productIds, (products) => {
|
||||
resolve(products)
|
||||
}, (error) => {
|
||||
reject(new Error(`请求产品信息失败:${error.message}`))
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function handlePaySuccess(orderID) {
|
||||
uni.redirectTo({
|
||||
url: `/pages/result?id=${orderID}`,
|
||||
})
|
||||
}
|
||||
|
||||
onLoad((option) => {
|
||||
if (option.id) {
|
||||
id.value = option.id
|
||||
queryProvisionalOrder(option.id).then((res) => {
|
||||
console.log('res', res)
|
||||
if (res.code === 200) {
|
||||
order.value.productName = res.data.product.product_name
|
||||
order.value.price = res.data.product.sell_price
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<view class="min-h-screen from-blue-200 via-sky-200 to-sky-100 bg-gradient-to-b p-6">
|
||||
<view class="card">
|
||||
<h1 class="mb-4 text-xl font-bold">
|
||||
订单支付
|
||||
</h1>
|
||||
<view class="my-10 text-center">
|
||||
<view class="text-2xl font-bold">
|
||||
¥{{ order.price }}
|
||||
</view>
|
||||
<view class="text-gray-600">
|
||||
{{ order.productName }}
|
||||
</view>
|
||||
</view>
|
||||
<view class="mb-4">
|
||||
<label class="mb-2 block text-sm text-gray-600">支付方式</label>
|
||||
<wd-radio-group v-model="selectedPaymentMethod" shape="dot" size="large">
|
||||
<view class="border-3 border-blue-500 rounded-lg border-solid px-4 py-2">
|
||||
<wd-radio value="appleiap">
|
||||
<view class="flex items-center">
|
||||
<image
|
||||
src="/static/image/apple.svg"
|
||||
mode="aspectFit"
|
||||
class="mr-1 h-5 w-5"
|
||||
/> Apple Pay
|
||||
</view>
|
||||
</wd-radio>
|
||||
</view>
|
||||
</wd-radio-group>
|
||||
</view>
|
||||
<button
|
||||
class="w-full rounded-xl from-blue-500 via-blue-500 to-blue-400 bg-gradient-to-b px-4 py-2 text-white"
|
||||
@click="handlePayment"
|
||||
>
|
||||
立即支付
|
||||
</button>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
:deep(.wd-radio) {
|
||||
margin-top: 0;
|
||||
}
|
||||
</style>
|
||||
|
||||
<route lang="json">
|
||||
{
|
||||
"layout": "page",
|
||||
"title": "全能查收款"
|
||||
}
|
||||
</route>
|
22
src/pages/privacyPolicy.vue
Normal file
22
src/pages/privacyPolicy.vue
Normal file
@ -0,0 +1,22 @@
|
||||
<script setup>
|
||||
const webviewStyles = ref({
|
||||
top: `${uni.getSystemInfoSync().statusBarHeight + 44}px`, // 距离顶部的距离
|
||||
height: `${uni.getSystemInfoSync().windowHeight - uni.getSystemInfoSync().statusBarHeight - 44}px`, // 高度
|
||||
position: 'absolute', // 绝对定位
|
||||
dock: 'bottom', // 停靠在底部
|
||||
bounce: 'vertical', // 垂直方向的回弹效果
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<view>
|
||||
<web-view :webview-styles="webviewStyles" src="https://app.quannengcha.com/privacyPolicy" @message="handleMessage" />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<route lang="json">
|
||||
{
|
||||
"layout": "page",
|
||||
"title": "隐私政策"
|
||||
}
|
||||
</route>
|
@ -1,245 +0,0 @@
|
||||
<template>
|
||||
<view class="min-h-screen p-4 promote">
|
||||
<view class="mb-4 card !bg-gradient-to-b from-orange-200 to-orange-200/80">
|
||||
<view>
|
||||
<text class="text-lg font-bold text-orange-500 block">直推用户查询</text>
|
||||
<text class="font-bold text-orange-400 mt-1 block">自定义价格,赚取差价</text>
|
||||
</view>
|
||||
|
||||
<view class="mt-6">
|
||||
<view class="mt-2 text-gray-600 bg-orange-100 rounded-xl px-4 py-2">
|
||||
在下方 "自定义价格" 处选择报告类型,设置客户查询价(元)即可立即推广。
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<VipBanner />
|
||||
|
||||
<!-- 推广内容 -->
|
||||
<view>
|
||||
<view class="card mb-4">
|
||||
<view>
|
||||
<text class="text-xl font-semibold mb-2 block">生成推广码</text>
|
||||
<wd-form :model="formData" ref="promotionForm">
|
||||
<wd-cell-group border>
|
||||
<!-- 报告类型 -->
|
||||
<wd-picker label="报告类型" label-width="100px" v-model="formData.productType" :columns="[reportTypes]"
|
||||
title="选择报告类型" prop="productType" placeholder="请选择报告类型" @confirm="onConfirmType"
|
||||
:rules="[{ required: true, message: '请选择报告类型' }]" />
|
||||
|
||||
<!-- 定价 -->
|
||||
<wd-input label="客户查询价" label-width="100px" v-model="formData.clientPrice" placeholder="请输入价格" readonly
|
||||
clickable @click="showPricePicker = true" prop="clientPrice" suffix-icon="arrow-right"
|
||||
:rules="[{ required: true, message: '请输入客户查询价' }]" />
|
||||
</wd-cell-group>
|
||||
|
||||
<view class="flex items-center justify-between my-2">
|
||||
<text class="text-sm text-gray-500">推广收益为 <text class="text-orange-500">{{ promotionRevenue }}</text>
|
||||
元</text>
|
||||
<text class="text-sm text-gray-500">我的成本为 <text class="text-orange-500">{{ costPrice }}</text> 元</text>
|
||||
</view>
|
||||
</wd-form>
|
||||
</view>
|
||||
|
||||
<view class="mt-6">
|
||||
<button type="primary" block @click="generatePromotionCode">点击立即推广</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<PriceInputPopup v-model:show="showPricePicker" :default-price="formData.clientPrice"
|
||||
:product-config="pickerProductConfig" @change="onPriceChange" />
|
||||
|
||||
<QRcode v-model:show="showQRcode" :linkIdentifier="linkIdentifier" />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { getProductConfig, generatePromotionLink } from '@/apis/agent'
|
||||
import PriceInputPopup from '@/components/PriceInputPopup.vue'
|
||||
import VipBanner from '@/components/VipBanner.vue'
|
||||
import QRcode from '@/components/QRcode.vue'
|
||||
|
||||
// 报告类型
|
||||
const reportTypes = [
|
||||
{ label: '人事背调', value: 'backgroundcheck', id: 1 },
|
||||
{ label: '老板企业报告', value: 'companyinfo', id: 2 },
|
||||
{ label: '家政风险', value: 'homeservice', id: 3 },
|
||||
{ label: '婚恋风险', value: 'marriage', id: 4 },
|
||||
{ label: '贷前背调', value: 'preloanbackgroundcheck', id: 5 },
|
||||
{ label: '租赁风险', value: 'rentalrisk', id: 6 },
|
||||
{ label: '个人风险', value: 'riskassessment', id: 7 }
|
||||
]
|
||||
|
||||
// 状态管理
|
||||
const promotionForm = ref(null)
|
||||
const showPricePicker = ref(false)
|
||||
const pickerProductConfig = ref(null)
|
||||
const productConfig = ref(null)
|
||||
const linkIdentifier = ref("")
|
||||
const showQRcode = ref(false)
|
||||
|
||||
// 表单数据对象
|
||||
const formData = ref({
|
||||
productType: '',
|
||||
clientPrice: null
|
||||
})
|
||||
|
||||
// 计算成本价格
|
||||
const costPrice = computed(() => {
|
||||
if (!pickerProductConfig.value) return '0.00'
|
||||
// 平台定价成本
|
||||
let platformPricing = 0
|
||||
platformPricing += pickerProductConfig.value.cost_price
|
||||
if (formData.value.clientPrice > pickerProductConfig.value.p_pricing_standard) {
|
||||
platformPricing += (formData.value.clientPrice - pickerProductConfig.value.p_pricing_standard) * pickerProductConfig.value.p_overpricing_ratio
|
||||
}
|
||||
|
||||
if (pickerProductConfig.value.a_pricing_standard > platformPricing &&
|
||||
pickerProductConfig.value.a_pricing_end > platformPricing &&
|
||||
pickerProductConfig.value.a_overpricing_ratio > 0) {
|
||||
if (formData.value.clientPrice > pickerProductConfig.value.a_pricing_standard) {
|
||||
if (formData.value.clientPrice > pickerProductConfig.value.a_pricing_end) {
|
||||
platformPricing += (pickerProductConfig.value.a_pricing_end - pickerProductConfig.value.a_pricing_standard) * pickerProductConfig.value.a_overpricing_ratio
|
||||
} else {
|
||||
platformPricing += (formData.value.clientPrice - pickerProductConfig.value.a_pricing_standard) * pickerProductConfig.value.a_overpricing_ratio
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return safeTruncate(platformPricing)
|
||||
})
|
||||
|
||||
// 计算推广收益
|
||||
const promotionRevenue = computed(() => {
|
||||
return safeTruncate(formData.value.clientPrice - costPrice.value)
|
||||
})
|
||||
|
||||
// 安全截断数字(保留2位小数)
|
||||
function safeTruncate(num, decimals = 2) {
|
||||
if (isNaN(num) || !isFinite(num)) return "0.00"
|
||||
|
||||
const factor = 10 ** decimals
|
||||
const scaled = Math.trunc(num * factor)
|
||||
const truncated = scaled / factor
|
||||
|
||||
return truncated.toFixed(decimals)
|
||||
}
|
||||
|
||||
// 生成推广码
|
||||
const generatePromotionCode = async () => {
|
||||
// 表单验证
|
||||
try {
|
||||
await promotionForm.value.validate()
|
||||
} catch (e) {
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
// 获取选中产品的完整信息
|
||||
const reportType = reportTypes.find(item => item.value === formData.value.productType)
|
||||
if (!reportType) {
|
||||
uni.showToast({
|
||||
title: '请选择有效的报告类型',
|
||||
icon: 'none'
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
const res = await generatePromotionLink({
|
||||
product: formData.value.productType,
|
||||
price: formData.value.clientPrice
|
||||
})
|
||||
|
||||
if (res.code === 200) {
|
||||
linkIdentifier.value = res.data.link_identifier
|
||||
showQRcode.value = true
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: res.msg || '生成推广码失败',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
} catch (error) {
|
||||
uni.showToast({
|
||||
title: '网络错误',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 选择类型
|
||||
const selectProductType = (reportTypeValue) => {
|
||||
const reportType = reportTypes.find(item => item.id === reportTypeValue || item.value === reportTypeValue)
|
||||
|
||||
if (!reportType) return
|
||||
|
||||
formData.value.productType = reportType.value
|
||||
|
||||
if (productConfig.value) {
|
||||
for (let i of productConfig.value) {
|
||||
if (i.product_id === reportType.id) {
|
||||
pickerProductConfig.value = i
|
||||
formData.value.clientPrice = i.p_pricing_standard.toString()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 获取产品配置
|
||||
const getPromoteConfig = async () => {
|
||||
try {
|
||||
const res = await getProductConfig()
|
||||
|
||||
if (res.code === 200) {
|
||||
productConfig.value = res.data.AgentProductConfig
|
||||
// 选择第一个报告类型
|
||||
selectProductType(1) // 使用ID 1选择第一个报告类型
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: res.msg || '获取配置失败',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
uni.showToast({
|
||||
title: '网络错误',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 价格变更
|
||||
const onPriceChange = (price) => {
|
||||
formData.value.clientPrice = price
|
||||
}
|
||||
|
||||
// 类型选择确认
|
||||
const onConfirmType = (e) => {
|
||||
// picker在单列模式下返回的是选中项的值
|
||||
if (e && e.value && e.value.length > 0) {
|
||||
const selectedValue = e.value[0]
|
||||
selectProductType(selectedValue)
|
||||
}
|
||||
}
|
||||
|
||||
// 页面加载
|
||||
onMounted(() => {
|
||||
getPromoteConfig()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.card {
|
||||
border-radius: 12px;
|
||||
background-color: white;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
|
||||
padding: 16px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
</style>
|
||||
<route type="page" lang="json">{
|
||||
"layout": "page",
|
||||
"title": "推广",
|
||||
"agent": true,
|
||||
"auth": true
|
||||
}</route>
|
@ -1,144 +0,0 @@
|
||||
<template>
|
||||
<view class="min-h-screen bg-gray-50">
|
||||
<!-- 收益列表 -->
|
||||
<uni-list :loading="loading" :loadmore="loadMoreStatus" @loadmore="onLoadMore">
|
||||
<!-- 空状态提示 -->
|
||||
<view v-if="!loading && list.length === 0" class="flex flex-col items-center justify-center py-16">
|
||||
<image src="/static/image/empty.svg" mode="aspectFit" class="w-48 h-48 mb-4" />
|
||||
<text class="text-gray-400 text-base">暂无直推报告</text>
|
||||
</view>
|
||||
|
||||
<view v-for="(item, index) in list" :key="index" class="mx-4 my-2 bg-white rounded-lg p-4 shadow-sm">
|
||||
<view class="flex justify-between items-center mb-2">
|
||||
<text class="text-gray-500 text-sm">{{ item.create_time || '-' }}</text>
|
||||
<text class="text-green-500 font-bold">+{{ item.amount.toFixed(2) }}</text>
|
||||
</view>
|
||||
<view class="flex items-center">
|
||||
<text class="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium"
|
||||
:class="getReportTypeStyle(item.product_name)">
|
||||
<text class="w-2 h-2 rounded-full mr-1 inline-block" :class="getDotColor(item.product_name)"></text>
|
||||
{{ item.product_name }}
|
||||
</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 加载更多/加载完成提示 -->
|
||||
<uni-load-more :status="loadMoreStatus" />
|
||||
</uni-list>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, onMounted } from 'vue'
|
||||
import { getAgentCommission } from '@/apis/agent'
|
||||
|
||||
// 颜色配置(根据产品名称映射)
|
||||
const typeColors = {
|
||||
'老板企业报告': { bg: 'bg-blue-100', text: 'text-blue-800', dot: 'bg-blue-500' },
|
||||
'人事背调': { bg: 'bg-green-100', text: 'text-green-800', dot: 'bg-green-500' },
|
||||
'家政风险': { bg: 'bg-purple-100', text: 'text-purple-800', dot: 'bg-purple-500' },
|
||||
'婚恋风险': { bg: 'bg-pink-100', text: 'text-pink-800', dot: 'bg-pink-500' },
|
||||
'贷前背调': { bg: 'bg-orange-100', text: 'text-orange-800', dot: 'bg-orange-500' },
|
||||
'租赁风险': { bg: 'bg-indigo-100', text: 'text-indigo-800', dot: 'bg-indigo-500' },
|
||||
'个人风险': { bg: 'bg-red-100', text: 'text-red-800', dot: 'bg-red-500' },
|
||||
// 默认类型
|
||||
'default': { bg: 'bg-gray-100', text: 'text-gray-800', dot: 'bg-gray-500' }
|
||||
}
|
||||
|
||||
const page = ref(1)
|
||||
const pageSize = ref(10)
|
||||
const total = ref(0)
|
||||
const list = ref([])
|
||||
const loading = ref(false)
|
||||
const loadMoreStatus = ref('more') // 'more'|'loading'|'noMore'
|
||||
|
||||
// 获取颜色样式
|
||||
const getReportTypeStyle = (name) => {
|
||||
const color = typeColors[name] || typeColors.default
|
||||
return `${color.bg} ${color.text}`
|
||||
}
|
||||
|
||||
// 获取小圆点颜色
|
||||
const getDotColor = (name) => {
|
||||
return (typeColors[name] || typeColors.default).dot
|
||||
}
|
||||
|
||||
// 加载更多数据
|
||||
const onLoadMore = async () => {
|
||||
if (loadMoreStatus.value === 'noMore') return
|
||||
|
||||
page.value++
|
||||
await getData()
|
||||
}
|
||||
|
||||
// 获取数据
|
||||
const getData = async () => {
|
||||
try {
|
||||
loading.value = true
|
||||
loadMoreStatus.value = 'loading'
|
||||
|
||||
const res = await getAgentCommission({
|
||||
page: page.value,
|
||||
page_size: pageSize.value
|
||||
})
|
||||
|
||||
if (res.code === 200) {
|
||||
// 首次加载
|
||||
if (page.value === 1) {
|
||||
list.value = res.data.list
|
||||
total.value = res.data.total
|
||||
} else {
|
||||
// 分页加载
|
||||
list.value.push(...res.data.list)
|
||||
}
|
||||
|
||||
// 判断是否加载完成
|
||||
if (list.value.length >= res.data.total || res.data.list.length < pageSize.value) {
|
||||
loadMoreStatus.value = 'noMore'
|
||||
} else {
|
||||
loadMoreStatus.value = 'more'
|
||||
}
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: res.msg || '加载失败',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
} catch (error) {
|
||||
uni.showToast({
|
||||
title: '网络错误',
|
||||
icon: 'none'
|
||||
})
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 页面加载
|
||||
onMounted(() => {
|
||||
getData()
|
||||
})
|
||||
|
||||
// 页面下拉刷新
|
||||
const onPullDownRefresh = () => {
|
||||
page.value = 1
|
||||
loadMoreStatus.value = 'more'
|
||||
getData().then(() => {
|
||||
uni.stopPullDownRefresh()
|
||||
})
|
||||
}
|
||||
|
||||
// 导出页面生命周期方法
|
||||
defineExpose({
|
||||
onPullDownRefresh
|
||||
})
|
||||
</script>
|
||||
|
||||
<route type="page" lang="json">
|
||||
{
|
||||
"layout": "page",
|
||||
"title": "直推报告",
|
||||
"agent": true,
|
||||
"auth": true
|
||||
}
|
||||
</route>
|
@ -98,8 +98,10 @@ function statusClass(state) {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<!-- <wd-notice-bar text="为保证用户的隐私以及数据安全,您的报告生成30天之后将自动清除,请及时保存您的报告。" prefix="warn-bold" color="#007aff"
|
||||
background-color="#f8f8f8" /> -->
|
||||
<wd-notice-bar
|
||||
text="为保证用户的隐私以及数据安全,您的报告生成30天之后将自动清除,请及时保存您的报告。" prefix="warn-bold" color="#007aff"
|
||||
background-color="#f8f8f8"
|
||||
/>
|
||||
<view class="flex flex-col gap-4 p-4">
|
||||
<view v-for="item in reportList" :key="item.id" class="card flex flex-col gap-2" @click="toDetail(item)">
|
||||
<view class="flex items-center justify-between">
|
||||
@ -115,7 +117,7 @@ function statusClass(state) {
|
||||
报告类型
|
||||
</view>
|
||||
<view>
|
||||
{{ item.product_name }}
|
||||
{{ getProductName(item.product_id) }}
|
||||
</view>
|
||||
</view>
|
||||
<view class="flex items-center justify-between">
|
||||
@ -146,8 +148,9 @@ function statusClass(state) {
|
||||
}
|
||||
</style>
|
||||
|
||||
<route lang="json">{
|
||||
"layout": "page",
|
||||
"title": "历史报告",
|
||||
"auth": true
|
||||
}</route>
|
||||
<route lang="json">
|
||||
{
|
||||
"layout": "page",
|
||||
"title": "历史报告"
|
||||
}
|
||||
</route>
|
||||
|
204
src/pages/result copy.vue
Normal file
204
src/pages/result copy.vue
Normal file
@ -0,0 +1,204 @@
|
||||
<script setup>
|
||||
import CBad from '@/ui/CBad.vue'
|
||||
import CBankLoanApplication from '@/ui/CBankLoanApplication.vue'
|
||||
import CBankLoanBehavior from '@/ui/CBankLoanBehavior.vue'
|
||||
import CLawsuit from '@/ui/CLawsuit.vue'
|
||||
import CRelatedEnterprises from '@/ui/CRelatedEnterprises.vue'
|
||||
import CSpecialList from '@/ui/CSpecialList.vue'
|
||||
import CTabs from '@/ui/CTabs.vue'
|
||||
import { queryResultByOrder } from '@/api/apis'
|
||||
import CMarriage from '@/ui/CMarriage.vue'
|
||||
|
||||
const productMap = {
|
||||
1: '背景调查',
|
||||
2: '企业报告',
|
||||
3: '家政服务',
|
||||
4: '婚姻状态',
|
||||
5: '贷前背景调查',
|
||||
6: '租赁服务',
|
||||
7: '个人风险评估',
|
||||
}
|
||||
|
||||
// 根据 product_id 获取产品名称
|
||||
function getProductName(productId) {
|
||||
return productMap[productId] || '未知类型'
|
||||
}
|
||||
const productId = ref(null)
|
||||
const isDone = ref(false)
|
||||
const entData = ref(null)
|
||||
const lawsuitData = ref(null)
|
||||
const badData = ref(null)
|
||||
const specialData = ref(null)
|
||||
const bankLoanApplicationData = ref(null)
|
||||
const marriageData = ref(null)
|
||||
const bankLoanBehavior = ref(null)
|
||||
const tabs = ref([
|
||||
{ label: '报告概述', value: 'overview' },
|
||||
])
|
||||
const reportItems = ref([
|
||||
|
||||
])
|
||||
const sortedReportItems = computed(() => {
|
||||
return reportItems.value.slice().sort((a, b) => a.sort - b.sort)
|
||||
})
|
||||
const sortedTabs = computed(() => {
|
||||
return tabs.value.slice().sort((a, b) => a.sort - b.sort)
|
||||
})
|
||||
onLoad((option) => {
|
||||
console.log('option', option)
|
||||
const { id } = option
|
||||
if (id) {
|
||||
queryResultByOrder(id).then((res) => {
|
||||
console.log('res', res)
|
||||
if (res.code === 200) {
|
||||
productId.value = res.data.product_id
|
||||
res.data.query_data.forEach((item) => {
|
||||
if (item.success) {
|
||||
switch (item.apiID) {
|
||||
case 'G09SC02':
|
||||
marriageData.value = item.data
|
||||
tabs.value.push({ label: '婚姻状态', value: 'marriage', sort: 1 })
|
||||
reportItems.value.push({ label: '婚姻状态', value: 'marriage', sort: 1 })
|
||||
break
|
||||
case 'G27BJ05':
|
||||
bankLoanApplicationData.value = item.data
|
||||
tabs.value.push({ label: '借贷申请记录', value: 'netloan', sort: 7 })
|
||||
reportItems.value.push({ label: '借贷申请记录', value: 'netloan', sort: 7 })
|
||||
break
|
||||
case 'G28BJ05':
|
||||
bankLoanBehavior.value = item.data
|
||||
tabs.value.push({ label: '借贷记录', value: 'loan', sort: 6 })
|
||||
reportItems.value.push({ label: '借贷记录', value: 'loan', sort: 6 })
|
||||
|
||||
break
|
||||
case 'G26BJ05':
|
||||
specialData.value = item.data
|
||||
tabs.value.push({ label: '异常名单', value: 'special', sort: 5 })
|
||||
reportItems.value.push({ label: '异常名单', value: 'special', sort: 5 })
|
||||
|
||||
break
|
||||
case 'G05HZ01':
|
||||
entData.value = item.data
|
||||
tabs.value.push({ label: '关联企业', value: 'ent', sort: 4 })
|
||||
reportItems.value.push({ label: '关联企业', value: 'ent', sort: 4 })
|
||||
break
|
||||
case 'G34BJ03':
|
||||
badData.value = item.data
|
||||
tabs.value.push({ label: '不良风险评估', value: 'bad', sort: 3 })
|
||||
reportItems.value.push({ label: '不良风险评估', value: 'bad', sort: 3 })
|
||||
break
|
||||
case 'G35SC01':
|
||||
lawsuitData.value = item.data
|
||||
tabs.value.push({ label: '涉诉案件', value: 'lawsuit', sort: 2 })
|
||||
reportItems.value.push({ label: '涉诉案件', value: 'lawsuit', sort: 2 })
|
||||
break
|
||||
default:
|
||||
console.log(`未知的apiID: ${item.apiID}`)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}).finally(() => {
|
||||
isDone.value = true
|
||||
})
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="min-h-full from-blue-100 to-white bg-gradient-to-b">
|
||||
<CTabs
|
||||
:tabs="sortedTabs"
|
||||
type="blue-green"
|
||||
/>
|
||||
<template v-if="isDone">
|
||||
<div class="flex flex-col gap-y-4 p-4 pt-12">
|
||||
<div id="overview" class="title">
|
||||
报告概述
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="flex flex-col gap-y-2">
|
||||
<div class="flex justify-between">
|
||||
<span class="text-gray-700 font-bold">报告时间:</span>
|
||||
<span class="text-gray-600">2024年11月18日 23:11:23</span>
|
||||
</div>
|
||||
<div class="flex justify-between">
|
||||
<span class="text-gray-700 font-bold">报告项目:</span>
|
||||
<span class="text-gray-600">{{ getProductName(productId) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<LTitle class="my-4" title="报告内容" type="blue-green" />
|
||||
<div class="flex flex-col gap-y-2">
|
||||
<div v-for="item in sortedReportItems" :key="item.value" class="flex justify-between">
|
||||
<span class="text-gray-700 font-bold">{{ item.label }}:</span>
|
||||
<span class="text-green-500 font-bold">已解锁</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<template v-if="marriageData">
|
||||
<div id="marriage" class="title">
|
||||
婚姻状态
|
||||
</div>
|
||||
<CMarriage :data="marriageData" />
|
||||
</template>
|
||||
<template v-if="lawsuitData">
|
||||
<div id="lawsuit" class="title">
|
||||
涉诉案件
|
||||
</div>
|
||||
<CLawsuit :data="lawsuitData" />
|
||||
</template>
|
||||
<template v-if="badData">
|
||||
<div id="bad" class="title">
|
||||
不良风险评估
|
||||
</div>
|
||||
<CBad :data="badData" />
|
||||
</template>
|
||||
<template v-if="entData">
|
||||
<div id="ent" class="title">
|
||||
关联企业
|
||||
</div>
|
||||
<CRelatedEnterprises :data="entData" />
|
||||
</template>
|
||||
<template v-if="specialData">
|
||||
<div id="special" class="title">
|
||||
异常名单
|
||||
</div>
|
||||
<CSpecialList :data="specialData" />
|
||||
</template>
|
||||
<template v-if="bankLoanBehavior">
|
||||
<div id="loan" class="title">
|
||||
借贷记录
|
||||
</div>
|
||||
<CBankLoanBehavior :data="bankLoanBehavior" />
|
||||
</template>
|
||||
<template v-if="bankLoanApplicationData">
|
||||
<div id="netloan" class="title">
|
||||
贷款申请记录
|
||||
</div>
|
||||
<CBankLoanApplication :data="bankLoanApplicationData" />
|
||||
</template>
|
||||
<view class="card">
|
||||
<view>
|
||||
<view>
|
||||
报告说明
|
||||
</view>
|
||||
<view>本报告的数据由用户本人明确授权后,我们才向相关合法存有用户个人数据的机构调取本报告相关内容,本平台只做大数据的获取与分析,仅向用户个人展示参考。</view><p> 报告有效期<strong>30天</strong>,过期自动删除。 </p><p> 若您的数据不全面,可能是数据具有延迟性或者合作信息机构未获取到您的数据。若数据有错误请联系客服</p>
|
||||
</view>
|
||||
</view>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
</style>
|
||||
|
||||
<route lang="json">
|
||||
{
|
||||
"layout": "page",
|
||||
"title": "报告结果"
|
||||
}
|
||||
</route>
|
40
src/pages/result.vue
Normal file
40
src/pages/result.vue
Normal file
@ -0,0 +1,40 @@
|
||||
<script setup>
|
||||
const webviewStyles = ref({
|
||||
top: `${uni.getSystemInfoSync().statusBarHeight + 44}px`, // 距离顶部的距离
|
||||
height: `${uni.getSystemInfoSync().windowHeight - uni.getSystemInfoSync().statusBarHeight - 44}px`, // 高度
|
||||
position: 'absolute', // 绝对定位
|
||||
dock: 'bottom', // 停靠在底部
|
||||
bounce: 'vertical', // 垂直方向的回弹效果
|
||||
})
|
||||
const orderId = ref(null)
|
||||
const token = ref(null)
|
||||
const webviewSrc = ref('')
|
||||
|
||||
onLoad((option) => {
|
||||
if (option.id) {
|
||||
orderId.value = option.id
|
||||
}
|
||||
|
||||
token.value = uni.getStorageSync('token') || ''
|
||||
|
||||
const baseUrl = 'https://app.quannengcha.com/report'
|
||||
webviewSrc.value = `${baseUrl}?order_id=${encodeURIComponent(orderId.value)}&token=${encodeURIComponent(token.value)}`
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<view>
|
||||
<web-view :webview-styles="webviewStyles" :src="webviewSrc" />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
</style>
|
||||
|
||||
<route lang="json">
|
||||
{
|
||||
"layout": "page",
|
||||
"title": "报告结果"
|
||||
}
|
||||
</route>
|
@ -1,165 +0,0 @@
|
||||
<template>
|
||||
<view class="min-h-screen bg-gray-50">
|
||||
<!-- 收益列表 -->
|
||||
<uni-list :loading="loading" :loadmore="loadMoreStatus" @loadmore="onLoadMore">
|
||||
<!-- 空状态提示 -->
|
||||
<view v-if="!loading && list.length === 0" class="flex flex-col items-center justify-center py-16">
|
||||
<image src="/static/image/empty.svg" mode="aspectFit" class="w-48 h-48 mb-4" />
|
||||
<text class="text-gray-400 text-base">暂无收益记录</text>
|
||||
</view>
|
||||
|
||||
<view v-for="(item, index) in list" :key="index" class="mx-4 my-2 bg-white rounded-lg p-4 shadow-sm">
|
||||
<view class="flex justify-between items-center mb-2">
|
||||
<text class="text-gray-500 text-sm">{{ item.create_time || '-' }}</text>
|
||||
<text class="text-green-500 font-bold">+{{ item.amount.toFixed(2) }}</text>
|
||||
</view>
|
||||
<view class="flex items-center">
|
||||
<text class="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium"
|
||||
:class="getReportTypeStyle(item.type)">
|
||||
<text class="w-2 h-2 rounded-full mr-1 inline-block" :class="getDotColor(item.type)"></text>
|
||||
{{ typeToChinese(item.type) }}
|
||||
</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 加载更多/加载完成提示 -->
|
||||
<uni-load-more :status="loadMoreStatus" />
|
||||
</uni-list>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, onMounted } from 'vue'
|
||||
import { getAgentRewards } from '@/apis/agent'
|
||||
|
||||
// 类型映射配置
|
||||
const typeConfig = {
|
||||
descendant_promotion: {
|
||||
chinese: '下级推广奖励',
|
||||
color: { bg: 'bg-blue-100', text: 'text-blue-800', dot: 'bg-blue-500' }
|
||||
},
|
||||
descendant_upgrade_vip: {
|
||||
chinese: '下级升级VIP奖励',
|
||||
color: { bg: 'bg-green-100', text: 'text-green-800', dot: 'bg-green-500' }
|
||||
},
|
||||
descendant_upgrade_svip: {
|
||||
chinese: '下级升级SVIP奖励',
|
||||
color: { bg: 'bg-purple-100', text: 'text-purple-800', dot: 'bg-purple-500' }
|
||||
},
|
||||
descendant_stay_activedescendant: {
|
||||
chinese: '下级活跃奖励',
|
||||
color: { bg: 'bg-pink-100', text: 'text-pink-800', dot: 'bg-pink-500' }
|
||||
},
|
||||
new_active: {
|
||||
chinese: '新增活跃奖励',
|
||||
color: { bg: 'bg-orange-100', text: 'text-orange-800', dot: 'bg-orange-500' }
|
||||
},
|
||||
descendant_withdraw: {
|
||||
chinese: '下级提现奖励',
|
||||
color: { bg: 'bg-indigo-100', text: 'text-indigo-800', dot: 'bg-indigo-500' }
|
||||
},
|
||||
default: {
|
||||
chinese: '其他奖励',
|
||||
color: { bg: 'bg-gray-100', text: 'text-gray-800', dot: 'bg-gray-500' }
|
||||
}
|
||||
}
|
||||
|
||||
const page = ref(1)
|
||||
const pageSize = ref(10)
|
||||
const total = ref(0)
|
||||
const list = ref([])
|
||||
const loading = ref(false)
|
||||
const loadMoreStatus = ref('more') // 'more'|'loading'|'noMore'
|
||||
|
||||
// 类型转中文
|
||||
const typeToChinese = (type) => {
|
||||
return typeConfig[type]?.chinese || typeConfig.default.chinese
|
||||
}
|
||||
|
||||
// 获取颜色样式
|
||||
const getReportTypeStyle = (type) => {
|
||||
const config = typeConfig[type] || typeConfig.default
|
||||
return `${config.color.bg} ${config.color.text}`
|
||||
}
|
||||
|
||||
// 获取小圆点颜色
|
||||
const getDotColor = (type) => {
|
||||
return typeConfig[type]?.color.dot || typeConfig.default.color.dot
|
||||
}
|
||||
|
||||
// 加载更多数据
|
||||
const onLoadMore = async () => {
|
||||
if (loadMoreStatus.value === 'noMore') return
|
||||
|
||||
page.value++
|
||||
await getData()
|
||||
}
|
||||
|
||||
// 获取数据
|
||||
const getData = async () => {
|
||||
try {
|
||||
loading.value = true
|
||||
loadMoreStatus.value = 'loading'
|
||||
|
||||
const res = await getAgentRewards({
|
||||
page: page.value,
|
||||
page_size: pageSize.value
|
||||
})
|
||||
|
||||
if (res.code === 200) {
|
||||
if (page.value === 1) {
|
||||
list.value = res.data.list
|
||||
total.value = res.data.total
|
||||
} else {
|
||||
list.value.push(...res.data.list)
|
||||
}
|
||||
|
||||
if (list.value.length >= res.data.total || res.data.list.length < pageSize.value) {
|
||||
loadMoreStatus.value = 'noMore'
|
||||
} else {
|
||||
loadMoreStatus.value = 'more'
|
||||
}
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: res.msg || '加载失败',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
} catch (error) {
|
||||
uni.showToast({
|
||||
title: '网络错误',
|
||||
icon: 'none'
|
||||
})
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 页面加载
|
||||
onMounted(() => {
|
||||
getData()
|
||||
})
|
||||
|
||||
// 页面下拉刷新
|
||||
const onPullDownRefresh = () => {
|
||||
page.value = 1
|
||||
loadMoreStatus.value = 'more'
|
||||
getData().then(() => {
|
||||
uni.stopPullDownRefresh()
|
||||
})
|
||||
}
|
||||
|
||||
// 导出页面生命周期方法
|
||||
defineExpose({
|
||||
onPullDownRefresh
|
||||
})
|
||||
</script>
|
||||
|
||||
<route type="page" lang="json">
|
||||
{
|
||||
"layout": "page",
|
||||
"title": "收益明细",
|
||||
"agent": true,
|
||||
"auth": true
|
||||
}
|
||||
</route>
|
22
src/pages/service.vue
Normal file
22
src/pages/service.vue
Normal file
@ -0,0 +1,22 @@
|
||||
<script setup>
|
||||
const webviewStyles = ref({
|
||||
top: `${uni.getSystemInfoSync().statusBarHeight + 44}px`, // 距离顶部的距离
|
||||
height: `${uni.getSystemInfoSync().windowHeight - uni.getSystemInfoSync().statusBarHeight - 44}px`, // 高度
|
||||
position: 'absolute', // 绝对定位
|
||||
dock: 'bottom', // 停靠在底部
|
||||
bounce: 'vertical', // 垂直方向的回弹效果
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<view>
|
||||
<web-view :webview-styles="webviewStyles" src="https://app.quannengcha.com/service" />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<route lang="json">
|
||||
{
|
||||
"layout": "page",
|
||||
"title": "客户服务"
|
||||
}
|
||||
</route>
|
22
src/pages/userAgreement.vue
Normal file
22
src/pages/userAgreement.vue
Normal file
@ -0,0 +1,22 @@
|
||||
<script setup>
|
||||
const webviewStyles = ref({
|
||||
top: `${uni.getSystemInfoSync().statusBarHeight + 44}px`, // 距离顶部的距离
|
||||
height: `${uni.getSystemInfoSync().windowHeight - uni.getSystemInfoSync().statusBarHeight - 44}px`, // 高度
|
||||
position: 'absolute', // 绝对定位
|
||||
dock: 'bottom', // 停靠在底部
|
||||
bounce: 'vertical', // 垂直方向的回弹效果
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<view>
|
||||
<web-view :webview-styles="webviewStyles" src="https://app.quannengcha.com/userAgreement" />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<route lang="json">
|
||||
{
|
||||
"layout": "page",
|
||||
"title": "用户协议"
|
||||
}
|
||||
</route>
|
@ -1,26 +0,0 @@
|
||||
<template>
|
||||
<view class="relative">
|
||||
<image class="w-full" src="/static/images/vip_bg.png" mode="widthFix" />
|
||||
<view @click="toService"
|
||||
class="absolute left-[50%] translate-x-[-50%] bottom-80 bg-gradient-to-r from-gray-900 via-black to-gray-900 py-2 px-4 rounded-lg text-white text-[24px] font-bold shadow-[0_0_15px_rgba(255,255,255,0.3)]"
|
||||
hover-class="scale-105">
|
||||
点击马上报名
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
function toService() {
|
||||
// 跳转到客服页面
|
||||
uni.navigateTo({
|
||||
url: 'https://work.weixin.qq.com/kfid/kfc5c19b2b93a5e73b9'
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.scale-105 {
|
||||
transform: scale(1.05);
|
||||
transition: transform 0.3s;
|
||||
}
|
||||
</style>
|
@ -1,427 +0,0 @@
|
||||
<template>
|
||||
<view class="min-h-screen bg-blue-50/30">
|
||||
<view class="p-4">
|
||||
<!-- 提现卡片 -->
|
||||
<view class="bg-white rounded-lg p-5 mb-4">
|
||||
<view class="flex items-center mb-6">
|
||||
<view class="w-6 h-6 bg-orange-100 rounded-full flex items-center justify-center mr-2">
|
||||
<text class="text-orange-400 text-sm">¥</text>
|
||||
</view>
|
||||
<text class="text-lg font-bold">支付宝提现</text>
|
||||
</view>
|
||||
|
||||
<wd-form :model="form" :rules="rules" label-position="top" class="withdraw-form">
|
||||
<!-- 支付宝账号 -->
|
||||
<view class="mb-4">
|
||||
<view class="mb-2">
|
||||
<text class="text-red-500 mr-1">*</text>
|
||||
<text class="text-base">支付宝账号</text>
|
||||
</view>
|
||||
<wd-input v-model="form.alipayAccount" prop="alipayAccount" placeholder="请输入支付宝账号"
|
||||
custom-class="custom-input" />
|
||||
<text class="text-gray-400 text-xs mt-1 block">可填写支付宝账户绑定的手机号</text>
|
||||
</view>
|
||||
|
||||
<!-- 支付宝实名姓名 -->
|
||||
<view class="mb-4">
|
||||
<view class="mb-2">
|
||||
<text class="text-red-500 mr-1">*</text>
|
||||
<text class="text-base">实名姓名</text>
|
||||
</view>
|
||||
<wd-input v-model="form.realName" prop="realName" placeholder="请输入支付宝认证姓名" custom-class="custom-input" />
|
||||
<text class="text-gray-400 text-xs mt-1 block">请填写支付宝账户认证的真实姓名</text>
|
||||
</view>
|
||||
|
||||
<!-- 提现金额 -->
|
||||
<view class="mb-4">
|
||||
<view class="mb-2">
|
||||
<text class="text-red-500 mr-1">*</text>
|
||||
<text class="text-base">提现金额</text>
|
||||
</view>
|
||||
<view class="relative">
|
||||
<wd-input v-model="form.amount" prop="amount" type="digit" placeholder="请输入提现金额"
|
||||
custom-class="custom-input" @input="handleAmountInput" />
|
||||
<view class="absolute right-2 top-1/2 transform -translate-y-1/2">
|
||||
<view class="bg-blue-100 text-blue-600 rounded-full px-3 py-1 text-sm" @click="fillMaxAmount">
|
||||
全部提现
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</wd-form>
|
||||
|
||||
<!-- 金额提示 -->
|
||||
<view class="text-sm text-gray-500 my-4">
|
||||
可提现金额:<text class="text-blue-600 font-semibold">¥{{ safeTruncate(availableAmount) }}</text>
|
||||
</view>
|
||||
|
||||
<!-- 提现规则 -->
|
||||
<view class="bg-gray-50 p-4 rounded-lg">
|
||||
<view class="flex items-center">
|
||||
<text class="text-orange-500 mr-1">⚠</text>
|
||||
<text class="text-blue-600 text-sm">提现须知</text>
|
||||
</view>
|
||||
<view class="text-xs text-gray-600 mt-2 space-y-1">
|
||||
<text class="block">· 每日限提现1次,最低50元</text>
|
||||
<text class="block">· 超过800元需人工审核(1-3个工作日)</text>
|
||||
<text class="block">· 到账时间:24小时内</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 提交按钮 -->
|
||||
<wd-button type="primary" block :loading="isSubmitting" @click="handleSubmit" custom-class="submit-button">
|
||||
立即提现
|
||||
</wd-button>
|
||||
</view>
|
||||
|
||||
<!-- 状态弹窗 -->
|
||||
<wd-popup v-model="popupVisible" custom-class="w-[85%] rounded-xl" closable close-on-click-modal>
|
||||
<view class="p-8 bg-gradient-to-b from-white to-blue-50/30 relative">
|
||||
<!-- 状态内容 -->
|
||||
<view class="text-center space-y-5">
|
||||
<!-- 状态图标 -->
|
||||
<view class="relative inline-block">
|
||||
<view class="w-14 h-14 rounded-full flex items-center justify-center" :class="statusIconClass[status]">
|
||||
<text class="text-4xl">{{ statusIcon[status] }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 状态文案 -->
|
||||
<view>
|
||||
<text class="text-xl font-semibold mb-1 block" :class="statusTextColors[status]">
|
||||
{{ statusMessages[status] }}
|
||||
</text>
|
||||
<template v-if="status === 2">
|
||||
<text class="text-sm text-gray-500 block">
|
||||
已向 <text class="text-blue-500">{{ form.alipayAccount }}</text> 转账
|
||||
</text>
|
||||
<text class="text-2xl font-bold text-green-600 mt-2 block">¥{{ form.amount }}</text>
|
||||
</template>
|
||||
<template v-if="status === 3">
|
||||
<text class="text-red-500 text-sm px-4 block">{{ failMsg }}</text>
|
||||
</template>
|
||||
</view>
|
||||
|
||||
<!-- 进度条(处理中状态) -->
|
||||
<view v-if="status === 1" class="my-2">
|
||||
<wd-progress :percentage="60" hide-text color="#4080ff" />
|
||||
</view>
|
||||
|
||||
<!-- 辅助文案 -->
|
||||
<view class="text-xs text-gray-400 space-y-1.5">
|
||||
<template v-if="status === 2">
|
||||
<text class="block">预计24小时内到账</text>
|
||||
<text class="block">到账后可在支付宝账单中查看详情</text>
|
||||
</template>
|
||||
<template v-if="status === 1">
|
||||
<text class="block">您的申请已进入处理队列</text>
|
||||
<text class="block">5分钟后结果在提现记录中查看</text>
|
||||
</template>
|
||||
</view>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<wd-button type="primary" block class="mt-4" :style="{ backgroundColor: statusButtonColor[status] }"
|
||||
@click="handlePopupAction">
|
||||
{{ status === 1 ? '知道了' : status === 2 ? '完成' : '重新提现' }}
|
||||
</wd-button>
|
||||
</view>
|
||||
</view>
|
||||
</wd-popup>
|
||||
<wd-toast />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, onMounted, watch } from 'vue'
|
||||
import { useToast } from 'wot-design-uni'
|
||||
import { getAgentRevenue, agentWithdrawal } from '@/apis/agent'
|
||||
|
||||
// 安全截断数字到指定小数位数(不进行四舍五入)
|
||||
function safeTruncate(num, decimals = 2) {
|
||||
if (isNaN(num) || !isFinite(num)) return "0.00";
|
||||
|
||||
const factor = 10 ** decimals;
|
||||
const scaled = Math.trunc(num * factor);
|
||||
const truncated = scaled / factor;
|
||||
|
||||
return truncated.toFixed(decimals);
|
||||
}
|
||||
|
||||
// 表单数据
|
||||
const form = ref({
|
||||
alipayAccount: '',
|
||||
realName: '',
|
||||
amount: ''
|
||||
})
|
||||
const availableAmount = ref(0)
|
||||
const isSubmitting = ref(false)
|
||||
|
||||
// 使用wot-design-ui的toast组件
|
||||
const toast = useToast()
|
||||
|
||||
// 弹窗控制
|
||||
const popupVisible = ref(false)
|
||||
|
||||
// 状态管理
|
||||
const status = ref(null)
|
||||
const failMsg = ref('')
|
||||
|
||||
|
||||
// 表单验证规则
|
||||
const rules = {
|
||||
alipayAccount: [
|
||||
{ required: true, message: '请输入支付宝账号' }
|
||||
],
|
||||
realName: [
|
||||
{ required: true, message: '请输入姓名' },
|
||||
{
|
||||
required: true,
|
||||
pattern: /^[\u4e00-\u9fa5]{2,4}$/,
|
||||
message: '请输入2-4位中文姓名'
|
||||
}
|
||||
],
|
||||
amount: [
|
||||
{ required: true, message: '请输入提现金额' },
|
||||
{
|
||||
validator: (val) => {
|
||||
const amountNum = Number(val)
|
||||
if (isNaN(amountNum)) {
|
||||
return '请输入有效金额'
|
||||
}
|
||||
// if (amountNum < 50) {
|
||||
// return '提现金额不能低于50元'
|
||||
// }
|
||||
if (amountNum > availableAmount.value) {
|
||||
return '超过可提现金额'
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
// 样式配置
|
||||
const statusIcon = {
|
||||
1: '⏳',
|
||||
2: '✅',
|
||||
3: '❌'
|
||||
}
|
||||
|
||||
const statusIconClass = {
|
||||
1: 'bg-blue-100 text-blue-500 border-4 border-blue-200',
|
||||
2: 'bg-green-100 text-green-500 border-4 border-green-200',
|
||||
3: 'bg-red-100 text-red-500 border-4 border-red-200'
|
||||
}
|
||||
|
||||
const statusTextColors = {
|
||||
1: 'text-blue-600',
|
||||
2: 'text-green-600',
|
||||
3: 'text-red-600'
|
||||
}
|
||||
|
||||
const statusButtonColor = {
|
||||
1: '#3b82f6',
|
||||
2: '#4ade80',
|
||||
3: '#f87171'
|
||||
}
|
||||
|
||||
const statusMessages = {
|
||||
1: '提现申请处理中,请稍后再查询结果',
|
||||
2: '提现成功',
|
||||
3: '提现失败'
|
||||
}
|
||||
|
||||
// 返回上一页
|
||||
const handleBack = () => {
|
||||
uni.navigateBack()
|
||||
}
|
||||
|
||||
// 获取可提现金额
|
||||
const getData = async () => {
|
||||
try {
|
||||
const res = await getAgentRevenue()
|
||||
|
||||
if (res.code === 200) {
|
||||
availableAmount.value = res.data.balance
|
||||
} else {
|
||||
toast.error(res.msg || '获取余额失败')
|
||||
}
|
||||
} catch (error) {
|
||||
toast.error('网络错误')
|
||||
}
|
||||
}
|
||||
|
||||
// 填充最大金额
|
||||
const fillMaxAmount = () => {
|
||||
// 使用safeTruncate确保金额正确截断到2位小数
|
||||
form.value.amount = safeTruncate(availableAmount.value)
|
||||
}
|
||||
|
||||
// 处理输入事件,控制输入格式
|
||||
const handleAmountInput = (event) => {
|
||||
let value = event.value
|
||||
// 转为数字以便比较
|
||||
let numValue = parseFloat(value)
|
||||
|
||||
// 如果超过可提现金额,设置为可提现金额并提示
|
||||
if (!isNaN(numValue) && numValue > availableAmount.value) {
|
||||
value = availableAmount.value
|
||||
// 使用toast提示用户
|
||||
toast.info(`金额已自动调整为最大可提现金额: ¥${value}`)
|
||||
}
|
||||
// 如果value的小数位数大于2位,才进行截断处理
|
||||
if (value.toString().includes('.') && value.toString().split('.')[1].length > 2) {
|
||||
value = safeTruncate(value)
|
||||
}
|
||||
form.value.amount = value
|
||||
console.log(value)
|
||||
console.log(form.value.amount)
|
||||
}
|
||||
|
||||
// 提交处理
|
||||
const handleSubmit = async () => {
|
||||
try {
|
||||
// 提现金额转为数字
|
||||
const amountNum = Number(form.value.amount)
|
||||
|
||||
// 验证表单
|
||||
if (!form.value.alipayAccount.trim()) {
|
||||
toast.info('请输入支付宝账号')
|
||||
return
|
||||
}
|
||||
|
||||
if (!form.value.realName.trim()) {
|
||||
toast.info('请输入账户实名姓名')
|
||||
return
|
||||
}
|
||||
|
||||
if (!/^[\u4e00-\u9fa5]{2,4}$/.test(form.value.realName)) {
|
||||
toast.info('请输入2-4位中文姓名')
|
||||
return
|
||||
}
|
||||
|
||||
if (!form.value.amount || isNaN(amountNum)) {
|
||||
toast.info('请输入有效金额')
|
||||
return
|
||||
}
|
||||
|
||||
// if (amountNum < 50) {
|
||||
// toast.info('提现金额不能低于50元')
|
||||
// return
|
||||
// }
|
||||
|
||||
if (amountNum > availableAmount.value) {
|
||||
toast.info('超过可提现金额')
|
||||
return
|
||||
}
|
||||
|
||||
isSubmitting.value = true
|
||||
|
||||
const res = await agentWithdrawal({
|
||||
payee_account: form.value.alipayAccount,
|
||||
amount: amountNum,
|
||||
payee_name: form.value.realName
|
||||
})
|
||||
|
||||
if (res.code === 200) {
|
||||
status.value = res.data.status
|
||||
if (status.value === 3) {
|
||||
failMsg.value = res.data.fail_msg
|
||||
}
|
||||
popupVisible.value = true
|
||||
} else {
|
||||
toast.error(res.msg || '提交失败')
|
||||
}
|
||||
} catch (error) {
|
||||
toast.error('网络错误')
|
||||
} finally {
|
||||
isSubmitting.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 弹窗操作
|
||||
const handlePopupAction = () => {
|
||||
popupVisible.value = false
|
||||
|
||||
if (status.value === 2) {
|
||||
resetForm()
|
||||
getData()
|
||||
}
|
||||
}
|
||||
|
||||
// 重置表单
|
||||
const resetForm = () => {
|
||||
status.value = null
|
||||
form.value = {
|
||||
alipayAccount: '',
|
||||
realName: '',
|
||||
amount: ''
|
||||
}
|
||||
}
|
||||
|
||||
// 页面加载
|
||||
onMounted(() => {
|
||||
getData()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style>
|
||||
@keyframes progress {
|
||||
0% {
|
||||
width: 0;
|
||||
}
|
||||
|
||||
100% {
|
||||
width: 60%;
|
||||
}
|
||||
}
|
||||
|
||||
.animate-progress {
|
||||
animation: progress 1.5s ease-in-out infinite;
|
||||
animation-direction: alternate;
|
||||
}
|
||||
|
||||
/* 自定义样式 */
|
||||
.withdraw-form :deep(.wd-form-item) {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.withdraw-form :deep(.wd-input__label) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.withdraw-form :deep(.custom-input .wd-input__inner) {
|
||||
padding: 10px 15px;
|
||||
font-size: 14px;
|
||||
height: 45px;
|
||||
border: none;
|
||||
background-color: rgba(64, 128, 255, 0.05);
|
||||
border-radius: 12px;
|
||||
transition: all 0.3s ease;
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.withdraw-form :deep(.custom-input:focus-within .wd-input__inner) {
|
||||
border: 2px solid #4080ff;
|
||||
background-color: rgba(64, 128, 255, 0.08);
|
||||
box-shadow: 0 0 0 2px rgba(64, 128, 255, 0.1);
|
||||
}
|
||||
|
||||
.withdraw-form :deep(.wd-input__prefix) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.submit-button {
|
||||
height: 45px;
|
||||
border-radius: 6px;
|
||||
background-color: #4080ff !important;
|
||||
font-size: 16px;
|
||||
}
|
||||
</style>
|
||||
<route type="page" lang="json">{
|
||||
"layout": "page",
|
||||
"title": "提现",
|
||||
"auth": true,
|
||||
"agent": true
|
||||
}</route>
|
@ -1,181 +0,0 @@
|
||||
<template>
|
||||
<view class="min-h-screen bg-gray-50">
|
||||
<!-- 提现记录列表 -->
|
||||
<uni-list :loading="loading" :loadmore="loadMoreStatus" @loadmore="onLoadMore">
|
||||
<!-- 空状态提示 -->
|
||||
<view v-if="!loading && list.length === 0" class="flex flex-col items-center justify-center py-16">
|
||||
<image src="/static/image/empty.svg" mode="aspectFit" class="w-48 h-48 mb-4" />
|
||||
<text class="text-gray-400 text-base">暂无提现记录</text>
|
||||
</view>
|
||||
|
||||
<view v-for="(item, index) in list" :key="index" class="mx-4 my-2 bg-white rounded-lg p-4 shadow-sm">
|
||||
<view class="flex justify-between items-center mb-2">
|
||||
<text class="text-gray-500 text-sm">{{ item.create_time || '-' }}</text>
|
||||
<text class="font-bold" :class="getAmountColor(item.status)">{{ item.amount.toFixed(2) }}元</text>
|
||||
</view>
|
||||
<view class="flex items-center mb-2">
|
||||
<text class="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium"
|
||||
:class="getStatusStyle(item.status)">
|
||||
<text class="w-2 h-2 rounded-full mr-1 inline-block" :class="getDotColor(item.status)"></text>
|
||||
{{ statusToChinese(item.status) }}
|
||||
</text>
|
||||
</view>
|
||||
<view class="text-xs text-gray-500">
|
||||
<text v-if="item.payee_account" class="block">收款账户:{{ maskName(item.payee_account) }}</text>
|
||||
<text v-if="item.remark" class="block">备注:{{ item.remark }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 加载更多/加载完成提示 -->
|
||||
<uni-load-more :status="loadMoreStatus" />
|
||||
</uni-list>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, onMounted } from 'vue'
|
||||
import { getWithdrawalRecords } from '@/apis/agent'
|
||||
|
||||
// 状态映射配置
|
||||
const statusConfig = {
|
||||
1: {
|
||||
chinese: '处理中',
|
||||
color: {
|
||||
bg: 'bg-yellow-100',
|
||||
text: 'text-yellow-800',
|
||||
dot: 'bg-yellow-500',
|
||||
amount: 'text-yellow-500'
|
||||
}
|
||||
},
|
||||
2: {
|
||||
chinese: '提现成功',
|
||||
color: {
|
||||
bg: 'bg-green-100',
|
||||
text: 'text-green-800',
|
||||
dot: 'bg-green-500',
|
||||
amount: 'text-green-500'
|
||||
}
|
||||
},
|
||||
3: {
|
||||
chinese: '提现失败',
|
||||
color: {
|
||||
bg: 'bg-red-100',
|
||||
text: 'text-red-800',
|
||||
dot: 'bg-red-500',
|
||||
amount: 'text-red-500'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const page = ref(1)
|
||||
const pageSize = ref(10)
|
||||
const total = ref(0)
|
||||
const list = ref([])
|
||||
const loading = ref(false)
|
||||
const loadMoreStatus = ref('more') // 'more'|'loading'|'noMore'
|
||||
|
||||
// 账户脱敏处理
|
||||
const maskName = (name) => {
|
||||
if (!name || typeof name !== 'string') return ''
|
||||
if (name.length <= 7) return name
|
||||
return name.substring(0, 3) + '****' + name.substring(7)
|
||||
}
|
||||
|
||||
// 状态转中文
|
||||
const statusToChinese = (status) => {
|
||||
return statusConfig[status]?.chinese || '未知状态'
|
||||
}
|
||||
|
||||
// 获取状态样式
|
||||
const getStatusStyle = (status) => {
|
||||
const config = statusConfig[status] || {}
|
||||
return `${config.color?.bg || 'bg-gray-100'} ${config.color?.text || 'text-gray-800'}`
|
||||
}
|
||||
|
||||
// 获取小圆点颜色
|
||||
const getDotColor = (status) => {
|
||||
return statusConfig[status]?.color.dot || 'bg-gray-500'
|
||||
}
|
||||
|
||||
// 获取金额颜色
|
||||
const getAmountColor = (status) => {
|
||||
return statusConfig[status]?.color.amount || 'text-gray-500'
|
||||
}
|
||||
|
||||
// 加载更多数据
|
||||
const onLoadMore = async () => {
|
||||
if (loadMoreStatus.value === 'noMore') return
|
||||
|
||||
page.value++
|
||||
await getData()
|
||||
}
|
||||
|
||||
// 获取数据
|
||||
const getData = async () => {
|
||||
try {
|
||||
loading.value = true
|
||||
loadMoreStatus.value = 'loading'
|
||||
|
||||
const res = await getWithdrawalRecords({
|
||||
page: page.value,
|
||||
page_size: pageSize.value
|
||||
})
|
||||
|
||||
if (res.code === 200) {
|
||||
if (page.value === 1) {
|
||||
list.value = res.data.list
|
||||
total.value = res.data.total
|
||||
} else {
|
||||
list.value.push(...res.data.list)
|
||||
}
|
||||
|
||||
if (list.value.length >= res.data.total || res.data.list.length < pageSize.value) {
|
||||
loadMoreStatus.value = 'noMore'
|
||||
} else {
|
||||
loadMoreStatus.value = 'more'
|
||||
}
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: res.msg || '加载失败',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
} catch (error) {
|
||||
uni.showToast({
|
||||
title: '网络错误',
|
||||
icon: 'none'
|
||||
})
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 页面加载
|
||||
onMounted(() => {
|
||||
getData()
|
||||
})
|
||||
|
||||
// 页面下拉刷新
|
||||
const onPullDownRefresh = () => {
|
||||
page.value = 1
|
||||
loadMoreStatus.value = 'more'
|
||||
getData().then(() => {
|
||||
uni.stopPullDownRefresh()
|
||||
})
|
||||
}
|
||||
|
||||
// 导出页面生命周期方法
|
||||
defineExpose({
|
||||
onPullDownRefresh
|
||||
})
|
||||
</script>
|
||||
|
||||
<style>
|
||||
/* 自定义样式 */
|
||||
</style>
|
||||
<route type="page" lang="json">{
|
||||
"layout": "page",
|
||||
"title": "提现记录",
|
||||
"auth": true,
|
||||
"agent": true
|
||||
}</route>
|
23
src/static/app-plus/echarts.min.js
vendored
Normal file
23
src/static/app-plus/echarts.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
23
src/static/h5/echarts.min.js
vendored
Normal file
23
src/static/h5/echarts.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
Binary file not shown.
Before Width: | Height: | Size: 52 KiB |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user