Compare commits

..

2 Commits

Author SHA1 Message Date
ecc6cca6c1 tempp 2025-03-14 04:57:49 +08:00
d88388d04b 新版本 2025-03-14 03:40:55 +08:00
140 changed files with 6228 additions and 20319 deletions

37
.cursorrules Normal file
View File

@ -0,0 +1,37 @@
// 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 Normal file
View File

@ -0,0 +1,5 @@
# 基础环境变量配置
VITE_APP_BASE_URL=https://www.quannengcha.com
VITE_APP_SHARE_URL=https://www.tianyuandata.com
# 默认环境配置
VITE_APP_DEBUG=false

5
.env.development Normal file
View File

@ -0,0 +1,5 @@
# 开发环境配置
VITE_APP_BASE_URL=https://www.quannengcha.com
# 是否启用调试模式
VITE_APP_DEBUG=true

5
.env.production Normal file
View File

@ -0,0 +1,5 @@
# 生产环境配置
VITE_APP_BASE_URL=https://www.quannengcha.com
# 关闭调试模式
VITE_APP_DEBUG=false

View File

@ -5,14 +5,13 @@
// Auto fix
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit",
"source.organizeImports": "never"
},
// Silent the stylistic rules in you IDE, but still auto fix them
"eslint.rules.customizations": [
{ "rule": "style/*", "severity": "off", "fixable": true },
// { "rule": "format/*", "severity": "off", "fixable": true },
{ "rule": "format/*", "severity": "off", "fixable": true },
{ "rule": "*-indent", "severity": "off", "fixable": true },
{ "rule": "*-spacing", "severity": "off", "fixable": true },
{ "rule": "*-spaces", "severity": "off", "fixable": true },

View File

@ -1,251 +0,0 @@
{
"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"
}

File diff suppressed because it is too large Load Diff

View File

@ -1,55 +0,0 @@
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}`)
}
})
})

View File

@ -1,41 +0,0 @@
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}`)
}
})
})

View File

@ -1,822 +0,0 @@
[
"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"
]

View File

View File

@ -1,51 +0,0 @@
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)

View File

@ -1,65 +0,0 @@
{
"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"
}
}
]
}
}

View File

@ -1,646 +0,0 @@
{
"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": "南工商高新处字2016500010024号",
"type": "",
"content": "",
"decisionDate": "2016-03-19",
"legalPersonName": "李强"
},
{
"departmentName": "45011101",
"reason": "南宁恒发网络科技有限公司等3177户企业未依法进行企业信息网上年报公示。经我分局执法人员在以上企业的执照注册住所检查发现上述企业已不在其注册住所经营或办公根据企业注册登记时所留电话也联系不上上述企业。",
"punishNumber": "南工商高新处字2016500010024号",
"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"
}
}
]
}
}

View File

@ -1,150 +0,0 @@
{
"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"
}
}
]
}
}

View File

@ -1,154 +0,0 @@
{
"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"
}

View File

@ -1,133 +0,0 @@
{
"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"
}

View File

@ -1,17 +0,0 @@
{
"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"
}
}
}

View File

@ -0,0 +1,53 @@
# 环境变量配置说明
## 环境变量文件
本项目使用 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密钥等

View File

@ -1,15 +0,0 @@
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',
},
},
)

View File

@ -26,6 +26,7 @@ export default defineManifestConfig({
/* 模块配置 */
modules: {
Payment: {},
Share: {},
},
/* 应用发布信息 */
distribute: {
@ -60,6 +61,19 @@ 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: {
@ -124,4 +138,24 @@ 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
}
}
}
}
}
})

View File

@ -41,39 +41,43 @@
"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",
"lint": "eslint .",
"lint:fix": "eslint . --fix"
"type-check": "vue-tsc --noEmit"
},
"dependencies": {
"@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",
"@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",
"@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.12",
"@dcloudio/uni-automator": "3.0.0-4020420240722002",
"@dcloudio/uni-cli-shared": "3.0.0-4020420240722002",
"@dcloudio/uni-stacktracey": "3.0.0-4020420240722002",
"@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/uni-vue-devtools": "3.0.0-4020420240722002",
"@dcloudio/vite-plugin-uni": "3.0.0-4020420240722002",
"@dcloudio/vite-plugin-uni": "3.0.0-4050520250307001",
"@iconify-json/carbon": "^1.2.3",
"@mini-types/alipay": "^3.0.14",
"@types/node": "^20.16.12",
@ -89,14 +93,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",
"vite": "^5.4.9",
"unplugin-vue-components": "^28.4.1",
"vite": "^5.2.8",
"vue-tsc": "^2.1.6"
}
}

View File

@ -24,6 +24,11 @@ export default defineUniPages({
text: '',
visible: false,
},
{
pagePath: 'pages/agent',
text: '',
visible: false,
},
{
pagePath: 'pages/ai',
text: '',

File diff suppressed because it is too large Load Diff

View File

@ -1,54 +1,88 @@
<script setup>
import { getToken } from '@/api/apis.js'
import { onLaunch } from '@dcloudio/uni-app'
import { refreshToken, getUserInfo } from '@/api/apis'
import { getAgentInfo } from '@/apis/agent'
onLaunch(() => {
initGetPlatform()
RefreshToken()
refreshTokenIfNeeded()
getUser()
getAgentInformation()
})
function initGetPlatform() {
uni.getSystemInfo().then((res) => {
console.log('res', res)
const platform = res.uniPlatform
uni.setStorageSync('platform', platform)
})
}
function RefreshToken() {
const token = uni.getStorageSync('token')
const refreshAfter = uni.getStorageSync('refreshAfter')
const accessExpire = uni.getStorageSync('accessExpire')
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 = Number.parseInt(accessExpire) * 1000 //
const accessExpireInMilliseconds = parseInt(accessExpire) * 1000 //
if (currentTime > accessExpireInMilliseconds) {
uni.removeStorageSync('token')
uni.removeStorageSync('refreshAfter')
uni.removeStorageSync('accessExpire')
return
}
}
// 1. token
// token
if (!token) {
return
}
// 2. refreshAfter refreshAfterrefreshAfter
// refreshAfter refreshAfter
if (refreshAfter) {
const refreshAfterInMilliseconds = Number.parseInt(refreshAfter) * 1000 //
const refreshAfterInMilliseconds = parseInt(refreshAfter) * 1000 //
if (currentTime < refreshAfterInMilliseconds) {
return
}
}
// 3. refreshAfter refreshAfter token
refreshToken()
}
async function refreshToken() {
getToken().then((res) => {
// 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)
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>

View File

@ -16,13 +16,6 @@ export function login(data) {
data,
})
}
export function getToken(data) {
return request({
url: '/user/getToken',
method: 'POST',
data,
})
}
export function getCode(data) {
return request({
url: '/auth/sendSms',
@ -126,3 +119,17 @@ 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',
});
}

138
src/apis/agent.js Normal file
View File

@ -0,0 +1,138 @@
// 代理相关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
})
}

View File

@ -3,6 +3,8 @@
}
html {
margin: auto !important;
@apply max-w-lg;
font-size: 4px; // * 方便unocss计算1单位 = 0.25rem = 1px
}
@ -40,3 +42,9 @@ 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);
}

View File

@ -113,6 +113,8 @@ 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']
@ -249,6 +251,7 @@ 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']
@ -285,6 +288,7 @@ 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']
@ -433,6 +437,7 @@ 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']>
@ -484,7 +489,6 @@ 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']>
@ -565,7 +569,6 @@ 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']>

35
src/components.d.ts vendored
View File

@ -7,36 +7,11 @@ export {}
declare module 'vue' {
export interface GlobalComponents {
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']
AgentApplicationForm: typeof import('./components/AgentApplicationForm.vue')['default']
EnvDemo: typeof import('./components/EnvDemo.vue')['default']
PriceInputPopup: typeof import('./components/PriceInputPopup.vue')['default']
PrivacyModel: typeof import('./components/PrivacyModel.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']
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']
WebviewPage: typeof import('./components/WebviewPage.vue')['default']
QRcode: typeof import('./components/QRcode.vue')['default']
VipBanner: typeof import('./components/VipBanner.vue')['default']
}
}

View File

@ -0,0 +1,341 @@
<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-uitoast
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.valuevalue
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
})
// popupVisibleprops.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>

View File

@ -1,25 +0,0 @@
<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>

View File

@ -1,27 +0,0 @@
<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>

View File

@ -0,0 +1,84 @@
<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>

View File

@ -1,23 +0,0 @@
<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>

View File

@ -1,47 +0,0 @@
<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>

View File

@ -1,87 +0,0 @@
<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>

View File

@ -1,61 +0,0 @@
<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>

View File

@ -1,30 +0,0 @@
<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>

View File

@ -1,98 +0,0 @@
<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>

View File

@ -1,58 +0,0 @@
<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>

View File

@ -0,0 +1,179 @@
<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>

View File

@ -51,11 +51,11 @@ onMounted(() => {
</view>
<view class="modal-message">
感谢您使用全能查APP! 我们非常重视您的隐私保护和个人信息保护在您使用全能查APP前请您仔细阅读充分理解
<text class="link" @click="openPage('/pages/userAgreement')">
<text class="link" @click="openPage('/pages/agreement?type=user')">
用户协议
</text>
<text class="link" @click="openPage('/pages/privacyPolicy')">
<text class="link" @click="openPage('/pages/agreement?type=privacy')">
隐私政策
</text>
的各项条款如果您同意请点击下方按钮开始接受我们的服务

545
src/components/QRcode.vue Normal file
View File

@ -0,0 +1,545 @@
<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(() => {
// uniappURL
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, // WXSceneSessionWXSceneTimeline
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>

View File

@ -0,0 +1,36 @@
<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>

View File

@ -1,147 +0,0 @@
<script setup>
// props
const props = defineProps({
webviewSrc: {
type: String,
required: true,
},
})
onMounted(() => {
})
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 token = uni.getStorageSync('token') // token
const env = uni.getStorageSync('platform')
// const baseUrl = `${window.location.origin}/app`
const baseUrl = 'https://www.quannengcha.com'
// const baseUrl = 'http://192.168.1.124:5678'
const webviewUrl = computed(() => {
let urlStr = baseUrl + props.webviewSrc
if (token) {
// url
urlStr += `${urlStr.includes('?') ? '&' : '?'}token=${token}`
}
urlStr += `${urlStr.includes('?') ? '&' : '?'}env=${env}#wechat_redirect`
return urlStr
})
const isLoading = ref(true) //
// const processedMessages = new Set() // ID
//
function handleLoaded() {
isLoading.value = false
}
//
// window.addEventListener('message', (event) => {
// const message = event.data
// const action = message?.action
// const messageId = message?.messageId
// const data = message?.data
// if (message.hello || message.wappalyzer)
// return
// if (!action)
// return
// if (processedMessages.has(messageId)) {
// return
// }
// processedMessages.add(messageId)
// if (action === 'loaded') {
// if (data)
// isLoading.value = false
// }
// else if (action === 'navigateTo') {
// uni.navigateTo(data)
// }
// else if (action === 'redirectTo') {
// uni.redirectTo(data)
// }
// else if (action === 'navigateBack') {
// uni.navigateBack(data)
// }
// else if (action === 'payment') {
// payment(data)
// }
// })
function onMessage(e) {
const data = e.detail.data
const message = data[data.length - 1]
console.log('message', message)
if (message.action === 'payment') {
console.log('data', message.data)
payment(message.data)
}
}
function payment(data) {
uni.navigateTo({
url: `/pages/me?paymentID${data}`,
})
}
</script>
<template>
<view v-if="isLoading" class="loading">
<view class="spinner" />
<view class="loading-text">
加载中请稍候...
</view>
</view>
<web-view :webview-styles="webviewStyles" :src="webviewUrl" @load="handleLoaded" @message="onMessage" />
</template>
<style scoped>
.loading {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
background: rgba(255, 255, 255, 0.9);
z-index: 10;
}
.spinner {
width: 50px;
height: 50px;
border: 5px solid rgba(0, 106, 255, 0.2);
/* 背景圆环颜色 */
border-top-color: rgba(0, 106, 255, 0.8);
/* 高亮部分颜色 */
border-radius: 50%;
animation: spin 1s linear infinite;
}
.loading-text {
margin-top: 16px;
font-size: 16px;
font-weight: bold;
background: linear-gradient(to right, #167ff6, #4a90e2);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
text-align: center;
}
@keyframes spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
</style>

View File

@ -1,201 +0,0 @@
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.

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -1,162 +0,0 @@
<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>

View File

@ -1,170 +0,0 @@
<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>

View File

@ -1,173 +0,0 @@
<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>

View File

@ -1,222 +0,0 @@
<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>

View File

@ -1,229 +0,0 @@
<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>

View File

@ -1,36 +0,0 @@
<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>

View File

@ -1,422 +0,0 @@
/*
* uCharts®
* 高性能跨平台图表库支持H5APP小程序微信/支付宝/百度/头条/QQ/360VueTaro等支持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;

View File

@ -1,606 +0,0 @@
/*
* uCharts®
* 高性能跨平台图表库支持H5APP小程序微信/支付宝/百度/头条/QQ/360VueTaro等支持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;

View File

@ -1,201 +0,0 @@
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.

View File

@ -1,5 +0,0 @@
# 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`文件,以免被强制覆盖。

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

View File

@ -1,16 +0,0 @@
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,
}
}

View File

@ -1,10 +0,0 @@
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 }
}

View File

@ -0,0 +1,38 @@
// 可以将此代码放置于项目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 }
}

View File

@ -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,9 +25,14 @@ onMounted(() => {
})
function toComplaint() {
uni.navigateTo({
url: '/pages/complaint',
})
// 使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
}
</script>
@ -40,13 +45,18 @@ export default {
</script>
<template>
<slot />
<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>
<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">
投诉
@ -59,4 +69,6 @@ export default {
:deep(.qnc-tabbar) {
bottom: 16px !important;
}
</style>

View File

@ -2,10 +2,15 @@ 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
}
}

View File

@ -16,7 +16,8 @@
"delay": 0
},
"modules": {
"Payment": {}
"Payment": {},
"Share": {}
},
"distribute": {
"android": {
@ -111,5 +112,23 @@
"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
}
}
}
}
}
}

View File

@ -3,30 +3,56 @@
{
"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/authorization",
"path": "pages/invitation",
"type": "page",
"layout": "page",
"title": "授权书"
"title": "邀请下级",
"auth": true,
"agent": true
},
{
"path": "pages/complaint",
"path": "pages/invitationAgentApply",
"type": "page",
"layout": "page",
"title": "投诉服务"
},
{
"path": "pages/inquire",
"type": "page",
"layout": "page",
"title": "报告查询"
"title": "代理申请",
"auth": true
},
{
"path": "pages/login",
@ -40,22 +66,55 @@
"layout": "home"
},
{
"path": "pages/privacyPolicy",
"path": "pages/promote",
"type": "page",
"layout": "page",
"title": "隐私政策"
"title": "推广",
"agent": true,
"auth": true
},
{
"path": "pages/service",
"path": "pages/promoteDetails",
"type": "page",
"layout": "page",
"title": "客户服务"
"title": "直推报告",
"agent": true,
"auth": true
},
{
"path": "pages/userAgreement",
"path": "pages/queryHistory",
"type": "page",
"layout": "page",
"title": "用户协议"
"title": "历史报告",
"auth": true
},
{
"path": "pages/rewardsDetails",
"type": "page",
"layout": "page",
"title": "收益明细",
"agent": true,
"auth": true
},
{
"path": "pages/vip",
"type": "page"
},
{
"path": "pages/withdraw",
"type": "page",
"layout": "page",
"title": "提现",
"auth": true,
"agent": true
},
{
"path": "pages/withdrawDetails",
"type": "page",
"layout": "page",
"title": "提现记录",
"auth": true,
"agent": true
}
],
"globalStyle": {
@ -79,6 +138,11 @@
"text": "",
"visible": false
},
{
"pagePath": "pages/agent",
"text": "",
"visible": false
},
{
"pagePath": "pages/ai",
"text": "",

249
src/pages/agent.vue Normal file
View File

@ -0,0 +1,249 @@
<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>

63
src/pages/agentVip.vue Normal file
View File

@ -0,0 +1,63 @@
<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>

View File

@ -0,0 +1,504 @@
<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>

63
src/pages/agreement.vue Normal file
View File

@ -0,0 +1,63 @@
<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>

View File

@ -1,16 +1,254 @@
<script setup>
import WebviewPage from '@/components/WebviewPage.vue'
const webviewSrc = '/ai' //
const navigationBarTitleText = 'AI律师' //
</script>
<template>
<WebviewPage :webview-src="webviewSrc" :navigation-bar-title-text="navigationBarTitleText" />
<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>
<!-- 聊天窗口 -->
<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>
</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>
</view>
</template>
<route lang="json">
{
"layout": "home"
<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] = ""
}
}
</route>
}
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(() => {
// UniAppUniApp
})
</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>
<route lang="json">{
"layout": "home"
}</route>

View File

@ -1,54 +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', //
})
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>

View File

@ -1,22 +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', //
})
</script>
<template>
<view>
<web-view :webview-styles="webviewStyles" src="https://app.quannengcha.com/complaint" />
</view>
</template>
<route lang="json">
{
"layout": "page",
"title": "投诉服务"
}
</route>

View File

@ -1,66 +1,166 @@
<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) {
uni.navigateTo({
url: `/pages/inquire?feature=${name}`,
})
// 使URL
console.log('使用服务:', name);
// App 使 UTS App 使
try {
// URL
urlLaunch(`https://www.quannengcha.com/inquire/${name}`)
} catch (error) {
console.error('打开URL失败:', error);
}
}
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-tl-[35px] rounded-bl-[35px] rounded-tr-lg rounded-br-lg' },
{ title: '贷前背调', name: 'preloanbackgroundcheck', subtitle: '放心借贷', bg: '/static/image/index_icon_7.png', bgColor: ' bg-red-400 ', position: 'rounded-tr-[35px] rounded-br-[35px] rounded-tl-lg rounded-bl-lg' },
])
// 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 min-h-screen from-blue-100 to-white bg-gradient-to-b">
<view class="box-border">
<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"
/>
<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-8">
<!-- <view class="mb-1 flex items-center">
<view class="flex-shrink-0 pl-2 font-bold">
在线信息
<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>
<wd-notice-bar
:text="noticeText" direction="vertical" :delay="5" color="#4c4c4c"
background-color="#00000000"
/>
</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>
</view>
<view class="relative p-4 pb-4 pt-2">
<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>
@ -68,15 +168,9 @@ function toHistory() {
</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">
我的历史查询记录
@ -85,10 +179,9 @@ function toHistory() {
查询记录有效期为30天
</view>
</view>
</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>
@ -105,8 +198,10 @@ function toHistory() {
}
</style>
<route type="home" lang="json">
{
"layout": "home"
}
</route>
<route type="home" lang="json">{
"layout": "home",
"style": {
"navigationBarTextStyle": "white",
"transparentTitle": "always"
}
}</route>

View File

@ -1,294 +0,0 @@
<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>

51
src/pages/invitation.vue Normal file
View File

@ -0,0 +1,51 @@
<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>

View File

@ -0,0 +1,199 @@
<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
// isSelffalse3
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>

View File

@ -1,6 +1,6 @@
<script setup>
import { getCode, login } from '@/api/apis'
import { getCode, login, getUserInfo } from '@/api/apis'
import { getAgentInfo } from '@/apis/agent'
const phoneNumber = ref('')
const verificationCode = ref('')
const password = ref('')
@ -42,6 +42,7 @@ function sendVerificationCode() {
}).then((res) => {
if (res.code === 200) {
uni.showToast({ title: '获取成功', icon: 'none' })
startCountdown()
}
})
@ -76,6 +77,8 @@ function handleLogin() {
uni.setStorageSync('refreshAfter', res.data.refreshAfter)
uni.setStorageSync('accessExpire', res.data.accessExpire)
uni.showToast({ title: '登录成功', icon: 'none' })
getUser()
getAgentInformation()
uni.reLaunch({
url: '/pages/index',
})
@ -88,14 +91,50 @@ function handleLogin() {
function toUserAgreement() {
uni.navigateTo({
url: '/pages/userAgreement',
url: '/pages/agreement?type=user',
})
}
function toPrivacyPolicy() {
uni.navigateTo({
url: '/pages/privacyPolicy',
url: '/pages/agreement?type=privacy',
})
}
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)
@ -107,47 +146,32 @@ 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" />
@ -165,17 +189,15 @@ 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;
@ -195,9 +217,7 @@ onUnmounted(() => {
}
</style>
<route lang="json">
{
<route lang="json">{
"layout": "login",
"title": "登录"
}
</route>
}</route>

View File

@ -1,120 +1,246 @@
<script setup>
import { getUserInfo } from '@/api/apis'
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: 'service', action: () => toService() },
{ title: '用户协议', icon: 'file', action: () => toUserAgreement() },
{ title: '退出登录', icon: 'logout', action: () => handleLogout() },
])
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 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>
<!-- 代理标识 -->
<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>
</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>
<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"
/>
<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>
</view>
</view>
</view>
</template>
<style lang="scss" scoped>
.profile-section {
@apply flex items-center gap-4 p-4 bg-white rounded-md shadow-md mb-4;
<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代理'
}
.features-section {
@apply flex flex-col gap-2;
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>
.profile-section {
background: linear-gradient(135deg, #ffffff 50%, rgba(236, 253, 245, 0.3));
border: 1px solid rgba(209, 213, 219, 0.2);
}
.profile-section .relative>view:first-child {
transition: all 0.3s ease;
}
.feature-item {
@apply bg-white p-3 rounded-md shadow-sm;
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);
}
</style>
<route lang="json">
{
"layout": "home"
}
</route>
<route lang="json">{
"layout": "home"
}</route>

View File

@ -1,22 +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', //
})
</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>

245
src/pages/promote.vue Normal file
View File

@ -0,0 +1,245 @@
<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>

View File

@ -0,0 +1,144 @@
<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>

153
src/pages/queryHistory.vue Normal file
View File

@ -0,0 +1,153 @@
<script setup>
import { onLoad, onReachBottom } from '@dcloudio/uni-app'
import { queryList } from '@/api/apis'
// id product_name
const productMap = {
1: '背景调查',
2: '企业报告',
3: '家政服务',
4: '婚姻状态',
5: '贷前背景调查',
6: '租赁服务',
7: '个人风险评估',
}
const page = ref(1)
const pageSize = ref(10)
const total = ref(0)
const reportList = ref([])
const loadingState = ref('loading')
const num = ref(0)
const max = ref(60)
//
function fetchData() {
queryList({ page: page.value, page_size: pageSize.value }).then((res) => {
if (res.code === 200) {
total.value = res.data.total
if (res.data.list && res.data.list.length > 0) {
reportList.value.push(...res.data.list)
page.value += 1
}
if (reportList.value.length >= total.value) {
loadingState.value = 'finished'
}
else {
loadingState.value = 'loading'
}
}
})
}
// product_id
function getProductName(productId) {
return productMap[productId] || '未知类型'
}
//
onLoad(() => {
fetchData()
})
//
onReachBottom(() => {
if (loadingState.value !== 'finished') {
if (num.value >= max.value) {
loadingState.value = 'finished'
}
else {
fetchData()
}
}
})
function toDetail(item) {
if (item.query_state !== 'success')
return
uni.navigateTo({
url: `/pages/result?id=${item.order_id}`,
})
}
//
function stateText(state) {
switch (state) {
case 'pending':
return '查询中'
case 'success':
return '查询成功'
case 'failed':
return '查询失败'
default:
return '未知状态'
}
}
//
function statusClass(state) {
switch (state) {
case 'pending':
return 'status-pending'
case 'success':
return 'status-success'
case 'failed':
return 'status-failed'
default:
return ''
}
}
</script>
<template>
<!-- <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">
<view class="">
状态:
</view>
<view class="rounded-xl px-2 py-1" :class="[statusClass(item.query_state)]">
{{ stateText(item.query_state) }}
</view>
</view>
<view class="flex items-center justify-between">
<view class="">
报告类型
</view>
<view>
{{ item.product_name }}
</view>
</view>
<view class="flex items-center justify-between">
<view class="">
查询时间:
</view>
<view>
{{ item.create_time }}
</view>
</view>
</view>
<!-- 加载更多 -->
<wd-loadmore :state="loadingState" @reload="fetchData" />
</view>
</template>
<style lang="scss" scoped>
.status-pending {
@apply bg-yellow-100 text-yellow-600;
}
.status-success {
@apply bg-green-100 text-green-600;
}
.status-failed {
@apply bg-red-100 text-red-600;
}
</style>
<route lang="json">{
"layout": "page",
"title": "历史报告",
"auth": true
}</route>

View File

@ -0,0 +1,165 @@
<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>

View File

@ -1,22 +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', //
})
</script>
<template>
<view>
<web-view :webview-styles="webviewStyles" src="https://app.quannengcha.com/service" />
</view>
</template>
<route lang="json">
{
"layout": "page",
"title": "客户服务"
}
</route>

View File

@ -1,22 +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', //
})
</script>
<template>
<view>
<web-view :webview-styles="webviewStyles" src="https://app.quannengcha.com/userAgreement" />
</view>
</template>
<route lang="json">
{
"layout": "page",
"title": "用户协议"
}
</route>

26
src/pages/vip.vue Normal file
View File

@ -0,0 +1,26 @@
<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>

427
src/pages/withdraw.vue Normal file
View File

@ -0,0 +1,427 @@
<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-uitoast
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 = () => {
// 使safeTruncate2
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}`)
}
// value2
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>

View File

@ -0,0 +1,181 @@
<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>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

View File

@ -0,0 +1,75 @@
<svg xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 1024 1024" height="1024px" width="1024px">
<title>空空如也</title>
<defs>
<rect rx="22.1405405" height="1024" width="1024" y="0" x="0" id="path-1"></rect>
<linearGradient id="linearGradient-3" y2="64.8840762%" x2="50%" y1="-33.7184979%" x1="115.913479%">
<stop offset="0%" stop-color="#6CADFF"></stop>
<stop offset="100%" stop-opacity="0" stop-color="#FFFFFF"></stop>
</linearGradient>
<linearGradient id="linearGradient-4" y2="100%" x2="70.4980572%" y1="-20.569195%" x1="10.5031837%">
<stop offset="0%" stop-color="#6CADFF"></stop>
<stop offset="100%" stop-opacity="0" stop-color="#FFFFFF"></stop>
</linearGradient>
<linearGradient id="linearGradient-5" y2="104.73608%" x2="38.801584%" y1="-97.78046%" x1="100.191761%">
<stop offset="0%" stop-color="#6CADFF"></stop>
<stop offset="100%" stop-color="#FFFFFF"></stop>
</linearGradient>
<linearGradient id="linearGradient-6" y2="100%" x2="50%" y1="-27.9013949%" x1="50%">
<stop offset="0%" stop-color="#6CADFF"></stop>
<stop offset="100%" stop-opacity="0" stop-color="#FFFFFF"></stop>
</linearGradient>
<linearGradient id="linearGradient-7" y2="100%" x2="50%" y1="-27.9013949%" x1="50%">
<stop offset="0%" stop-color="#6CADFF"></stop>
<stop offset="100%" stop-opacity="0" stop-color="#FFFFFF"></stop>
</linearGradient>
<linearGradient id="linearGradient-8" y2="100%" x2="50%" y1="-221.1569%" x1="50%">
<stop offset="0%" stop-color="#D2D2D2"></stop>
<stop offset="100%" stop-opacity="0" stop-color="#D2D2D2"></stop>
</linearGradient>
<linearGradient id="linearGradient-9" y2="53.7335012%" x2="73.0360423%" y1="48.1527472%" x1="67.5652976%">
<stop offset="0%" stop-opacity="0" stop-color="#858585"></stop>
<stop offset="100%" stop-opacity="0.5" stop-color="#616161"></stop>
</linearGradient>
</defs>
<g fill-rule="evenodd" fill="none" stroke-width="1" stroke="none" id="空空如也">
<g>
<mask fill="white" id="mask-2">
<use xlink:href="#path-1"></use>
</mask>
<g id="蒙版"></g>
<g mask="url(#mask-2)" id="编组-3">
<g transform="translate(0, 238.0108)">
<g fill-rule="evenodd" fill="none" stroke-width="1" stroke="none" id="编组-2">
<g fill-rule="nonzero" transform="translate(162.5599, 0)" id="编组">
<polygon points="592.450826 498.100707 589.3555 489.432325 587.255101 479.632083 586.398359 469.500567 586.868185 459.341443 588.001295 452.660716 589.852963 446.421689 592.367915 440.541544 595.711972 435.158313 599.857498 430.520452 604.887401 426.517537 606.932527 428.091097 608.342006 430.133964 609.060564 432.508107 609.032927 435.075494 608.286732 439.989418 607.070711 451.308006 606.794343 463.813666 607.540538 469.25211 608.894743 472.371623 610.248947 473.448269 612.072979 473.393057 614.864299 471.791891 619.037461 467.319668 626.084854 456.884481 638.963619 434.136879 651.870021 411.527309 659.000324 400.705634 667.015006 390.325661 673.758394 383.451689 680.225413 378.42734 686.471338 374.921338 693.159452 372.491982 699.156645 371.470549 704.628738 371.691399 709.8521 373.126928 714.191083 375.639102 717.783871 379.283135 720.32646 383.755358 721.818849 389.331833 722.150491 396.343837 721.155565 403.328234 718.530066 411.610128 713.942351 421.493188 708.884811 429.471413 700.400302 443.19175 696.006046 451.031943 692.219799 458.706498 689.345568 466.270628 688.212458 472.09556 688.46119 475.601562 689.760121 477.920492 692.109252 479.438839 695.232214 479.714902 698.299903 479.052351 705.070927 476.540176 711.924862 473.393057 718.778797 470.383969 725.384001 468.258282 729.805894 467.595731 734.144877 467.8994 738.511497 469.224503 741.966102 471.377796 744.702148 474.055608 746.857821 477.368366 748.985858 483.000054 750.008421 489.349506 750.036057 495.864596 749.206952 502.158835 746.526179 511.40695 742.104286 520.737884 736.21764 529.406266 728.866242 537.16364 723.283601 541.608256 717.203498 545.25229 710.570657 548.123346 703.606175 550.000575 696.199503 550.745946 688.212458 550.359458 675.554788 548.09574 661.238907 544.396494 646.923027 539.537783 632.855878 533.464394 623.76336 528.688502 615.582857 523.526121 608.203822 517.977252 601.543344 511.683013 596.375256 505.140317 592.533736 498.349164" fill="url(#linearGradient-3)" id="路径"></polygon>
<polygon points="39.9075893 440.458725 31.7823599 436.096928 23.6571305 430.216783 16.222822 423.287598 9.75580266 415.447406 4.58771456 406.834236 1.21602073 397.834578 0.0552736694 391.623157 0 385.411737 1.05019972 379.117498 3.59278851 378.896647 5.99719313 379.421167 8.12522941 380.635845 9.83871316 382.54068 12.6023966 386.654021 19.2905106 395.87453 27.4986505 405.315889 31.6994494 408.849497 34.7947749 410.257419 36.5082587 410.146993 37.8348267 408.877103 38.8297528 405.840409 38.9403001 399.711807 37.1439059 387.26136 31.3401706 361.863552 25.7022563 336.465744 23.7676779 323.601202 22.8003886 310.488203 23.242578 300.881206 24.6520566 292.820163 26.9459139 286.056616 30.2899709 279.789983 34.0762172 275.014091 38.2770161 271.508089 43.1134622 269.078734 48.0051819 268.0573 53.1179963 268.333363 57.9820792 269.934529 62.8185253 273.081649 67.7655187 278.050785 71.6899493 283.903324 75.3103746 291.798729 78.5162474 302.206309 80.1191838 311.509637 83.0210515 327.383267 85.0385404 336.134468 87.4153082 344.361149 90.3448127 351.870067 93.4125013 356.977234 95.9550901 359.378984 98.4700421 360.234779 101.206089 359.765472 103.748678 357.888243 105.572709 355.320856 108.916766 348.916191 111.873907 342.014613 114.913959 335.195853 118.368563 329.23289 121.215157 325.782101 124.642125 323.159501 128.78765 321.254665 132.794991 320.509295 136.636511 320.674933 140.450394 321.696366 145.81194 324.429391 150.841844 328.459913 155.236101 333.291018 158.856526 338.508611 162.670409 345.575827 166.788298 354.823942 170.381086 364.762215 173.448775 375.639102 175.604448 386.764446 176.5441 397.641334 176.378279 404.874188 175.41099 411.499703 173.697506 417.628304 171.04437 423.315205 167.396308 428.173916 162.642772 432.314863 157.032495 435.62762 150.344381 438.691921 142.440246 441.424946 130.058944 444.572066 116.2958 446.835784 102.173378 448.160887 87.9956817 448.547375 74.0390802 447.967642 61.3537731 446.504508 49.4422973 443.964727 40.1563208 440.707182" fill="url(#linearGradient-4)" id="路径"></polygon>
<path fill="url(#linearGradient-5)" id="形状结合" d="M648.498327,284.510663 L644.71208,289.9215 L641.589118,295.939676 L639.350534,302.344341 L638.217424,308.914643 L638.355608,315.567765 L640.013818,322.165674 L642.224765,326.058164 L644.988449,328.92922 L647.94559,331.579426 L650.571089,334.505696 L652.284573,338.039304 L652.83731,343.588173 L651.648926,349.689168 L649.576163,355.458887 L646.619022,360.952544 L640.428371,370.780391 L633.408615,379.945687 L625.615028,388.53125 L630.092195,393.086292 L633.159883,398.524736 L634.735183,404.570518 L634.707546,410.947577 L633.215157,417.186603 L630.755479,423.066748 L627.411422,428.477585 L623.210623,433.336296 L620.115297,436.234959 L616.384325,438.25022 L612.459894,438.691921 L608.535464,438.25022 L595.960704,435.517195 L583.77286,431.624705 L571.944295,426.57275 L566.555112,423.729299 L561.608118,420.250904 L557.545504,416.027138 L554.864731,410.91997 L554.035626,406.723811 L554.25672,403.769935 L555.251646,401.699462 L557.877146,399.049256 L561.41466,396.895963 L562.685955,396.178199 L566.30638,393.886875 L569.180611,390.822574 L571.253374,386.129501 L572.524668,380.939514 L574.127604,370.55954 L575.150167,359.075314 L575.896362,352.781075 L577.444025,347.121781 L579.212782,343.864236 L581.783008,341.352061 L585.292886,339.557651 L592.533736,338.260154 L599.74695,336.935051 L604.389938,334.754152 L608.176185,331.827883 L611.243873,328.128637 L614.974846,321.696366 L618.180719,314.518725 L618.899277,312.751921 L622.630249,304.663271 L624.785922,300.908813 L627.273238,297.568449 L630.313289,294.86303 L634.292994,292.461281 L642.611681,288.430759 L646.28738,286.387892 L648.498327,284.510663 Z M619.009824,341.73855 L615.195941,346.514442 L606.158696,359.323771 L600.935334,367.854122 L595.463241,378.013245 L590.626795,388.807313 L586.702364,400.346752 L584.795423,408.269764 L583.717586,416.192776 L583.468855,424.115788 L595.325057,424.115788 L596.319983,416.109957 L599.912771,395.929742 L602.925186,383.313657 L607.153622,369.234437 L612.432257,355.238037 L619.009824,341.73855 Z"></path>
<polygon points="125.250135 60.7614951 125.250135 60.7614951 124.559214 54.3016178 122.431178 48.4214731 119.059484 43.2314863 114.55468 38.9249014 109.165497 35.7777818 102.947209 33.9005525 96.4525532 33.5416704 90.3171759 34.7011355 84.6239879 37.21331 79.6769945 40.9677686 75.6972903 45.7712671 72.8783332 51.6238055 66.8258663 52.3415696 61.3537731 54.5500746 56.6278743 58.111289 52.9245385 62.9147875 50.658318 68.5464754 49.9673972 74.3990138 50.8517759 80.2515521 53.3114542 85.8004211 57.1529742 90.4934943 61.9894203 93.8890708 67.5444241 95.931938 73.569254 96.4564579 123.011551 96.4564579 127.626903 95.7663001 131.634244 94.1375276 135.171759 91.5149279 137.963079 88.1193514 139.78711 84.1992549 140.699126 79.6442132 140.367484 74.9787463 139.013279 70.8654057 136.664148 67.1661597 133.513549 64.1294653 129.727302 62.0037792" fill="url(#linearGradient-6)" id="路径"></polygon>
<polygon points="329.569254 33.7073083 329.569254 33.5416704 329.127065 28.130833 327.911044 23.0788777 325.921192 18.3305919 321.665119 11.9259273 316.054842 6.65312145 311.715859 3.89249014 306.934686 1.84962298 301.656051 0.496913635 296.266868 0 291.071143 0.35888207 286.041239 1.49074091 278.993846 4.61025428 272.858469 9.22050857 269.376228 13.0301798 266.557271 17.3643709 264.318687 22.305901 259.205873 22.8856335 254.507611 24.2383429 250.196265 26.364029 246.299471 29.2074792 243.010688 32.6030557 240.302278 36.5783648 238.284789 40.9677686 237.096405 45.6608418 236.681853 50.7956161 237.234589 55.902784 238.588794 60.5682509 240.744467 64.8748357 243.591061 68.7673259 246.990392 72.0524771 250.970096 74.7855021 255.364353 76.7731567 260.062615 77.9878345 265.203066 78.3743228 326.612113 78.3743228 332.360574 77.6565587 337.501026 75.5860852 341.950556 72.3285403 345.488071 68.1047744 347.892475 63.1080317 348.997949 57.4211312 348.611033 51.6514118 346.842276 46.378606 343.885134 41.7683517 339.877793 37.9862868 335.041347 35.2808681 329.403433 33.8453398" fill="url(#linearGradient-7)" id="路径"></polygon>
</g>
<polygon points="1024 550.359458 999.596675 534.403009 973.839145 519.164324 946.672136 504.615797 918.040376 490.785034 889.159883 478.224161 859.118644 466.491478 827.833747 455.669804 795.305193 445.703925 762.693728 437.007936 729.114974 429.360987 694.541293 422.735472 658.917413 417.186603 623.348807 412.880018 587.034006 409.760505 549.945374 407.883276 512 407.193118 474.054626 407.883276 436.965994 409.760505 400.623556 412.880018 365.082587 417.186603 329.458707 422.735472 294.885026 429.360987 261.306272 437.007936 228.694807 445.703925 196.166253 455.669804 164.881356 466.491478 134.840117 478.224161 105.931987 490.785034 77.3278635 504.615797 50.160855 519.164324 24.4033251 534.403009 0 550.359458" fill-rule="nonzero" fill="url(#linearGradient-8)" id="路径"></polygon>
</g>
<polygon points="168.585366 389.215532 314.612039 389.215532 461.536985 469.266954 317.214646 465.594981" fill-rule="nonzero" fill="url(#linearGradient-9)" stroke="none" id="矩形"></polygon>
<polygon points="481.155803 208.25638 479.722777 299.451613 688.569371 236.303345" fill-rule="nonzero" fill="#B8D6FF" stroke="none" id="路径"></polygon>
<polygon points="314.788219 244.959395 481.155803 208.631248 481.155803 264.00952" fill-rule="nonzero" fill="#9CC6FF" stroke="none" id="路径"></polygon>
<polygon points="314.788219 244.959395 511.147006 264.384388 511.147006 512.547202 314.788219 465.075243" fill-rule="nonzero" fill="#64ADFF" stroke="none" id="路径"></polygon>
<polygon points="314.788219 244.959395 511.283486 263.617612 489.889892 383.428742 314.788219 346.994453" fill-rule="nonzero" fill="#429BFF" stroke="none" id="矩形"></polygon>
<polygon points="511.147006 264.384388 688.569371 236.303345 688.569371 458.600245 511.147006 512.547202" opacity="0.99" fill-rule="nonzero" fill="#9CC5FF" stroke="none" id="路径"></polygon>
<polygon points="511.283486 264.997809 671.897967 239.34913 688.569371 344.292902 535.025228 383.428742" fill-rule="nonzero" fill="#64ADFF" stroke="none" id="矩形"></polygon>
<polygon points="314.788219 244.959395 267.566573 324.806343 465.801946 362.565804 511.147006 264.384388" fill-rule="nonzero" fill="#9CC6FF" stroke="none" id="路径"></polygon>
<polygon points="511.147006 264.384388 566.898574 362.565804 745.583366 317.786082 688.569371 236.303345" opacity="0.99" fill-rule="nonzero" fill="#9DC6FF" stroke="none" id="路径"></polygon>
<path stroke-dasharray="11.05477807439905,8.29108355579929" fill="none" stroke-width="5.52738904" stroke="#9DC6FF" id="路径-19" d="M583.139543,151.843183 C532.695151,184.875351 501.824507,214.257045 511.001904,232.450753 C523.475834,257.179661 544.659409,246.913618 547.874,236.537816 C551.088588,226.162013 542.242035,205.908265 523.475834,216.933951 C504.709635,227.959637 484.261479,247.732311 479.722777,267.098145"></path>
<g transform="translate(555.0939, 41.4059)" fill-rule="evenodd" fill="none" stroke-width="1" stroke="none" id="飞机">
<polygon points="163.057977 9.09494702e-13 0 30.854292 41.4554178 58.3378535" fill-rule="nonzero" fill="#9DC6FF" id="路径-16备份"></polygon>
<polygon points="163.057977 0 41.4554178 58.3378535 41.4554178 104.894966" fill-rule="nonzero" fill="#64ADFF" id="路径-16备份-2"></polygon>
<polygon points="163.057977 0 41.4554178 58.3378535 65.4910753 84.1769753" fill-rule="nonzero" fill="#429BFF" id="路径-16备份-2"></polygon>
<polygon points="163.057977 0 58.9237102 70.0692202 108.951745 102.134572" fill-rule="nonzero" fill="#9DC6FF" id="路径-16备份"></polygon>
<line stroke-linecap="round" stroke-width="2.76369452" stroke="#429BFF" id="路径-16" y2="32.1173295" x2="0.501635492" y1="58.3378535" x1="41.4554178"></line>
<line stroke-linecap="round" stroke-width="2.76369452" stroke="#429BFF" id="路径-17" y2="101.744072" x2="107.648858" y1="71.0666294" x1="59.7211085"></line>
<line stroke-linecap="round" stroke-width="2.76369452" stroke="#429BFF" id="路径-18" y2="103.502333" x2="41.4554178" y1="58.3378535" x1="41.4554178"></line>
</g>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1733324501181" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6340" xmlns:xlink="http://www.w3.org/1999/xlink" width="48" height="48"><path d="M339.162366 1023.729653c-95.973119 0-127.972351-435.012601-127.97235-518.254842 0-63.900156 121.557758-115.167743 121.557758-115.167743h127.972351s6.390016 51.193856 31.950078 63.900156C466.962679 479.865595 441.476347 742.224889 460.670971 799.759606a214.974871 214.974871 0 0 0 51.193856 95.973119 227.681171 227.681171 0 0 0 63.900156-95.973119c6.414593-51.193856 0-307.212288-25.58464-345.503228a90.394144 90.394144 0 0 0 25.58464-63.900156h127.97235s115.143166 44.80384 108.753151 115.167743c0 76.778495-44.80384 505.450234-140.776959 518.254842z m511.864827-204.750846c12.780031-51.193856 19.170047-319.918589-19.194624-390.307068s-147.166975-89.558526-147.166974-102.363135c0-6.390016 25.584639-12.780031 44.80384-12.780031h211.140861a84.692284 84.692284 0 0 1 83.193088 83.168511l-25.682947 351.893244c-6.414593 51.193856-44.779263 70.38848-102.387712 70.388479z m-729.395704 0c-57.583871 0-89.583103-19.194624-102.363134-70.388479L0 396.697084a84.692284 84.692284 0 0 1 83.168511-83.168511h204.750846c19.170047 0 44.80384 0 44.80384 12.780031s-108.777727 31.950078-147.166975 102.363135-31.950078 339.162366-19.194624 390.307068z m230.261755-652.617209A169.384567 169.384567 0 0 1 518.254842 0a169.581183 169.581183 0 0 1 0 339.162366 170.785455 170.785455 0 0 1-166.361598-172.800768z m377.50246 12.780032a101.060554 101.060554 0 0 1 102.363134-102.363135 95.850234 95.850234 0 0 1 102.363135 95.973119 101.060554 101.060554 0 0 1-102.363135 102.363135 99.635089 99.635089 0 0 1-102.363134-95.973119z m-639.812601 0A101.060554 101.060554 0 0 1 191.946238 76.778495a99.659666 99.659666 0 0 1 102.363134 95.973119 101.060554 101.060554 0 0 1-102.363134 102.363135 95.850234 95.850234 0 0 1-102.363135-95.973119z" fill="#4B64FA" p-id="6341"></path></svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1733326573199" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="9341" xmlns:xlink="http://www.w3.org/1999/xlink" width="48" height="48"><path d="M390.063158 950.649263a104.286316 104.286316 0 0 0-10.644211 50.149053H26.947368v-150.042948c0-220.779789 177.259789-400.410947 395.290948-400.410947 68.985263 0 133.820632 18.081684 190.383158 49.744842l-222.558316 450.56z m32.175158-550.346105c-109.029053 0-197.658947-89.869474-197.658948-200.218947C224.579368 89.788632 313.236211 0 422.265263 0s197.632 89.734737 197.632 200.218947c0 110.322526-88.656842 200.084211-197.632 200.084211z m571.930947 583.895579c8.973474 18.270316-4.149895 39.801263-24.306526 39.801263H480.741053c-20.156632 0-33.306947-21.530947-24.306527-39.801263l244.601263-495.400421a27.028211 27.028211 0 0 1 48.613053 0l244.493474 495.400421z m-296.016842-42.738526h54.298947v-55.080422h-54.298947v55.080422z m0-110.133895h54.298947v-137.620211h-54.298947v137.620211z" fill="#4B64FA" p-id="9342"></path></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1733326791000" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="28866" xmlns:xlink="http://www.w3.org/1999/xlink" width="48" height="48"><path d="M425.3 245.5c80.1 0 126.4 50.8 126.4 147.4 0 55.2-19 102.2-47.9 132.4-9.1 15.2-13.9 37.5-13.9 47.4 0 5.9 4.6 13.7 13 21.9-20.1 9.4-32.7 29-32.5 50.5v22.8c0 24.7 16 45.4 38.5 52.9-8.7 19.1-6.1 41.1 6.7 57.9h-339c-12.7 0-23-10.1-23-24 0-30.9 4.6-51.4 13.7-61.4 22.5-24.7 70.7-46.4 118.3-62.9 47.6-16.4 74.5-42.8 74.5-57.6 0-10.2-5-33.6-14.6-48.8-28.2-30.2-46.6-76.7-46.6-131 0.1-96.8 46.4-147.5 126.4-147.5z m241 266.7l66.9 68.4-9.8 8.6 15.4 16.6-10.3 9 128.3 125.3c6.6 6.3 22.4 21.6 7.1 33.8-15.4 12.2-29.4-4.9-36-11.2l-125.6-124-12.2 10.8-15.4-16.6-8.9 7.6-66.4-68.4 66.9-59.9z m50.8 205.9c7.9 0 14.5 6.3 14.5 14l0.5 3.6c11.7 0 21 9 21 20.2v18h-201v-18c0-11.2 9.3-20.2 21-20.2h1.4v-3.6c0-7.7 6.6-14 14.5-14h128.1zM593.3 578.4l65.5 67.5c6.6 6.7 6.6 18-1 24.3l-10.3 9c-7 6.3-18.7 5.8-25.2-1l-65.5-67.5c-6.6-6.7-6.6-18 1-24.3l10.3-9c7-6.2 18.7-6.2 25.2 1z m116.5-104l65.5 67.5c6.6 6.7 6.6 18-1 24.3l-10.3 9c-7 6.3-18.7 6.3-25.2-0.9l-65.5-67.4c-6.6-6.7-6.6-18 1-24.3l10.3-9c6.9-6.4 18.1-5.9 25.2 0.8z" fill="#4B64FA" p-id="28867"></path></svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

Some files were not shown because too many files have changed in this diff Show More