f
This commit is contained in:
@@ -26,10 +26,10 @@ export default defineUniPages({
|
|||||||
selectedIconPath: 'static/tabbar/home-active.png',
|
selectedIconPath: 'static/tabbar/home-active.png',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pagePath: 'pages/report',
|
pagePath: 'pages/toolbox/index',
|
||||||
text: '报告',
|
text: '工具',
|
||||||
iconPath: 'static/tabbar/report.png',
|
iconPath: 'static/tabbar/toolbox.png',
|
||||||
selectedIconPath: 'static/tabbar/report-active.png',
|
selectedIconPath: 'static/tabbar/toolbox-active.png',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pagePath: 'pages/mine',
|
pagePath: 'pages/mine',
|
||||||
|
|||||||
@@ -1087,6 +1087,63 @@ export const toolboxItems = [
|
|||||||
index: '热度',
|
index: '热度',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
key: 'star',
|
||||||
|
name: '星座运势',
|
||||||
|
desc: '查询十二星座今日运势(娱乐)',
|
||||||
|
icon: 'i-carbon-star',
|
||||||
|
fields: [
|
||||||
|
{ key: 'astro', label: '星座', type: 'select', mode: 'selector', options: [
|
||||||
|
{ label: '白羊座', value: '白羊座' },
|
||||||
|
{ label: '金牛座', value: '金牛座' },
|
||||||
|
{ label: '双子座', value: '双子座' },
|
||||||
|
{ label: '巨蟹座', value: '巨蟹座' },
|
||||||
|
{ label: '狮子座', value: '狮子座' },
|
||||||
|
{ label: '处女座', value: '处女座' },
|
||||||
|
{ label: '天秤座', value: '天秤座' },
|
||||||
|
{ label: '天蝎座', value: '天蝎座' },
|
||||||
|
{ label: '射手座', value: '射手座' },
|
||||||
|
{ label: '摩羯座', value: '摩羯座' },
|
||||||
|
{ label: '水瓶座', value: '水瓶座' },
|
||||||
|
{ label: '双鱼座', value: '双鱼座' },
|
||||||
|
], placeholder: '请选择星座' },
|
||||||
|
],
|
||||||
|
validate: (form) => (form.astro || '').length > 0,
|
||||||
|
validateMsg: '请选择星座',
|
||||||
|
resultType: 'list',
|
||||||
|
resultLabels: {
|
||||||
|
type: '运势类型',
|
||||||
|
content: '运势内容',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'tianqishiju',
|
||||||
|
name: '天气诗句',
|
||||||
|
desc: '根据天气类型随机返回经典诗句',
|
||||||
|
icon: 'i-carbon-cloud',
|
||||||
|
fields: [
|
||||||
|
{ key: 'tqtype', label: '天气类型', type: 'select', mode: 'selector', options: [
|
||||||
|
{ label: '风', value: 1 },
|
||||||
|
{ label: '云', value: 2 },
|
||||||
|
{ label: '雨', value: 3 },
|
||||||
|
{ label: '雪', value: 4 },
|
||||||
|
{ label: '霜', value: 5 },
|
||||||
|
{ label: '露', value: 6 },
|
||||||
|
{ label: '雾', value: 7 },
|
||||||
|
{ label: '雷', value: 8 },
|
||||||
|
{ label: '晴', value: 9 },
|
||||||
|
{ label: '阴', value: 10 },
|
||||||
|
], placeholder: '可选,选择天气类型' },
|
||||||
|
],
|
||||||
|
validate: () => true,
|
||||||
|
validateMsg: '',
|
||||||
|
resultLabels: {
|
||||||
|
content: '诗句',
|
||||||
|
author: '作者',
|
||||||
|
source: '出处',
|
||||||
|
weather: '天气',
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
key: 'verse',
|
key: 'verse',
|
||||||
name: '诗词名句',
|
name: '诗词名句',
|
||||||
@@ -1457,7 +1514,9 @@ export const toolboxItems = [
|
|||||||
resultLabels: {
|
resultLabels: {
|
||||||
name: '名称',
|
name: '名称',
|
||||||
type_name: '分类',
|
type_name: '分类',
|
||||||
explain: '说明',
|
explain: '分类说明',
|
||||||
|
contain: '包含类型',
|
||||||
|
tip: '投放提示',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -2214,17 +2273,19 @@ export const toolboxItems = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'anslajifenlei',
|
key: 'anslajifenlei',
|
||||||
name: '按师垃圾分类',
|
name: '垃圾分类问答',
|
||||||
desc: '按垃圾分类指南',
|
desc: '随机出现一个物品,选出它属于哪种垃圾分类,考考你的环保知识',
|
||||||
icon: 'i-carbon-recycle',
|
icon: 'i-carbon-recycle',
|
||||||
autoQuery: true,
|
autoQuery: true,
|
||||||
|
isGame: true,
|
||||||
fields: [],
|
fields: [],
|
||||||
validate: () => true,
|
validate: () => true,
|
||||||
validateMsg: '',
|
validateMsg: '',
|
||||||
resultType: 'list',
|
|
||||||
resultLabels: {
|
resultLabels: {
|
||||||
name: '名称',
|
name: { label: '物品名称' },
|
||||||
type_name: '分类',
|
type: { label: '正确分类', hidden: true },
|
||||||
|
type_name: { label: '分类名称', hidden: true },
|
||||||
|
explain: { label: '分类说明', hidden: true },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -2268,6 +2329,7 @@ export const toolboxItems = [
|
|||||||
content: '问候语',
|
content: '问候语',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
key: 'story',
|
key: 'story',
|
||||||
name: '故事大全',
|
name: '故事大全',
|
||||||
|
|||||||
@@ -74,6 +74,16 @@
|
|||||||
"navigationBarTextStyle": "black"
|
"navigationBarTextStyle": "black"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/inquire/list",
|
||||||
|
"type": "page",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "车辆查询服务",
|
||||||
|
"navigationStyle": "default",
|
||||||
|
"navigationBarBackgroundColor": "#ffffff",
|
||||||
|
"navigationBarTextStyle": "black"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"path": "pages/legal/authorization",
|
"path": "pages/legal/authorization",
|
||||||
"type": "page",
|
"type": "page",
|
||||||
@@ -128,7 +138,7 @@
|
|||||||
"path": "pages/toolbox/index",
|
"path": "pages/toolbox/index",
|
||||||
"type": "page",
|
"type": "page",
|
||||||
"style": {
|
"style": {
|
||||||
"navigationBarTitleText": "实用工具",
|
"navigationBarTitleText": "工具分类",
|
||||||
"navigationStyle": "default",
|
"navigationStyle": "default",
|
||||||
"navigationBarBackgroundColor": "#ffffff",
|
"navigationBarBackgroundColor": "#ffffff",
|
||||||
"navigationBarTextStyle": "black"
|
"navigationBarTextStyle": "black"
|
||||||
@@ -161,10 +171,10 @@
|
|||||||
"selectedIconPath": "static/tabbar/home-active.png"
|
"selectedIconPath": "static/tabbar/home-active.png"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"pagePath": "pages/report",
|
"pagePath": "pages/toolbox/index",
|
||||||
"text": "报告",
|
"text": "工具",
|
||||||
"iconPath": "static/tabbar/report.png",
|
"iconPath": "static/tabbar/toolbox.png",
|
||||||
"selectedIconPath": "static/tabbar/report-active.png"
|
"selectedIconPath": "static/tabbar/toolbox-active.png"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"pagePath": "pages/mine",
|
"pagePath": "pages/mine",
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,4 @@
|
|||||||
<script setup lang="ts">
|
<script setup>
|
||||||
import { onLoad } from '@dcloudio/uni-app'
|
import { onLoad } from '@dcloudio/uni-app'
|
||||||
import { computed, onUnmounted, ref } from 'vue'
|
import { computed, onUnmounted, ref } from 'vue'
|
||||||
import { getProductByEn, getUserDetail, postAuthSendSmsQuery, postPayPayment, postQueryService, postUploadImage } from '@/api'
|
import { getProductByEn, getUserDetail, postAuthSendSmsQuery, postPayPayment, postQueryService, postUploadImage } from '@/api'
|
||||||
@@ -21,12 +21,7 @@ const loading = ref(true)
|
|||||||
const productLoadOk = ref(false)
|
const productLoadOk = ref(false)
|
||||||
const submitting = ref(false)
|
const submitting = ref(false)
|
||||||
const paying = ref(false)
|
const paying = ref(false)
|
||||||
const featureData = ref<{
|
const featureData = ref({})
|
||||||
product_name?: string
|
|
||||||
description?: string
|
|
||||||
sell_price?: number
|
|
||||||
product_en?: string
|
|
||||||
}>({})
|
|
||||||
|
|
||||||
const queryId = ref('')
|
const queryId = ref('')
|
||||||
const showPaySheet = ref(false)
|
const showPaySheet = ref(false)
|
||||||
@@ -35,7 +30,7 @@ const vlphotoPreviewPath = ref('')
|
|||||||
const imageUrlUploading = ref(false)
|
const imageUrlUploading = ref(false)
|
||||||
|
|
||||||
const countdown = ref(0)
|
const countdown = ref(0)
|
||||||
let smsTimer: ReturnType<typeof setInterval> | null = null
|
let smsTimer = null
|
||||||
|
|
||||||
const userTypeOptions = [
|
const userTypeOptions = [
|
||||||
{ text: 'ETC开户人', value: '1' },
|
{ text: 'ETC开户人', value: '1' },
|
||||||
@@ -78,7 +73,7 @@ const isIdCardWomanValid = computed(() => /^\d{17}[\dX]$/i.test(formData.idCardW
|
|||||||
const isCreditCodeValid = computed(() => /^.{18}$/.test(formData.entCode || ''))
|
const isCreditCodeValid = computed(() => /^.{18}$/.test(formData.entCode || ''))
|
||||||
|
|
||||||
onLoad((options) => {
|
onLoad((options) => {
|
||||||
feature.value = (options?.feature as string) || ''
|
feature.value = (options?.feature) || ''
|
||||||
void loadProduct()
|
void loadProduct()
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -119,10 +114,7 @@ async function loadProduct() {
|
|||||||
}
|
}
|
||||||
loading.value = true
|
loading.value = true
|
||||||
try {
|
try {
|
||||||
const res = await getProductByEn(feature.value) as {
|
const res = await getProductByEn(feature.value)
|
||||||
code?: number
|
|
||||||
data?: typeof featureData.value
|
|
||||||
}
|
|
||||||
if (res?.code === 200 && res.data) {
|
if (res?.code === 200 && res.data) {
|
||||||
featureData.value = res.data
|
featureData.value = res.data
|
||||||
productLoadOk.value = true
|
productLoadOk.value = true
|
||||||
@@ -145,7 +137,7 @@ async function loadProduct() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function readToken(): string {
|
function readToken() {
|
||||||
try {
|
try {
|
||||||
const t = uni.getStorageSync('token')
|
const t = uni.getStorageSync('token')
|
||||||
return typeof t === 'string' ? t : ''
|
return typeof t === 'string' ? t : ''
|
||||||
@@ -155,17 +147,14 @@ function readToken(): string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function ensureLoginAndMobile(): Promise<boolean> {
|
async function ensureLoginAndMobile() {
|
||||||
if (!readToken()) {
|
if (!readToken()) {
|
||||||
uni.showToast({ title: '请先登录', icon: 'none' })
|
uni.showToast({ title: '请先登录', icon: 'none' })
|
||||||
uni.navigateTo({ url: '/pages/login' })
|
uni.navigateTo({ url: '/pages/login' })
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
const res = await getUserDetail() as {
|
const res = await getUserDetail()
|
||||||
code?: number
|
|
||||||
data?: { userInfo?: { mobile?: string } }
|
|
||||||
}
|
|
||||||
const mobile = (res?.data?.userInfo?.mobile || '').trim()
|
const mobile = (res?.data?.userInfo?.mobile || '').trim()
|
||||||
if (res?.code !== 200 || !/^1[3-9]\d{9}$/.test(mobile)) {
|
if (res?.code !== 200 || !/^1[3-9]\d{9}$/.test(mobile)) {
|
||||||
uni.showModal({
|
uni.showModal({
|
||||||
@@ -188,11 +177,11 @@ async function ensureLoginAndMobile(): Promise<boolean> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function validateField(
|
function validateField(
|
||||||
field: string,
|
field,
|
||||||
value: unknown,
|
value,
|
||||||
ok: (v: unknown) => boolean,
|
ok,
|
||||||
msg: string,
|
msg,
|
||||||
): boolean {
|
) {
|
||||||
if (!isHasInput(field))
|
if (!isHasInput(field))
|
||||||
return true
|
return true
|
||||||
if (!ok(value)) {
|
if (!ok(value)) {
|
||||||
@@ -202,7 +191,7 @@ function validateField(
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
function validateAll(): boolean {
|
function validateAll() {
|
||||||
if (!formData.agreeToTerms) {
|
if (!formData.agreeToTerms) {
|
||||||
uni.showToast({ title: '请阅读并同意用户协议与隐私政策', icon: 'none' })
|
uni.showToast({ title: '请阅读并同意用户协议与隐私政策', icon: 'none' })
|
||||||
return false
|
return false
|
||||||
@@ -240,17 +229,17 @@ function validateAll(): boolean {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
function onUserTypePick(e: { detail: { value: string | number } }) {
|
function onUserTypePick(e) {
|
||||||
const idx = Number(e.detail.value)
|
const idx = Number(e.detail.value)
|
||||||
formData.userType = userTypeOptions[idx]?.value ?? '1'
|
formData.userType = userTypeOptions[idx]?.value ?? '1'
|
||||||
}
|
}
|
||||||
|
|
||||||
function onAuthorizedPick(e: { detail: { value: string | number } }) {
|
function onAuthorizedPick(e) {
|
||||||
const idx = Number(e.detail.value)
|
const idx = Number(e.detail.value)
|
||||||
formData.authorized = authorizedOptions[idx]?.value ?? '1'
|
formData.authorized = authorizedOptions[idx]?.value ?? '1'
|
||||||
}
|
}
|
||||||
|
|
||||||
function onFirstRegChange(e: { detail: { value: string } }) {
|
function onFirstRegChange(e) {
|
||||||
formData.firstRegistrationDate = (e.detail.value || '').slice(0, 7)
|
formData.firstRegistrationDate = (e.detail.value || '').slice(0, 7)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -285,7 +274,7 @@ async function sendSmsCode() {
|
|||||||
if (!(await ensureLoginAndMobile()))
|
if (!(await ensureLoginAndMobile()))
|
||||||
return
|
return
|
||||||
try {
|
try {
|
||||||
const res = await postAuthSendSmsQuery({ mobile: formData.mobile, captchaVerifyParam: '' }) as { code?: number }
|
const res = await postAuthSendSmsQuery({ mobile: formData.mobile, captchaVerifyParam: '' })
|
||||||
if (res?.code === 200) {
|
if (res?.code === 200) {
|
||||||
uni.showToast({ title: '验证码已发送', icon: 'none' })
|
uni.showToast({ title: '验证码已发送', icon: 'none' })
|
||||||
startSmsCountdown()
|
startSmsCountdown()
|
||||||
@@ -296,7 +285,7 @@ async function sendSmsCode() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function chooseImageFile(maxBytes: number): Promise<{ path: string, base64: string }> {
|
function chooseImageFile(maxBytes) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
uni.chooseImage({
|
uni.chooseImage({
|
||||||
count: 1,
|
count: 1,
|
||||||
@@ -338,7 +327,7 @@ async function onPickImageUrl() {
|
|||||||
try {
|
try {
|
||||||
const { base64 } = await chooseImageFile(3 * 1024 * 1024)
|
const { base64 } = await chooseImageFile(3 * 1024 * 1024)
|
||||||
imageUrlUploading.value = true
|
imageUrlUploading.value = true
|
||||||
const up = await postUploadImage(base64) as { code?: number, data?: { url?: string }, msg?: string }
|
const up = await postUploadImage(base64)
|
||||||
if (up?.code === 200 && up.data?.url)
|
if (up?.code === 200 && up.data?.url)
|
||||||
formData.imageUrl = up.data.url
|
formData.imageUrl = up.data.url
|
||||||
else if (up?.msg)
|
else if (up?.msg)
|
||||||
@@ -371,11 +360,7 @@ async function doCreateQuery(captchaVerifyParam = '') {
|
|||||||
const res = await postQueryService(feature.value, {
|
const res = await postQueryService(feature.value, {
|
||||||
data: enc,
|
data: enc,
|
||||||
captchaVerifyParam,
|
captchaVerifyParam,
|
||||||
}) as {
|
})
|
||||||
code?: number
|
|
||||||
data?: { id?: string }
|
|
||||||
msg?: string
|
|
||||||
}
|
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -419,7 +404,7 @@ async function onConfirmPay() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
await new Promise<void>((resolve, reject) => {
|
await new Promise((resolve, reject) => {
|
||||||
uni.showModal({
|
uni.showModal({
|
||||||
title: '重要提示',
|
title: '重要提示',
|
||||||
content: '请确认您了解本服务为大数据报告查询,付款前请仔细阅读产品说明。是否继续支付?',
|
content: '请确认您了解本服务为大数据报告查询,付款前请仔细阅读产品说明。是否继续支付?',
|
||||||
@@ -443,17 +428,7 @@ async function onConfirmPay() {
|
|||||||
id: queryId.value,
|
id: queryId.value,
|
||||||
pay_method: 'wechat',
|
pay_method: 'wechat',
|
||||||
pay_type: 'query',
|
pay_type: 'query',
|
||||||
}) as {
|
})
|
||||||
code?: number
|
|
||||||
data?: {
|
|
||||||
prepay_data?: Record<string, string>
|
|
||||||
prepayData?: Record<string, string>
|
|
||||||
prepay_id?: string
|
|
||||||
prepayId?: string
|
|
||||||
order_no?: string
|
|
||||||
orderNo?: string
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (payRes?.code !== 200 || !payRes.data) {
|
if (payRes?.code !== 200 || !payRes.data) {
|
||||||
return
|
return
|
||||||
@@ -478,7 +453,7 @@ async function onConfirmPay() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
await new Promise<void>((resolve, reject) => {
|
await new Promise((resolve, reject) => {
|
||||||
uni.requestPayment({
|
uni.requestPayment({
|
||||||
provider: 'wxpay',
|
provider: 'wxpay',
|
||||||
timeStamp: String(prepay.timeStamp ?? prepay.timestamp ?? ''),
|
timeStamp: String(prepay.timeStamp ?? prepay.timestamp ?? ''),
|
||||||
@@ -502,7 +477,7 @@ async function onConfirmPay() {
|
|||||||
resolve()
|
resolve()
|
||||||
},
|
},
|
||||||
fail(err) {
|
fail(err) {
|
||||||
const msg = (err as { errMsg?: string })?.errMsg || '支付未完成'
|
const msg = err?.errMsg || '支付未完成'
|
||||||
uni.showToast({ title: msg.replace('requestPayment:fail ', ''), icon: 'none' })
|
uni.showToast({ title: msg.replace('requestPayment:fail ', ''), icon: 'none' })
|
||||||
reject(err)
|
reject(err)
|
||||||
},
|
},
|
||||||
@@ -528,8 +503,15 @@ async function onConfirmPay() {
|
|||||||
</view>
|
</view>
|
||||||
<scroll-view v-else scroll-y class="scroll page-inner">
|
<scroll-view v-else scroll-y class="scroll page-inner">
|
||||||
<view class="card-container">
|
<view class="card-container">
|
||||||
|
<!-- 顶部产品长图 -->
|
||||||
|
<view class="inquire-banner">
|
||||||
|
<image class="inquire-banner-img" src="/static/home/images/VIN.png" mode="widthFix" />
|
||||||
|
<view class="inquire-banner-overlay">
|
||||||
|
<text class="inquire-banner-title">{{ featureData.product_name || '查询服务' }}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
<view class="card-header">
|
<view class="card-header">
|
||||||
{{ featureData.product_name || feature || '查询' }}
|
请输入查询信息
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view class="section-row">
|
<view class="section-row">
|
||||||
@@ -577,7 +559,7 @@ async function onConfirmPay() {
|
|||||||
</view>
|
</view>
|
||||||
<view v-if="isHasInput('mobile')" class="field">
|
<view v-if="isHasInput('mobile')" class="field">
|
||||||
<text class="label">手机号</text>
|
<text class="label">手机号</text>
|
||||||
<input v-model="formData.mobile" class="input" type="number" maxlength="11" placeholder="请输入手机号" placeholder-class="ph">
|
<input v-model="formData.mobile" class="input" type="number" :maxlength="11" placeholder="请输入手机号" placeholder-class="ph">
|
||||||
</view>
|
</view>
|
||||||
<view v-if="isHasInput('carLicense')" class="field">
|
<view v-if="isHasInput('carLicense')" class="field">
|
||||||
<text class="label">车牌号</text>
|
<text class="label">车牌号</text>
|
||||||
@@ -654,7 +636,7 @@ async function onConfirmPay() {
|
|||||||
|
|
||||||
<view v-if="isHasInput('verificationCode')" class="field code-row">
|
<view v-if="isHasInput('verificationCode')" class="field code-row">
|
||||||
<text class="label">验证码</text>
|
<text class="label">验证码</text>
|
||||||
<input v-model="formData.verificationCode" class="input flex1" maxlength="6" placeholder="请输入验证码" placeholder-class="ph">
|
<input v-model="formData.verificationCode" class="input flex1" :maxlength="6" placeholder="请输入验证码" placeholder-class="ph">
|
||||||
<view class="sms-btn" :class="{ disabled: isCountingDown || !isPhoneNumberValid }" @tap="sendSmsCode">
|
<view class="sms-btn" :class="{ disabled: isCountingDown || !isPhoneNumberValid }" @tap="sendSmsCode">
|
||||||
{{ isCountingDown ? `${countdown}s重新获取` : '获取验证码' }}
|
{{ isCountingDown ? `${countdown}s重新获取` : '获取验证码' }}
|
||||||
</view>
|
</view>
|
||||||
@@ -750,6 +732,33 @@ async function onConfirmPay() {
|
|||||||
padding: 24rpx 24rpx 48rpx;
|
padding: 24rpx 24rpx 48rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 顶部产品图 */
|
||||||
|
.inquire-banner {
|
||||||
|
position: relative;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
overflow: hidden;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
.inquire-banner-img {
|
||||||
|
width: 100%;
|
||||||
|
max-height: 260rpx;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
.inquire-banner-overlay {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
padding: 16rpx 24rpx;
|
||||||
|
background: linear-gradient(transparent, rgba(0,0,0,0.4));
|
||||||
|
}
|
||||||
|
.inquire-banner-title {
|
||||||
|
font-size: 26rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #fff;
|
||||||
|
text-shadow: 0 1rpx 4rpx rgba(0,0,0,0.3);
|
||||||
|
}
|
||||||
|
|
||||||
.card-container {
|
.card-container {
|
||||||
background: #fff;
|
background: #fff;
|
||||||
border-radius: 16rpx;
|
border-radius: 16rpx;
|
||||||
|
|||||||
190
src/pages/inquire/list.vue
Normal file
190
src/pages/inquire/list.vue
Normal file
@@ -0,0 +1,190 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { computed } from 'vue'
|
||||||
|
import { getInquireCategoryConfig, getInquiryItemIconUrl } from '@/config/inquireCategories'
|
||||||
|
|
||||||
|
definePage({
|
||||||
|
style: {
|
||||||
|
navigationBarTitleText: '车辆查询服务',
|
||||||
|
navigationStyle: 'default',
|
||||||
|
navigationBarBackgroundColor: '#ffffff',
|
||||||
|
navigationBarTextStyle: 'black',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const vehicleItems = computed(() => getInquireCategoryConfig('vehicle')?.items ?? [])
|
||||||
|
|
||||||
|
function goInquireFeature(feature: string) {
|
||||||
|
uni.navigateTo({ url: `/pages/inquire/index?feature=${encodeURIComponent(feature)}` })
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<view class="page-root">
|
||||||
|
<scroll-view scroll-y class="scrollarea">
|
||||||
|
<view class="page">
|
||||||
|
<!-- 头部统计 -->
|
||||||
|
<view class="list-header">
|
||||||
|
<view class="list-header-icon">
|
||||||
|
<view class="i-carbon-car" />
|
||||||
|
</view>
|
||||||
|
<view class="list-header-info">
|
||||||
|
<text class="list-header-title">车辆查询服务</text>
|
||||||
|
<text class="list-header-desc">共 {{ vehicleItems.length }} 项专业车况核验服务</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 服务列表 -->
|
||||||
|
<view class="service-list">
|
||||||
|
<view
|
||||||
|
v-for="item in vehicleItems"
|
||||||
|
:key="item.feature"
|
||||||
|
class="service-item"
|
||||||
|
@tap="goInquireFeature(item.feature)"
|
||||||
|
>
|
||||||
|
<view class="svc-icon-wrap">
|
||||||
|
<image class="svc-icon" :src="getInquiryItemIconUrl(item)" mode="aspectFit" />
|
||||||
|
</view>
|
||||||
|
<view class="svc-content">
|
||||||
|
<text class="svc-name">{{ item.name }}</text>
|
||||||
|
<text class="svc-desc">{{ item.desc }}</text>
|
||||||
|
</view>
|
||||||
|
<text class="svc-arrow">›</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</scroll-view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.page-root {
|
||||||
|
height: 100vh;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
background: linear-gradient(180deg, #f8faff 0%, #f3f5fb 100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.scrollarea {
|
||||||
|
flex: 1;
|
||||||
|
min-height: 0;
|
||||||
|
height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page {
|
||||||
|
padding: 24rpx 24rpx 40rpx;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.list-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 20rpx;
|
||||||
|
padding: 28rpx 28rpx;
|
||||||
|
background: linear-gradient(145deg, #ffffff 0%, #f7f8ff 100%);
|
||||||
|
border-radius: 24rpx;
|
||||||
|
border: 1rpx solid #e5e6f0;
|
||||||
|
margin-bottom: 24rpx;
|
||||||
|
box-shadow: 0 16rpx 40rpx rgba(15, 35, 52, 0.04),
|
||||||
|
0 0 0 1rpx rgba(255, 255, 255, 0.5) inset;
|
||||||
|
}
|
||||||
|
|
||||||
|
.list-header-icon {
|
||||||
|
width: 80rpx;
|
||||||
|
height: 80rpx;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
background: linear-gradient(135deg, #e8f0fe, #d4e4fd);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: 38rpx;
|
||||||
|
color: #1768ff;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.list-header-info {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.list-header-title {
|
||||||
|
display: block;
|
||||||
|
font-size: 32rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #1d2129;
|
||||||
|
margin-bottom: 6rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.list-header-desc {
|
||||||
|
display: block;
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #86909c;
|
||||||
|
}
|
||||||
|
|
||||||
|
.service-list {
|
||||||
|
background: linear-gradient(145deg, #ffffff 0%, #f7f8ff 100%);
|
||||||
|
border-radius: 24rpx;
|
||||||
|
border: 1rpx solid #e5e6f0;
|
||||||
|
overflow: hidden;
|
||||||
|
box-shadow: 0 16rpx 40rpx rgba(15, 35, 52, 0.04),
|
||||||
|
0 0 0 1rpx rgba(255, 255, 255, 0.5) inset;
|
||||||
|
}
|
||||||
|
|
||||||
|
.service-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 20rpx;
|
||||||
|
padding: 24rpx 28rpx;
|
||||||
|
border-bottom: 1rpx solid #f2f3f5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.service-item:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.service-item:active {
|
||||||
|
background: #f7f8fa;
|
||||||
|
}
|
||||||
|
|
||||||
|
.svc-icon-wrap {
|
||||||
|
width: 72rpx;
|
||||||
|
height: 72rpx;
|
||||||
|
border-radius: 18rpx;
|
||||||
|
background: linear-gradient(135deg, #e8f0fe, #d4e4fd);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.svc-icon {
|
||||||
|
width: 40rpx;
|
||||||
|
height: 40rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.svc-content {
|
||||||
|
flex: 1;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.svc-name {
|
||||||
|
display: block;
|
||||||
|
font-size: 28rpx;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #1d2129;
|
||||||
|
margin-bottom: 4rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.svc-desc {
|
||||||
|
display: block;
|
||||||
|
font-size: 22rpx;
|
||||||
|
color: #86909c;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.svc-arrow {
|
||||||
|
font-size: 32rpx;
|
||||||
|
color: #c9cdd4;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -329,120 +329,160 @@ onUnmounted(() => {
|
|||||||
<view class="page-root">
|
<view class="page-root">
|
||||||
<scroll-view scroll-y class="scrollarea">
|
<scroll-view scroll-y class="scrollarea">
|
||||||
<view class="page">
|
<view class="page">
|
||||||
<view class="banner mine-banner">
|
|
||||||
<view class="banner-text">
|
|
||||||
<view class="banner-title">
|
|
||||||
买车先查车况,更安心
|
|
||||||
</view>
|
|
||||||
<view class="banner-sub">
|
|
||||||
减少隐蔽事故车、泡水车、调表车风险
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="banner-illustration">
|
|
||||||
<view class="car-illus" />
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<view class="card mine-user">
|
<!-- ═══ 区块1: 个人信息栏 ═══ -->
|
||||||
<view class="mine-user-main" @tap="handleUserTap">
|
<view class="profile-card">
|
||||||
<view class="mine-avatar-placeholder" />
|
<view class="profile-bg" />
|
||||||
<view class="mine-user-text">
|
<view class="profile-content" @tap="handleUserTap">
|
||||||
<view class="mine-user-name">
|
<view class="profile-avatar">
|
||||||
{{ isLogin ? nickname : '您还没有登录,立即登录' }}
|
<view class="avatar-inner">
|
||||||
</view>
|
<view class="avatar-icon i-carbon-user" />
|
||||||
<view class="mine-user-desc">
|
|
||||||
{{ isLogin ? userDesc : '登录后可同步历史报告与收藏' }}
|
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
<view class="profile-info">
|
||||||
|
<text class="profile-name">{{ isLogin ? nickname : '点击登录' }}</text>
|
||||||
|
<text class="profile-desc">{{ isLogin ? userDesc : '登录后可同步历史报告与收藏' }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="profile-arrow">
|
||||||
|
<view class="i-carbon-chevron-right" />
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<!-- 已登录未绑定手机 -->
|
||||||
|
<view v-if="isLogin && !hasBoundMobile" class="profile-actions">
|
||||||
|
<view class="action-btn" @tap.stop="openBindModal">
|
||||||
|
<view class="action-icon i-carbon-phone" />
|
||||||
|
<text class="action-text">绑定手机号</text>
|
||||||
</view>
|
</view>
|
||||||
<!-- #ifdef MP-WEIXIN -->
|
<!-- #ifdef MP-WEIXIN -->
|
||||||
<view v-if="isLogin && !hasBoundMobile" class="mine-user-extra">
|
<view class="action-btn" @tap.stop="syncWxNickname">
|
||||||
<text class="extra-link" @tap.stop="syncWxNickname">同步微信昵称</text>
|
<view class="action-icon i-carbon-edit" />
|
||||||
<text class="extra-dot">·</text>
|
<text class="action-text">同步昵称</text>
|
||||||
<text class="extra-hint">绑定手机后优先显示手机号</text>
|
|
||||||
</view>
|
</view>
|
||||||
<!-- #endif -->
|
<!-- #endif -->
|
||||||
<view
|
|
||||||
v-if="isLogin && !hasBoundMobile"
|
|
||||||
class="mine-bind-row"
|
|
||||||
@tap.stop="openBindModal"
|
|
||||||
>
|
|
||||||
<text class="mine-bind-text">绑定手机号</text>
|
|
||||||
<text class="mine-bind-arrow">›</text>
|
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view class="card">
|
<!-- ═══ 区块2: 快捷功能(4宫格) ═══ -->
|
||||||
<view class="grid-4">
|
<view class="section">
|
||||||
<view class="grid-item" @tap="goHistoryReport">
|
<view class="section-title">快捷功能</view>
|
||||||
<view class="icon-tool i-carbon-document" />
|
<view class="quick-grid">
|
||||||
<view class="grid-text">
|
<view class="quick-item" @tap="goHistoryReport">
|
||||||
历史报告
|
<view class="quick-icon-wrap" style="background: rgba(23,104,255,0.08)">
|
||||||
|
<view class="quick-icon i-carbon-document" style="color: #1768ff" />
|
||||||
</view>
|
</view>
|
||||||
|
<text class="quick-name">历史报告</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="grid-item" @tap="goFreeValuation">
|
<view class="quick-item" @tap="goFreeValuation">
|
||||||
<view class="icon-tool i-carbon-chart-line" />
|
<view class="quick-icon-wrap" style="background: rgba(250,140,22,0.08)">
|
||||||
<view class="grid-text">
|
<view class="quick-icon i-carbon-chart-line" style="color: #fa8c16" />
|
||||||
免费估值
|
|
||||||
</view>
|
</view>
|
||||||
|
<text class="quick-name">免费估值</text>
|
||||||
</view>
|
</view>
|
||||||
<!-- #ifdef MP-WEIXIN -->
|
<!-- #ifdef MP-WEIXIN -->
|
||||||
<button class="grid-item grid-item-btn" open-type="share" hover-class="grid-item-hover">
|
<button class="quick-item quick-item-btn" open-type="share" hover-class="quick-item-hover">
|
||||||
<view class="icon-tool i-carbon-share" />
|
<view class="quick-icon-wrap" style="background: rgba(19,194,94,0.08)">
|
||||||
<view class="grid-text">
|
<view class="quick-icon i-carbon-share" style="color: #13c25e" />
|
||||||
分享好友
|
|
||||||
</view>
|
</view>
|
||||||
|
<text class="quick-name">分享好友</text>
|
||||||
</button>
|
</button>
|
||||||
<!-- #endif -->
|
<!-- #endif -->
|
||||||
<!-- #ifndef MP-WEIXIN -->
|
<!-- #ifndef MP-WEIXIN -->
|
||||||
<view class="grid-item" @tap="goShareFallback">
|
<view class="quick-item" @tap="goShareFallback">
|
||||||
<view class="icon-tool i-carbon-share" />
|
<view class="quick-icon-wrap" style="background: rgba(19,194,94,0.08)">
|
||||||
<view class="grid-text">
|
<view class="quick-icon i-carbon-share" style="color: #13c25e" />
|
||||||
分享好友
|
|
||||||
</view>
|
</view>
|
||||||
|
<text class="quick-name">分享好友</text>
|
||||||
</view>
|
</view>
|
||||||
<!-- #endif -->
|
<!-- #endif -->
|
||||||
<view class="grid-item" @tap="openCoopModal">
|
<view class="quick-item" @tap="openCoopModal">
|
||||||
<view class="icon-tool i-carbon-enterprise" />
|
<view class="quick-icon-wrap" style="background: rgba(114,46,209,0.08)">
|
||||||
<view class="grid-text">
|
<view class="quick-icon i-carbon-enterprise" style="color: #722ed1" />
|
||||||
商务合作
|
|
||||||
</view>
|
</view>
|
||||||
|
<text class="quick-name">商务合作</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view class="card list-card">
|
<!-- ═══ 区块3: 常用工具 ═══ -->
|
||||||
<view class="list-item" @tap="goLegalUserAgreement">
|
<view class="section">
|
||||||
<view class="list-icon i-carbon-document-blank" />
|
<view class="section-title">常用工具</view>
|
||||||
<text class="list-text">用户协议</text>
|
<view class="tool-list">
|
||||||
|
<view class="tool-row" @tap="goOilPrice">
|
||||||
|
<view class="tool-row-icon-wrap" style="background: rgba(23,104,255,0.08)">
|
||||||
|
<view class="tool-row-icon i-carbon-gas-station" style="color: #1768ff" />
|
||||||
</view>
|
</view>
|
||||||
<view class="list-item" @tap="goLegalPrivacyPolicy">
|
<text class="tool-row-name">实时油价查询</text>
|
||||||
<view class="list-icon i-carbon-security" />
|
<text class="tool-row-arrow">›</text>
|
||||||
<text class="list-text">隐私政策</text>
|
</view>
|
||||||
|
<view class="tool-row" @tap="goIllegalCode">
|
||||||
|
<view class="tool-row-icon-wrap" style="background: rgba(250,140,22,0.08)">
|
||||||
|
<view class="tool-row-icon i-carbon-search" style="color: #fa8c16" />
|
||||||
|
</view>
|
||||||
|
<text class="tool-row-name">违章代码查询</text>
|
||||||
|
<text class="tool-row-arrow">›</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="list-item" @tap="goLegalAuthorization">
|
|
||||||
<view class="list-icon i-carbon-certificate" />
|
|
||||||
<text class="list-text">授权书</text>
|
|
||||||
</view>
|
</view>
|
||||||
<view class="list-item" @tap="goHelp">
|
|
||||||
<view class="list-icon i-carbon-help" />
|
|
||||||
<text class="list-text">帮助中心</text>
|
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
|
<!-- ═══ 区块4: 服务与支持 ═══ -->
|
||||||
|
<view class="section">
|
||||||
<button
|
<view class="section-title">服务与支持</view>
|
||||||
class="list-item list-item-contact no-border"
|
<view class="tool-list">
|
||||||
open-type="contact"
|
<button class="tool-row tool-row-btn no-border" open-type="contact" hover-class="tool-row-hover">
|
||||||
hover-class="list-item-contact-hover"
|
<view class="tool-row-icon-wrap" style="background: rgba(19,194,94,0.08)">
|
||||||
>
|
<view class="tool-row-icon i-carbon-chat" style="color: #13c25e" />
|
||||||
<view class="list-icon i-carbon-chat" />
|
</view>
|
||||||
<view class="service-row">
|
<view class="tool-row-text">
|
||||||
<text class="list-text">在线客服</text>
|
<text class="tool-row-name">在线客服</text>
|
||||||
<text class="service-time">人工客服 周一至周日 9:00-20:00</text>
|
<text class="tool-row-sub">周一至周日 9:00-20:00</text>
|
||||||
</view>
|
</view>
|
||||||
</button>
|
</button>
|
||||||
|
<view class="tool-row" @tap="goHelp">
|
||||||
|
<view class="tool-row-icon-wrap" style="background: rgba(114,46,209,0.08)">
|
||||||
|
<view class="tool-row-icon i-carbon-help" style="color: #722ed1" />
|
||||||
</view>
|
</view>
|
||||||
|
<text class="tool-row-name">帮助中心</text>
|
||||||
|
<text class="tool-row-arrow">›</text>
|
||||||
|
</view>
|
||||||
|
<view class="tool-row" @tap="goAbout">
|
||||||
|
<view class="tool-row-icon-wrap" style="background: rgba(78,89,105,0.08)">
|
||||||
|
<view class="tool-row-icon i-carbon-information" style="color: #4e5969" />
|
||||||
|
</view>
|
||||||
|
<text class="tool-row-name">关于我们</text>
|
||||||
|
<text class="tool-row-arrow">›</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- ═══ 区块5: 法律条款 ═══ -->
|
||||||
|
<view class="section">
|
||||||
|
<view class="section-title">法律条款</view>
|
||||||
|
<view class="tool-list">
|
||||||
|
<view class="tool-row" @tap="goLegalUserAgreement">
|
||||||
|
<view class="tool-row-icon-wrap" style="background: rgba(78,89,105,0.06)">
|
||||||
|
<view class="tool-row-icon i-carbon-document-blank" style="color: #86909c" />
|
||||||
|
</view>
|
||||||
|
<text class="tool-row-name">用户协议</text>
|
||||||
|
<text class="tool-row-arrow">›</text>
|
||||||
|
</view>
|
||||||
|
<view class="tool-row" @tap="goLegalPrivacyPolicy">
|
||||||
|
<view class="tool-row-icon-wrap" style="background: rgba(78,89,105,0.06)">
|
||||||
|
<view class="tool-row-icon i-carbon-security" style="color: #86909c" />
|
||||||
|
</view>
|
||||||
|
<text class="tool-row-name">隐私政策</text>
|
||||||
|
<text class="tool-row-arrow">›</text>
|
||||||
|
</view>
|
||||||
|
<view class="tool-row no-border" @tap="goLegalAuthorization">
|
||||||
|
<view class="tool-row-icon-wrap" style="background: rgba(78,89,105,0.06)">
|
||||||
|
<view class="tool-row-icon i-carbon-certificate" style="color: #86909c" />
|
||||||
|
</view>
|
||||||
|
<text class="tool-row-name">授权书</text>
|
||||||
|
<text class="tool-row-arrow">›</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view style="height: 40rpx" />
|
||||||
</view>
|
</view>
|
||||||
</scroll-view>
|
</scroll-view>
|
||||||
|
|
||||||
@@ -531,7 +571,7 @@ onUnmounted(() => {
|
|||||||
height: 100vh;
|
height: 100vh;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
background: linear-gradient(180deg, #f8faff 0%, #f3f5fb 100%);
|
background: linear-gradient(180deg, #f0f5ff 0%, #f5f7fa 30%, #f3f5fb 100%);
|
||||||
}
|
}
|
||||||
|
|
||||||
.scrollarea {
|
.scrollarea {
|
||||||
@@ -541,143 +581,355 @@ onUnmounted(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.page {
|
.page {
|
||||||
padding: 24rpx 24rpx 40rpx;
|
padding: 0 24rpx 40rpx;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
.banner {
|
/* ═══ 区块1: 个人信息栏 ═══ */
|
||||||
display: flex;
|
.profile-card {
|
||||||
padding: 32rpx 28rpx;
|
position: relative;
|
||||||
|
border-radius: 0 0 32rpx 32rpx;
|
||||||
|
overflow: hidden;
|
||||||
margin-bottom: 24rpx;
|
margin-bottom: 24rpx;
|
||||||
background: linear-gradient(135deg, #fff7f0 0%, #ffffff 100%);
|
|
||||||
border-radius: 24rpx;
|
|
||||||
box-shadow:
|
|
||||||
0 18rpx 40rpx rgba(15, 35, 52, 0.05),
|
|
||||||
0 0 0 1rpx rgba(226, 229, 239, 0.9);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.banner-text {
|
.profile-bg {
|
||||||
flex: 1;
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background: linear-gradient(135deg, #1768ff 0%, #4d94ff 60%, #7bb8ff 100%);
|
||||||
}
|
}
|
||||||
|
|
||||||
.banner-title {
|
.profile-content {
|
||||||
font-size: 32rpx;
|
position: relative;
|
||||||
font-weight: 600;
|
|
||||||
color: #1d2129;
|
|
||||||
margin-bottom: 8rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.banner-sub {
|
|
||||||
font-size: 24rpx;
|
|
||||||
color: #4e5969;
|
|
||||||
}
|
|
||||||
|
|
||||||
.banner-illustration {
|
|
||||||
width: 180rpx;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
padding: 48rpx 32rpx 32rpx;
|
||||||
|
gap: 20rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.car-illus {
|
.profile-avatar {
|
||||||
width: 160rpx;
|
|
||||||
height: 120rpx;
|
|
||||||
border-radius: 16rpx;
|
|
||||||
background: linear-gradient(145deg, #ffe8dc 0%, #ffc9a8 100%);
|
|
||||||
opacity: 0.95;
|
|
||||||
}
|
|
||||||
|
|
||||||
.card {
|
|
||||||
background: linear-gradient(145deg, #ffffff 0%, #f7f8ff 100%);
|
|
||||||
border-radius: 24rpx;
|
|
||||||
padding: 24rpx 24rpx 20rpx;
|
|
||||||
margin-bottom: 24rpx;
|
|
||||||
border: 1rpx solid #e5e6f0;
|
|
||||||
box-shadow:
|
|
||||||
0 16rpx 40rpx rgba(15, 35, 52, 0.04),
|
|
||||||
0 0 0 1rpx rgba(255, 255, 255, 0.5) inset;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mine-user {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: stretch;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mine-user-main {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mine-avatar-placeholder {
|
|
||||||
width: 80rpx;
|
|
||||||
height: 80rpx;
|
|
||||||
border-radius: 50%;
|
|
||||||
background-color: #f2f3f5;
|
|
||||||
margin-right: 20rpx;
|
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mine-user-text {
|
.avatar-inner {
|
||||||
|
width: 96rpx;
|
||||||
|
height: 96rpx;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: rgba(255, 255, 255, 0.2);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
border: 3rpx solid rgba(255, 255, 255, 0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar-icon {
|
||||||
|
font-size: 44rpx;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.profile-info {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mine-user-name {
|
.profile-name {
|
||||||
|
display: block;
|
||||||
|
font-size: 32rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #fff;
|
||||||
|
margin-bottom: 6rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.profile-desc {
|
||||||
|
display: block;
|
||||||
|
font-size: 22rpx;
|
||||||
|
color: rgba(255, 255, 255, 0.8);
|
||||||
|
}
|
||||||
|
|
||||||
|
.profile-arrow {
|
||||||
|
flex-shrink: 0;
|
||||||
|
color: rgba(255, 255, 255, 0.6);
|
||||||
font-size: 28rpx;
|
font-size: 28rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.profile-actions {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
gap: 24rpx;
|
||||||
|
padding: 0 32rpx 28rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-btn {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8rpx;
|
||||||
|
padding: 10rpx 24rpx;
|
||||||
|
border-radius: 24rpx;
|
||||||
|
background: rgba(255, 255, 255, 0.18);
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-icon {
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-text {
|
||||||
|
font-size: 22rpx;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ═══ 区块通用 ═══ */
|
||||||
|
.section {
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 24rpx;
|
||||||
|
padding: 28rpx 24rpx 8rpx;
|
||||||
|
margin-bottom: 24rpx;
|
||||||
|
box-shadow: 0 4rpx 16rpx rgba(15, 35, 52, 0.03);
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-title {
|
||||||
|
font-size: 26rpx;
|
||||||
|
font-weight: 600;
|
||||||
color: #1d2129;
|
color: #1d2129;
|
||||||
margin-bottom: 4rpx;
|
margin-bottom: 20rpx;
|
||||||
|
padding-left: 4rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mine-user-desc {
|
/* ═══ 区块2: 快捷功能(4宫格) ═══ */
|
||||||
font-size: 22rpx;
|
.quick-grid {
|
||||||
color: #86909c;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mine-user-extra {
|
|
||||||
margin-top: 16rpx;
|
|
||||||
padding-top: 16rpx;
|
|
||||||
border-top: 1rpx solid #f0f0f0;
|
|
||||||
font-size: 22rpx;
|
|
||||||
color: #86909c;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
|
padding-bottom: 16rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quick-item {
|
||||||
|
width: 25%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
padding: 12rpx 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.extra-link {
|
.quick-item-btn {
|
||||||
color: #1768ff;
|
margin: 0;
|
||||||
|
padding: 12rpx 0;
|
||||||
|
border: none;
|
||||||
|
background: transparent;
|
||||||
|
line-height: normal;
|
||||||
|
font-size: inherit;
|
||||||
|
color: inherit;
|
||||||
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
.extra-dot {
|
.quick-item-btn::after {
|
||||||
margin: 0 8rpx;
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quick-item-hover {
|
||||||
|
opacity: 0.7;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quick-icon-wrap {
|
||||||
|
width: 80rpx;
|
||||||
|
height: 80rpx;
|
||||||
|
border-radius: 24rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
margin-bottom: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quick-icon {
|
||||||
|
font-size: 36rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quick-name {
|
||||||
|
font-size: 22rpx;
|
||||||
|
color: #4e5969;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ═══ 区块3/4/5: 列表行 ═══ */
|
||||||
|
.tool-list {
|
||||||
|
padding-bottom: 8rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tool-row {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 20rpx 4rpx;
|
||||||
|
border-bottom: 1rpx solid #f5f5f5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tool-row:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tool-row:active {
|
||||||
|
background: #fafbfc;
|
||||||
|
border-radius: 12rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tool-row-btn {
|
||||||
|
margin: 0;
|
||||||
|
padding: 20rpx 4rpx;
|
||||||
|
border: none;
|
||||||
|
border-radius: 0;
|
||||||
|
background: transparent;
|
||||||
|
text-align: left;
|
||||||
|
line-height: inherit;
|
||||||
|
font-size: inherit;
|
||||||
|
color: inherit;
|
||||||
|
box-sizing: border-box;
|
||||||
|
width: 100%;
|
||||||
|
border-bottom: 1rpx solid #f5f5f5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tool-row-btn::after {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tool-row-hover {
|
||||||
|
background: rgba(23, 104, 255, 0.04);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tool-row-icon-wrap {
|
||||||
|
width: 56rpx;
|
||||||
|
height: 56rpx;
|
||||||
|
border-radius: 50%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
margin-right: 16rpx;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tool-row-icon {
|
||||||
|
font-size: 28rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tool-row-text {
|
||||||
|
flex: 1;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tool-row-name {
|
||||||
|
flex: 1;
|
||||||
|
font-size: 26rpx;
|
||||||
|
color: #1d2129;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tool-row-sub {
|
||||||
|
display: block;
|
||||||
|
font-size: 20rpx;
|
||||||
|
color: #ffb020;
|
||||||
|
margin-top: 2rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tool-row-arrow {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #c9cdd4;
|
||||||
|
flex-shrink: 0;
|
||||||
|
margin-left: 8rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-border {
|
||||||
|
border-bottom: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ═══ 弹窗样式 ═══ */
|
||||||
|
.coop-mask {
|
||||||
|
position: fixed;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background: rgba(0, 0, 0, 0.5);
|
||||||
|
z-index: 1001;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 48rpx;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.coop-dialog {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 600rpx;
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 24rpx;
|
||||||
|
padding: 36rpx 32rpx 28rpx;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.coop-title {
|
||||||
|
font-size: 32rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #1d2129;
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 12rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.coop-hint {
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #86909c;
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 28rpx;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.coop-qr {
|
||||||
|
display: block;
|
||||||
|
width: 360rpx;
|
||||||
|
height: 360rpx;
|
||||||
|
margin: 0 auto 28rpx;
|
||||||
|
border-radius: 12rpx;
|
||||||
|
background: #f7f8fa;
|
||||||
|
}
|
||||||
|
|
||||||
|
.coop-qr-placeholder {
|
||||||
|
width: 360rpx;
|
||||||
|
height: 360rpx;
|
||||||
|
margin: 0 auto 28rpx;
|
||||||
|
border-radius: 12rpx;
|
||||||
|
border: 2rpx dashed #dcdfe6;
|
||||||
|
background: #fafbfc;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 24rpx;
|
||||||
|
box-sizing: border-box;
|
||||||
|
gap: 12rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.coop-qr-placeholder-text {
|
||||||
|
font-size: 22rpx;
|
||||||
|
color: #86909c;
|
||||||
|
line-height: 1.6;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.coop-qr-placeholder-sub {
|
||||||
|
font-size: 20rpx;
|
||||||
color: #c9cdd4;
|
color: #c9cdd4;
|
||||||
}
|
}
|
||||||
|
|
||||||
.extra-hint {
|
.coop-close {
|
||||||
color: #86909c;
|
height: 80rpx;
|
||||||
}
|
line-height: 80rpx;
|
||||||
|
text-align: center;
|
||||||
.mine-bind-row {
|
background: linear-gradient(90deg, #1768ff 0%, #4d94ff 100%);
|
||||||
margin-top: 12rpx;
|
color: #fff;
|
||||||
padding: 16rpx 0 4rpx;
|
font-size: 28rpx;
|
||||||
display: flex;
|
font-weight: 600;
|
||||||
align-items: center;
|
border-radius: 40rpx;
|
||||||
justify-content: space-between;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mine-bind-text {
|
|
||||||
font-size: 26rpx;
|
|
||||||
color: #1768ff;
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mine-bind-arrow {
|
|
||||||
font-size: 36rpx;
|
|
||||||
color: #1768ff;
|
|
||||||
line-height: 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ═══ 绑定手机弹窗 ═══ */
|
||||||
.bind-mask {
|
.bind-mask {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
left: 0;
|
left: 0;
|
||||||
@@ -785,198 +1037,4 @@ onUnmounted(() => {
|
|||||||
color: #86909c;
|
color: #86909c;
|
||||||
padding: 12rpx;
|
padding: 12rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.grid-4 {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
}
|
|
||||||
|
|
||||||
.grid-item {
|
|
||||||
width: 25%;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
padding-top: 8rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.grid-item-btn {
|
|
||||||
margin: 0;
|
|
||||||
padding: 8rpx 0 0;
|
|
||||||
border: none;
|
|
||||||
background: transparent;
|
|
||||||
line-height: normal;
|
|
||||||
font-size: inherit;
|
|
||||||
color: inherit;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
.grid-item-btn::after {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.grid-item-hover {
|
|
||||||
opacity: 0.88;
|
|
||||||
}
|
|
||||||
|
|
||||||
.coop-mask {
|
|
||||||
position: fixed;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
top: 0;
|
|
||||||
bottom: 0;
|
|
||||||
background: rgba(0, 0, 0, 0.5);
|
|
||||||
z-index: 1001;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
padding: 48rpx;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
.coop-dialog {
|
|
||||||
width: 100%;
|
|
||||||
max-width: 600rpx;
|
|
||||||
background: #fff;
|
|
||||||
border-radius: 24rpx;
|
|
||||||
padding: 36rpx 32rpx 28rpx;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
.coop-title {
|
|
||||||
font-size: 32rpx;
|
|
||||||
font-weight: 600;
|
|
||||||
color: #1d2129;
|
|
||||||
text-align: center;
|
|
||||||
margin-bottom: 12rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.coop-hint {
|
|
||||||
font-size: 24rpx;
|
|
||||||
color: #86909c;
|
|
||||||
text-align: center;
|
|
||||||
margin-bottom: 28rpx;
|
|
||||||
line-height: 1.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
.coop-qr {
|
|
||||||
display: block;
|
|
||||||
width: 360rpx;
|
|
||||||
height: 360rpx;
|
|
||||||
margin: 0 auto 28rpx;
|
|
||||||
border-radius: 12rpx;
|
|
||||||
background: #f7f8fa;
|
|
||||||
}
|
|
||||||
|
|
||||||
.coop-qr-placeholder {
|
|
||||||
width: 360rpx;
|
|
||||||
height: 360rpx;
|
|
||||||
margin: 0 auto 28rpx;
|
|
||||||
border-radius: 12rpx;
|
|
||||||
border: 2rpx dashed #dcdfe6;
|
|
||||||
background: #fafbfc;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
padding: 24rpx;
|
|
||||||
box-sizing: border-box;
|
|
||||||
gap: 12rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.coop-qr-placeholder-text {
|
|
||||||
font-size: 22rpx;
|
|
||||||
color: #86909c;
|
|
||||||
line-height: 1.6;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.coop-qr-placeholder-sub {
|
|
||||||
font-size: 20rpx;
|
|
||||||
color: #c9cdd4;
|
|
||||||
}
|
|
||||||
|
|
||||||
.coop-close {
|
|
||||||
height: 80rpx;
|
|
||||||
line-height: 80rpx;
|
|
||||||
text-align: center;
|
|
||||||
background: linear-gradient(90deg, #1768ff 0%, #4d94ff 100%);
|
|
||||||
color: #fff;
|
|
||||||
font-size: 28rpx;
|
|
||||||
font-weight: 600;
|
|
||||||
border-radius: 40rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.icon-tool {
|
|
||||||
width: 48rpx;
|
|
||||||
height: 48rpx;
|
|
||||||
margin-bottom: 8rpx;
|
|
||||||
color: #1768ff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.grid-text {
|
|
||||||
font-size: 24rpx;
|
|
||||||
color: #4e5969;
|
|
||||||
}
|
|
||||||
|
|
||||||
.list-card {
|
|
||||||
padding: 0 24rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.list-item {
|
|
||||||
height: 96rpx;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
border-bottom: 1rpx solid #f0f0f0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.list-item-contact {
|
|
||||||
width: 100%;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
border: none;
|
|
||||||
border-radius: 0;
|
|
||||||
background: transparent;
|
|
||||||
text-align: left;
|
|
||||||
line-height: inherit;
|
|
||||||
font-size: inherit;
|
|
||||||
color: inherit;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
.list-item-contact::after {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.list-item-contact-hover {
|
|
||||||
background: rgba(23, 104, 255, 0.06);
|
|
||||||
}
|
|
||||||
|
|
||||||
.list-icon {
|
|
||||||
width: 40rpx;
|
|
||||||
height: 40rpx;
|
|
||||||
margin-right: 20rpx;
|
|
||||||
flex-shrink: 0;
|
|
||||||
color: #1768ff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.no-border {
|
|
||||||
border-bottom-width: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.list-text {
|
|
||||||
font-size: 26rpx;
|
|
||||||
color: #1d2129;
|
|
||||||
}
|
|
||||||
|
|
||||||
.service-row {
|
|
||||||
width: 100%;
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.service-time {
|
|
||||||
font-size: 22rpx;
|
|
||||||
color: #ffb020;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref } from 'vue'
|
import { ref, computed } from 'vue'
|
||||||
import { onLoad } from '@dcloudio/uni-app'
|
import { onLoad } from '@dcloudio/uni-app'
|
||||||
import { toolboxCategories, getCategoryAllTools } from '@/config/toolboxRegistry'
|
import { toolboxCategories, toolboxItems, getCategoryAllTools } from '@/config/toolboxRegistry'
|
||||||
|
|
||||||
definePage({
|
definePage({
|
||||||
style: {
|
style: {
|
||||||
@@ -15,11 +15,44 @@ definePage({
|
|||||||
const categoryKey = ref('')
|
const categoryKey = ref('')
|
||||||
const category = ref<any>(null)
|
const category = ref<any>(null)
|
||||||
const tools = ref<any[]>([])
|
const tools = ref<any[]>([])
|
||||||
|
const isAllCategories = ref(false)
|
||||||
|
|
||||||
|
/** 当前选中的 tab 索引 */
|
||||||
|
const activeTab = ref(0)
|
||||||
|
|
||||||
|
/** 搜索关键词 */
|
||||||
|
const searchKeyword = ref('')
|
||||||
|
|
||||||
|
/** 当前选中分类的完整数据 */
|
||||||
|
const activeCategory = computed(() => toolboxCategories[activeTab.value] || toolboxCategories[0])
|
||||||
|
|
||||||
|
/** 当前选中分类的全部工具 */
|
||||||
|
const activeTools = computed(() => getCategoryAllTools(activeCategory.value.key))
|
||||||
|
|
||||||
|
/** 是否正在搜索(有关键词) */
|
||||||
|
const isSearching = computed(() => searchKeyword.value.trim().length > 0)
|
||||||
|
|
||||||
|
/** 搜索结果:从所有工具中匹配名称 / 描述 / key */
|
||||||
|
const searchResults = computed(() => {
|
||||||
|
const kw = searchKeyword.value.trim().toLowerCase()
|
||||||
|
if (!kw) return []
|
||||||
|
return toolboxItems.filter(item =>
|
||||||
|
item.name.toLowerCase().includes(kw)
|
||||||
|
|| item.desc.toLowerCase().includes(kw)
|
||||||
|
|| item.key.toLowerCase().includes(kw),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
onLoad((query) => {
|
onLoad((query) => {
|
||||||
const key = (query?.category as string) || ''
|
const key = (query?.category as string) || ''
|
||||||
categoryKey.value = key
|
categoryKey.value = key
|
||||||
|
|
||||||
|
if (key === 'all') {
|
||||||
|
isAllCategories.value = true
|
||||||
|
uni.setNavigationBarTitle({ title: '全部分类' })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
const cat = toolboxCategories.find(c => c.key === key)
|
const cat = toolboxCategories.find(c => c.key === key)
|
||||||
if (cat) {
|
if (cat) {
|
||||||
category.value = cat
|
category.value = cat
|
||||||
@@ -28,6 +61,15 @@ onLoad((query) => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
function switchTab(idx: number) {
|
||||||
|
activeTab.value = idx
|
||||||
|
searchKeyword.value = ''
|
||||||
|
}
|
||||||
|
|
||||||
|
function clearSearch() {
|
||||||
|
searchKeyword.value = ''
|
||||||
|
}
|
||||||
|
|
||||||
function goTool(key: string) {
|
function goTool(key: string) {
|
||||||
uni.navigateTo({
|
uni.navigateTo({
|
||||||
url: `/pages/toolbox/query?key=${encodeURIComponent(key)}`,
|
url: `/pages/toolbox/query?key=${encodeURIComponent(key)}`,
|
||||||
@@ -37,9 +79,109 @@ function goTool(key: string) {
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<view class="page-root">
|
<view class="page-root">
|
||||||
|
<!-- 全部分类视图 -->
|
||||||
|
<template v-if="isAllCategories">
|
||||||
|
<!-- 搜索栏 -->
|
||||||
|
<view class="search-bar">
|
||||||
|
<view class="search-input-wrap">
|
||||||
|
<view class="search-icon i-carbon-search" />
|
||||||
|
<input
|
||||||
|
class="search-input"
|
||||||
|
type="text"
|
||||||
|
placeholder="搜索工具名称"
|
||||||
|
placeholder-class="search-placeholder"
|
||||||
|
:value="searchKeyword"
|
||||||
|
confirm-type="search"
|
||||||
|
@input="searchKeyword = $event.detail.value"
|
||||||
|
/>
|
||||||
|
<view v-if="isSearching" class="search-clear i-carbon-close-filled" @tap="clearSearch" />
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- Tab 栏(搜索时隐藏) -->
|
||||||
|
<view v-show="!isSearching" class="tab-bar-wrap">
|
||||||
|
<scroll-view scroll-x class="tab-scroll" :scroll-into-view="'tab-' + activeTab" :scroll-with-animation="true">
|
||||||
|
<view class="tab-bar">
|
||||||
|
<view
|
||||||
|
v-for="(cat, idx) in toolboxCategories"
|
||||||
|
:id="'tab-' + idx"
|
||||||
|
:key="cat.key"
|
||||||
|
class="tab-item"
|
||||||
|
:class="{ 'tab-item--active': activeTab === idx }"
|
||||||
|
@tap="switchTab(idx)"
|
||||||
|
>
|
||||||
|
<text class="tab-text" :class="{ 'tab-text--active': activeTab === idx }">{{ cat.name }}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</scroll-view>
|
||||||
|
<view class="tab-indicator-track">
|
||||||
|
<view
|
||||||
|
class="tab-indicator"
|
||||||
|
:style="{ width: `${100 / toolboxCategories.length}%`, transform: `translateX(${activeTab * 100}%)` }"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 搜索结果 / 工具网格 -->
|
||||||
|
<scroll-view scroll-y class="tool-scrollarea">
|
||||||
|
<view class="tool-grid-page">
|
||||||
|
<!-- 搜索结果视图 -->
|
||||||
|
<template v-if="isSearching">
|
||||||
|
<view v-if="searchResults.length === 0" class="search-empty">
|
||||||
|
<view class="search-empty-icon i-carbon-search" />
|
||||||
|
<text class="search-empty-text">未找到相关工具</text>
|
||||||
|
</view>
|
||||||
|
<template v-else>
|
||||||
|
<view class="grid-header">
|
||||||
|
<text class="grid-header-name">搜索结果</text>
|
||||||
|
<text class="grid-header-count">共 {{ searchResults.length }} 个</text>
|
||||||
|
</view>
|
||||||
|
<view class="tool-grid">
|
||||||
|
<view
|
||||||
|
v-for="item in searchResults"
|
||||||
|
:key="item.key"
|
||||||
|
class="tool-cell"
|
||||||
|
@tap="goTool(item.key)"
|
||||||
|
>
|
||||||
|
<view class="tool-cell-icon-wrap" style="background: #eef4ff">
|
||||||
|
<view :class="['tool-cell-icon', item.icon]" style="color: #1768ff" />
|
||||||
|
</view>
|
||||||
|
<text class="tool-cell-name">{{ item.name }}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 正常 Tab 工具网格 -->
|
||||||
|
<template v-else>
|
||||||
|
<view class="grid-header">
|
||||||
|
<view class="grid-header-dot" :style="{ background: activeCategory.color }" />
|
||||||
|
<text class="grid-header-name">{{ activeCategory.name }}</text>
|
||||||
|
<text class="grid-header-count">共 {{ activeTools.length }} 个</text>
|
||||||
|
</view>
|
||||||
|
<view class="tool-grid">
|
||||||
|
<view
|
||||||
|
v-for="item in activeTools"
|
||||||
|
:key="item.key"
|
||||||
|
class="tool-cell"
|
||||||
|
@tap="goTool(item.key)"
|
||||||
|
>
|
||||||
|
<view class="tool-cell-icon-wrap" :style="{ background: `${activeCategory.color}12` }">
|
||||||
|
<view :class="['tool-cell-icon', item.icon]" :style="{ color: activeCategory.color }" />
|
||||||
|
</view>
|
||||||
|
<text class="tool-cell-name">{{ item.name }}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
</view>
|
||||||
|
</scroll-view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 单分类视图 -->
|
||||||
|
<template v-else-if="category">
|
||||||
<scroll-view scroll-y class="scrollarea">
|
<scroll-view scroll-y class="scrollarea">
|
||||||
<view class="page">
|
<view class="page">
|
||||||
<view v-if="category" class="cat-header">
|
<view class="cat-header">
|
||||||
<view class="cat-icon-large" :style="{ background: `${category.color}15` }">
|
<view class="cat-icon-large" :style="{ background: `${category.color}15` }">
|
||||||
<view :class="['icon', category.icon]" :style="{ color: category.color }" />
|
<view :class="['icon', category.icon]" :style="{ color: category.color }" />
|
||||||
</view>
|
</view>
|
||||||
@@ -63,11 +205,11 @@ function goTool(key: string) {
|
|||||||
<text class="item-name">{{ item.name }}</text>
|
<text class="item-name">{{ item.name }}</text>
|
||||||
<text class="item-desc">{{ item.desc }}</text>
|
<text class="item-desc">{{ item.desc }}</text>
|
||||||
</view>
|
</view>
|
||||||
<!-- <text class="item-arrow"></text> -->
|
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</scroll-view>
|
</scroll-view>
|
||||||
|
</template>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -79,6 +221,204 @@ function goTool(key: string) {
|
|||||||
background: linear-gradient(180deg, #f8faff 0%, #f3f5fb 100%);
|
background: linear-gradient(180deg, #f8faff 0%, #f3f5fb 100%);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ============ 搜索栏 ============ */
|
||||||
|
.search-bar {
|
||||||
|
padding: 16rpx 24rpx 12rpx;
|
||||||
|
background: #fff;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-input-wrap {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
height: 72rpx;
|
||||||
|
background: #f5f6fa;
|
||||||
|
border-radius: 36rpx;
|
||||||
|
padding: 0 24rpx;
|
||||||
|
gap: 12rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-icon {
|
||||||
|
font-size: 30rpx;
|
||||||
|
color: #c0c4cc;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-input {
|
||||||
|
flex: 1;
|
||||||
|
font-size: 26rpx;
|
||||||
|
color: #1d2129;
|
||||||
|
height: 72rpx;
|
||||||
|
line-height: 72rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-placeholder {
|
||||||
|
color: #c0c4cc;
|
||||||
|
font-size: 26rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-clear {
|
||||||
|
font-size: 30rpx;
|
||||||
|
color: #c0c4cc;
|
||||||
|
flex-shrink: 0;
|
||||||
|
padding: 8rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-empty {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
padding: 120rpx 0 80rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-empty-icon {
|
||||||
|
font-size: 80rpx;
|
||||||
|
color: #dcdfe6;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-empty-text {
|
||||||
|
font-size: 26rpx;
|
||||||
|
color: #86909c;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ============ Tab 栏 ============ */
|
||||||
|
.tab-bar-wrap {
|
||||||
|
background: #fff;
|
||||||
|
flex-shrink: 0;
|
||||||
|
border-bottom: 1rpx solid #f0f1f5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-scroll {
|
||||||
|
width: 100%;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-bar {
|
||||||
|
display: flex;
|
||||||
|
height: 88rpx;
|
||||||
|
line-height: 88rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-item {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 0 8rpx;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-text {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #86909c;
|
||||||
|
transition: color 0.25s, font-weight 0.25s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-text--active {
|
||||||
|
color: #1d2129;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 下划线指示器 */
|
||||||
|
.tab-indicator-track {
|
||||||
|
height: 6rpx;
|
||||||
|
position: relative;
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-indicator {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
height: 6rpx;
|
||||||
|
border-radius: 3rpx;
|
||||||
|
background: #1768ff;
|
||||||
|
transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ============ 工具网格区域 ============ */
|
||||||
|
.tool-scrollarea {
|
||||||
|
flex: 1;
|
||||||
|
min-height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tool-grid-page {
|
||||||
|
padding: 24rpx 24rpx 40rpx;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10rpx;
|
||||||
|
margin-bottom: 24rpx;
|
||||||
|
padding: 0 4rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid-header-dot {
|
||||||
|
width: 12rpx;
|
||||||
|
height: 12rpx;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid-header-name {
|
||||||
|
font-size: 28rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #1d2129;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid-header-count {
|
||||||
|
font-size: 22rpx;
|
||||||
|
color: #86909c;
|
||||||
|
margin-left: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 4列网格 */
|
||||||
|
.tool-grid {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tool-cell {
|
||||||
|
width: 25%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
padding: 20rpx 4rpx;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tool-cell:active {
|
||||||
|
opacity: 0.7;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tool-cell-icon-wrap {
|
||||||
|
width: 80rpx;
|
||||||
|
height: 80rpx;
|
||||||
|
border-radius: 24rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
margin-bottom: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tool-cell-icon {
|
||||||
|
font-size: 38rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tool-cell-name {
|
||||||
|
font-size: 22rpx;
|
||||||
|
color: #333;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 1.3;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ============ 单分类详情 ============ */
|
||||||
.scrollarea {
|
.scrollarea {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
min-height: 0;
|
min-height: 0;
|
||||||
@@ -99,8 +439,7 @@ function goTool(key: string) {
|
|||||||
border-radius: 24rpx;
|
border-radius: 24rpx;
|
||||||
border: 1rpx solid #e5e6f0;
|
border: 1rpx solid #e5e6f0;
|
||||||
margin-bottom: 24rpx;
|
margin-bottom: 24rpx;
|
||||||
box-shadow:
|
box-shadow: 0 16rpx 40rpx rgba(15, 35, 52, 0.04),
|
||||||
0 16rpx 40rpx rgba(15, 35, 52, 0.04),
|
|
||||||
0 0 0 1rpx rgba(255, 255, 255, 0.5) inset;
|
0 0 0 1rpx rgba(255, 255, 255, 0.5) inset;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -140,8 +479,7 @@ function goTool(key: string) {
|
|||||||
border-radius: 24rpx;
|
border-radius: 24rpx;
|
||||||
border: 1rpx solid #e5e6f0;
|
border: 1rpx solid #e5e6f0;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
box-shadow:
|
box-shadow: 0 16rpx 40rpx rgba(15, 35, 52, 0.04),
|
||||||
0 16rpx 40rpx rgba(15, 35, 52, 0.04),
|
|
||||||
0 0 0 1rpx rgba(255, 255, 255, 0.5) inset;
|
0 0 0 1rpx rgba(255, 255, 255, 0.5) inset;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -196,10 +534,4 @@ function goTool(key: string) {
|
|||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.item-arrow {
|
|
||||||
font-size: 24rpx;
|
|
||||||
color: #c9cdd4;
|
|
||||||
flex-shrink: 0;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,69 +1,186 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { toolboxCategories, getCategoryHotTools } from '@/config/toolboxRegistry'
|
import { ref, computed } from 'vue'
|
||||||
|
import { toolboxCategories, getCategoryAllTools } from '@/config/toolboxRegistry'
|
||||||
|
import { getInquireCategoryConfig, getInquiryItemIconUrl } from '@/config/inquireCategories'
|
||||||
|
|
||||||
definePage({
|
definePage({
|
||||||
style: {
|
style: {
|
||||||
navigationBarTitleText: '实用工具',
|
navigationBarTitleText: '工具分类',
|
||||||
navigationStyle: 'default',
|
navigationStyle: 'default',
|
||||||
navigationBarBackgroundColor: '#ffffff',
|
navigationBarBackgroundColor: '#ffffff',
|
||||||
navigationBarTextStyle: 'black',
|
navigationBarTextStyle: 'black',
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
function goTool(key: string) {
|
const vehicleItems = computed(() => getInquireCategoryConfig('vehicle')?.items ?? [])
|
||||||
uni.navigateTo({
|
|
||||||
url: `/pages/toolbox/query?key=${encodeURIComponent(key)}`,
|
/** 左侧分类列表:热门推荐 + 车辆查询 + 所有工具分类 */
|
||||||
|
const sidebarItems = computed(() => [
|
||||||
|
{ key: 'hot', name: '热门推荐', icon: '', color: '#ff6b6b' },
|
||||||
|
{ key: 'vehicle', name: '车辆查询', icon: 'i-carbon-car', color: '#1768ff' },
|
||||||
|
...toolboxCategories.map(cat => ({
|
||||||
|
key: cat.key,
|
||||||
|
name: cat.name,
|
||||||
|
icon: cat.icon,
|
||||||
|
color: cat.color,
|
||||||
|
})),
|
||||||
|
])
|
||||||
|
|
||||||
|
const activeKey = ref('hot')
|
||||||
|
|
||||||
|
/** 当前选中分类的数据(仅工具分类有) */
|
||||||
|
const activeCategory = computed(() => {
|
||||||
|
if (activeKey.value === 'hot' || activeKey.value === 'vehicle') return null
|
||||||
|
return toolboxCategories.find(c => c.key === activeKey.value) || null
|
||||||
})
|
})
|
||||||
|
|
||||||
|
/** 当前分类的工具列表 */
|
||||||
|
const activeTools = computed(() => {
|
||||||
|
if (activeKey.value === 'hot' || activeKey.value === 'vehicle') return []
|
||||||
|
return getCategoryAllTools(activeKey.value)
|
||||||
|
})
|
||||||
|
|
||||||
|
/** 热门推荐的分类卡片:车辆查询 + 所有工具分类 */
|
||||||
|
const hotCategoryCards = computed(() => [
|
||||||
|
{ key: 'vehicle', name: '车辆查询', icon: 'i-carbon-car', color: '#1768ff', count: vehicleItems.value.length, previews: [] },
|
||||||
|
...toolboxCategories.map(cat => ({
|
||||||
|
key: cat.key,
|
||||||
|
name: cat.name,
|
||||||
|
icon: cat.icon,
|
||||||
|
color: cat.color,
|
||||||
|
count: getCategoryAllTools(cat.key).length,
|
||||||
|
previews: getCategoryAllTools(cat.key).slice(0, 4),
|
||||||
|
})),
|
||||||
|
])
|
||||||
|
|
||||||
|
function switchCategory(key: string) {
|
||||||
|
activeKey.value = key
|
||||||
}
|
}
|
||||||
|
|
||||||
function goCategory(categoryKey: string) {
|
function goTool(key: string) {
|
||||||
uni.navigateTo({
|
uni.navigateTo({ url: `/pages/toolbox/query?key=${encodeURIComponent(key)}` })
|
||||||
url: `/pages/toolbox/category?category=${encodeURIComponent(categoryKey)}`,
|
}
|
||||||
})
|
|
||||||
|
function goInquireFeature(feature: string) {
|
||||||
|
uni.navigateTo({ url: `/pages/inquire/index?feature=${encodeURIComponent(feature)}` })
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<view class="page-root">
|
<view class="page-root">
|
||||||
<scroll-view scroll-y class="scrollarea">
|
<view class="layout">
|
||||||
<view class="page">
|
<!-- 左侧分类导航 -->
|
||||||
|
<scroll-view scroll-y class="sidebar">
|
||||||
<view
|
<view
|
||||||
v-for="cat in toolboxCategories"
|
v-for="item in sidebarItems"
|
||||||
:key="cat.key"
|
:key="item.key"
|
||||||
class="card"
|
class="sidebar-item"
|
||||||
|
:class="{ 'sidebar-item--active': activeKey === item.key }"
|
||||||
|
@tap="switchCategory(item.key)"
|
||||||
>
|
>
|
||||||
<!-- 分类标题 -->
|
<view v-if="activeKey === item.key" class="sidebar-indicator" />
|
||||||
<view class="card-header" @tap="goCategory(cat.key)">
|
<text class="sidebar-text" :class="{ 'sidebar-text--active': activeKey === item.key }">{{ item.name }}</text>
|
||||||
<view class="card-header-left">
|
|
||||||
<view class="cat-icon-wrap" :style="{ background: `${cat.color}15` }">
|
|
||||||
<view :class="['cat-icon', cat.icon]" :style="{ color: cat.color }" />
|
|
||||||
</view>
|
|
||||||
<text class="card-title">{{ cat.name }}</text>
|
|
||||||
</view>
|
|
||||||
<view class="card-more">
|
|
||||||
<text class="more-text">查看更多</text>
|
|
||||||
<!-- <text class="more-arrow">></text> -->
|
|
||||||
</view>
|
|
||||||
</view>
|
</view>
|
||||||
|
</scroll-view>
|
||||||
|
|
||||||
<!-- 热门工具网格 -->
|
<!-- 右侧内容区 -->
|
||||||
|
<scroll-view scroll-y class="content" :scroll-top="0">
|
||||||
|
<!-- 热门推荐:分类卡片网格 -->
|
||||||
|
<template v-if="activeKey === 'hot'">
|
||||||
|
<view class="content-header">
|
||||||
|
<view class="content-icon-wrap" style="background: rgba(255,107,107,0.1)">
|
||||||
|
<view class="content-icon i-carbon-grid" style="color: #ff6b6b" />
|
||||||
|
</view>
|
||||||
|
<view class="content-info">
|
||||||
|
<text class="content-title">热门推荐</text>
|
||||||
|
<text class="content-count">全部分类入口</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="cat-grid">
|
||||||
|
<view
|
||||||
|
v-for="card in hotCategoryCards"
|
||||||
|
:key="card.key"
|
||||||
|
class="cat-card"
|
||||||
|
@tap="switchCategory(card.key)"
|
||||||
|
>
|
||||||
|
<!-- 车辆查询用单图标 -->
|
||||||
|
<view v-if="card.key === 'vehicle'" class="cat-card-single-icon" :style="{ background: `${card.color}12` }">
|
||||||
|
<view :class="card.icon" :style="{ color: card.color, fontSize: '28rpx' }" />
|
||||||
|
</view>
|
||||||
|
<!-- 工具分类用四宫格 -->
|
||||||
|
<view v-else class="cat-card-grid-icon" :style="{ background: `${card.color}10` }">
|
||||||
|
<view
|
||||||
|
v-for="(preview, pIdx) in card.previews"
|
||||||
|
:key="preview.key"
|
||||||
|
class="mini-icon-cell"
|
||||||
|
>
|
||||||
|
<view :class="[preview.icon, 'mini-icon']" :style="{ color: card.color }" />
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="cat-card-text">
|
||||||
|
<text class="cat-card-name">{{ card.name }}</text>
|
||||||
|
<text class="cat-card-count">{{ card.count }}个</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 车辆查询 -->
|
||||||
|
<template v-else-if="activeKey === 'vehicle'">
|
||||||
|
<view class="content-header">
|
||||||
|
<view class="content-icon-wrap" style="background: rgba(23,104,255,0.1)">
|
||||||
|
<view class="content-icon i-carbon-car" style="color: #1768ff" />
|
||||||
|
</view>
|
||||||
|
<view class="content-info">
|
||||||
|
<text class="content-title">车辆查询服务</text>
|
||||||
|
<text class="content-count">{{ vehicleItems.length }} 项专业车况核验</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
<view class="tool-grid">
|
<view class="tool-grid">
|
||||||
<view
|
<view
|
||||||
v-for="item in getCategoryHotTools(cat.key)"
|
v-for="item in vehicleItems"
|
||||||
:key="item.key"
|
:key="item.feature"
|
||||||
class="tool-cell"
|
class="tool-cell"
|
||||||
@tap="goTool(item.key)"
|
@tap="goInquireFeature(item.feature)"
|
||||||
>
|
>
|
||||||
<view class="tool-icon-wrap" :style="{ background: `${cat.color}12` }">
|
<view class="tool-icon-wrap" style="background: rgba(23,104,255,0.08)">
|
||||||
<view :class="['tool-icon', item.icon]" :style="{ color: cat.color }" />
|
<image class="tool-icon-img" :src="getInquiryItemIconUrl(item)" mode="aspectFit" />
|
||||||
</view>
|
</view>
|
||||||
<text class="tool-name">{{ item.name }}</text>
|
<text class="tool-name">{{ item.name }}</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 工具分类 -->
|
||||||
|
<template v-else-if="activeCategory">
|
||||||
|
<view class="content-header">
|
||||||
|
<view class="content-icon-wrap" :style="{ background: `${activeCategory.color}15` }">
|
||||||
|
<view :class="['content-icon', activeCategory.icon]" :style="{ color: activeCategory.color }" />
|
||||||
|
</view>
|
||||||
|
<view class="content-info">
|
||||||
|
<text class="content-title">{{ activeCategory.name }}</text>
|
||||||
|
<text class="content-count">{{ activeTools.length }} 个工具</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
<view class="tool-grid">
|
||||||
|
<view
|
||||||
|
v-for="item in activeTools"
|
||||||
|
:key="item.key"
|
||||||
|
class="tool-cell"
|
||||||
|
@tap="goTool(item.key)"
|
||||||
|
>
|
||||||
|
<view class="tool-icon-wrap" :style="{ background: `${activeCategory.color}12` }">
|
||||||
|
<view :class="['tool-icon-grid', item.icon]" :style="{ color: activeCategory.color }" />
|
||||||
|
</view>
|
||||||
|
<text class="tool-name">{{ item.name }}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<view style="height: 32rpx" />
|
||||||
</scroll-view>
|
</scroll-view>
|
||||||
</view>
|
</view>
|
||||||
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@@ -71,101 +188,201 @@ function goCategory(categoryKey: string) {
|
|||||||
height: 100vh;
|
height: 100vh;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
background: linear-gradient(180deg, #f8faff 0%, #f3f5fb 100%);
|
background: #f5f6fa;
|
||||||
}
|
}
|
||||||
|
|
||||||
.scrollarea {
|
/* ============ 双栏布局 ============ */
|
||||||
|
.layout {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
min-height: 0;
|
|
||||||
height: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.page {
|
|
||||||
padding: 24rpx 24rpx 40rpx;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
.card {
|
|
||||||
background: linear-gradient(145deg, #ffffff 0%, #f7f8ff 100%);
|
|
||||||
border-radius: 24rpx;
|
|
||||||
padding: 24rpx 24rpx 20rpx;
|
|
||||||
margin-bottom: 24rpx;
|
|
||||||
border: 1rpx solid #e5e6f0;
|
|
||||||
box-shadow:
|
|
||||||
0 16rpx 40rpx rgba(15, 35, 52, 0.04),
|
|
||||||
0 0 0 1rpx rgba(255, 255, 255, 0.5) inset;
|
|
||||||
}
|
|
||||||
|
|
||||||
.card-header {
|
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
min-height: 0;
|
||||||
align-items: center;
|
|
||||||
margin-bottom: 20rpx;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.card-header-left {
|
/* 左侧分类导航 */
|
||||||
|
.sidebar {
|
||||||
|
width: 180rpx;
|
||||||
|
height: 100%;
|
||||||
|
background: #f0f1f5;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-item {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
height: 104rpx;
|
||||||
|
padding: 0 8rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-item:active {
|
||||||
|
background: #e8e9ed;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-item--active {
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-indicator {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 50%;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
width: 8rpx;
|
||||||
|
height: 40rpx;
|
||||||
|
border-radius: 0 4rpx 4rpx 0;
|
||||||
|
background: #1768ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-text {
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #86909c;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 1.3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-text--active {
|
||||||
|
color: #1d2129;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 右侧内容区 */
|
||||||
|
.content {
|
||||||
|
flex: 1;
|
||||||
|
height: 100%;
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-header {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 16rpx;
|
gap: 16rpx;
|
||||||
|
padding: 28rpx 28rpx 16rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.cat-icon-wrap {
|
.content-icon-wrap {
|
||||||
width: 56rpx;
|
width: 52rpx;
|
||||||
height: 56rpx;
|
height: 52rpx;
|
||||||
|
border-radius: 14rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-icon {
|
||||||
|
font-size: 28rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-info {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-title {
|
||||||
|
display: block;
|
||||||
|
font-size: 28rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #1d2129;
|
||||||
|
margin-bottom: 4rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-count {
|
||||||
|
display: block;
|
||||||
|
font-size: 20rpx;
|
||||||
|
color: #86909c;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ============ 热门推荐:分类卡片网格 ============ */
|
||||||
|
.cat-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(2, 1fr);
|
||||||
|
gap: 14rpx;
|
||||||
|
padding: 8rpx 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cat-card {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
gap: 14rpx;
|
||||||
|
padding: 20rpx 16rpx;
|
||||||
border-radius: 16rpx;
|
border-radius: 16rpx;
|
||||||
|
background: #f7f8fa;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cat-card:active {
|
||||||
|
background: #eef1f5;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 车辆查询单图标 */
|
||||||
|
.cat-card-single-icon {
|
||||||
|
width: 48rpx;
|
||||||
|
height: 48rpx;
|
||||||
|
border-radius: 12rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 四宫格图标 */
|
||||||
|
.cat-card-grid-icon {
|
||||||
|
width: 48rpx;
|
||||||
|
height: 48rpx;
|
||||||
|
border-radius: 12rpx;
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
grid-template-rows: 1fr 1fr;
|
||||||
|
overflow: hidden;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mini-icon-cell {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.cat-icon {
|
.mini-icon {
|
||||||
font-size: 32rpx;
|
font-size: 16rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.card-title {
|
.cat-card-text {
|
||||||
font-size: 30rpx;
|
flex: 1;
|
||||||
font-weight: 600;
|
min-width: 0;
|
||||||
color: #1d2129;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.card-more {
|
.cat-card-name {
|
||||||
display: flex;
|
display: block;
|
||||||
align-items: center;
|
|
||||||
gap: 4rpx;
|
|
||||||
padding: 8rpx 16rpx;
|
|
||||||
border-radius: 20rpx;
|
|
||||||
background: #f2f3f5;
|
|
||||||
}
|
|
||||||
|
|
||||||
.more-text {
|
|
||||||
font-size: 22rpx;
|
font-size: 22rpx;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #1d2129;
|
||||||
|
margin-bottom: 2rpx;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cat-card-count {
|
||||||
|
display: block;
|
||||||
|
font-size: 18rpx;
|
||||||
color: #86909c;
|
color: #86909c;
|
||||||
}
|
}
|
||||||
|
|
||||||
.more-arrow {
|
/* ============ 工具网格 ============ */
|
||||||
font-size: 22rpx;
|
|
||||||
color: #c9cdd4;
|
|
||||||
}
|
|
||||||
|
|
||||||
.card-more:active {
|
|
||||||
opacity: 0.7;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tool-grid {
|
.tool-grid {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
margin: 0 -6rpx;
|
padding: 0 16rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tool-cell {
|
.tool-cell {
|
||||||
width: 33.333%;
|
width: 25%;
|
||||||
padding: 6rpx;
|
|
||||||
box-sizing: border-box;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding-top: 12rpx;
|
padding: 16rpx 0;
|
||||||
padding-bottom: 12rpx;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tool-cell:active {
|
.tool-cell:active {
|
||||||
@@ -173,27 +390,33 @@ function goCategory(categoryKey: string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.tool-icon-wrap {
|
.tool-icon-wrap {
|
||||||
width: 76rpx;
|
width: 68rpx;
|
||||||
height: 76rpx;
|
height: 68rpx;
|
||||||
border-radius: 20rpx;
|
border-radius: 18rpx;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
margin-bottom: 10rpx;
|
margin-bottom: 8rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tool-icon {
|
.tool-icon-grid {
|
||||||
font-size: 36rpx;
|
font-size: 34rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tool-icon-img {
|
||||||
|
width: 38rpx;
|
||||||
|
height: 38rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tool-name {
|
.tool-name {
|
||||||
font-size: 24rpx;
|
font-size: 20rpx;
|
||||||
font-weight: 500;
|
color: #333;
|
||||||
color: #1d2129;
|
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
line-height: 1.3;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
padding: 0 4rpx;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -253,6 +253,14 @@ async function handleQuery() {
|
|||||||
if (toolKey.value === 'idiom-quiz' || toolKey.value === 'poem-fill') {
|
if (toolKey.value === 'idiom-quiz' || toolKey.value === 'poem-fill') {
|
||||||
prepareGameOptions()
|
prepareGameOptions()
|
||||||
}
|
}
|
||||||
|
// 百科题库:准备选项
|
||||||
|
if (toolKey.value === 'baiketiku') {
|
||||||
|
prepareBaiKeOptions()
|
||||||
|
}
|
||||||
|
// 垃圾分类问答:准备选项
|
||||||
|
if (toolKey.value === 'anslajifenlei') {
|
||||||
|
prepareGarbageOptions()
|
||||||
|
}
|
||||||
// 成语接龙:记录系统返回的成语
|
// 成语接龙:记录系统返回的成语
|
||||||
if (toolKey.value === 'chengyujielong') {
|
if (toolKey.value === 'chengyujielong') {
|
||||||
if (result.value?.word) {
|
if (result.value?.word) {
|
||||||
@@ -354,6 +362,59 @@ const prepareGameOptions = () => {
|
|||||||
answered.value = false
|
answered.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 百科题库:准备选项(A/B/C/D 四个选项,标记正确答案)
|
||||||
|
const prepareBaiKeOptions = () => {
|
||||||
|
if (!result.value)
|
||||||
|
return
|
||||||
|
|
||||||
|
// answer 可能是选项字母标识(如 "A"),也可能是选项文本内容
|
||||||
|
const correctAnswer = String(result.value.answer || '').trim()
|
||||||
|
const optionKeys = ['answerA', 'answerB', 'answerC', 'answerD'] as const
|
||||||
|
const optionLabels = ['A', 'B', 'C', 'D'] as const
|
||||||
|
const options = optionKeys
|
||||||
|
.map((key, i) => {
|
||||||
|
const val = String(result.value[key] || '').trim()
|
||||||
|
if (!val) return null
|
||||||
|
// answer 可能是字母标识 "A"/"B"/...,也可能是选项文本本身
|
||||||
|
const isCorrect = correctAnswer === optionLabels[i] || correctAnswer === val
|
||||||
|
return { label: `${optionLabels[i]}. ${val}`, value: val, isCorrect }
|
||||||
|
})
|
||||||
|
.filter(Boolean) as Array<{ label: string; value: string; isCorrect: boolean }>
|
||||||
|
|
||||||
|
gameOptions.value = options
|
||||||
|
selectedOption.value = null
|
||||||
|
answered.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
// 垃圾分类问答:准备选项(四个分类,标记正确答案)
|
||||||
|
const prepareGarbageOptions = () => {
|
||||||
|
if (!result.value)
|
||||||
|
return
|
||||||
|
|
||||||
|
const correctType = result.value.type
|
||||||
|
const typeNames: Record<number, string> = {
|
||||||
|
0: '可回收物',
|
||||||
|
1: '有害垃圾',
|
||||||
|
2: '厨余垃圾',
|
||||||
|
3: '其他垃圾',
|
||||||
|
}
|
||||||
|
const options = Object.entries(typeNames).map(([typeKey, typeName]) => ({
|
||||||
|
label: typeName,
|
||||||
|
value: typeName,
|
||||||
|
isCorrect: Number(typeKey) === Number(correctType),
|
||||||
|
}))
|
||||||
|
|
||||||
|
// 打乱顺序
|
||||||
|
for (let i = options.length - 1; i > 0; i--) {
|
||||||
|
const j = Math.floor(Math.random() * (i + 1))
|
||||||
|
;[options[i], options[j]] = [options[j], options[i]]
|
||||||
|
}
|
||||||
|
|
||||||
|
gameOptions.value = options
|
||||||
|
selectedOption.value = null
|
||||||
|
answered.value = false
|
||||||
|
}
|
||||||
|
|
||||||
// 点击选项
|
// 点击选项
|
||||||
function handleOptionClick(option: { label: string; value: string; isCorrect: boolean }) {
|
function handleOptionClick(option: { label: string; value: string; isCorrect: boolean }) {
|
||||||
if (answered.value)
|
if (answered.value)
|
||||||
@@ -538,11 +599,15 @@ function handleRestart() {
|
|||||||
|
|
||||||
<!-- 题目 -->
|
<!-- 题目 -->
|
||||||
<view class="game-question">
|
<view class="game-question">
|
||||||
<text class="game-question-text">{{ result.question }}</text>
|
<text v-if="toolKey === 'anslajifenlei'" class="game-question-text game-question-garbage">
|
||||||
|
<text class="garbage-name">{{ result.name }}</text>
|
||||||
|
<text class="garbage-prompt">属于什么垃圾?</text>
|
||||||
|
</text>
|
||||||
|
<text v-else class="game-question-text">{{ result.title || result.question }}</text>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 选项按钮 -->
|
<!-- 选项按钮 -->
|
||||||
<view class="game-options">
|
<view class="game-options" :class="{ 'game-options-col': toolKey === 'anslajifenlei' }">
|
||||||
<view
|
<view
|
||||||
v-for="(option, index) in gameOptions"
|
v-for="(option, index) in gameOptions"
|
||||||
:key="index"
|
:key="index"
|
||||||
@@ -551,6 +616,10 @@ function handleRestart() {
|
|||||||
'game-option-selected': selectedOption === option.value,
|
'game-option-selected': selectedOption === option.value,
|
||||||
'game-option-correct': answered && option.isCorrect,
|
'game-option-correct': answered && option.isCorrect,
|
||||||
'game-option-wrong': answered && selectedOption === option.value && !option.isCorrect,
|
'game-option-wrong': answered && selectedOption === option.value && !option.isCorrect,
|
||||||
|
'game-option-recyclable': toolKey === 'anslajifenlei' && option.value === '可回收物',
|
||||||
|
'game-option-hazardous': toolKey === 'anslajifenlei' && option.value === '有害垃圾',
|
||||||
|
'game-option-kitchen': toolKey === 'anslajifenlei' && option.value === '厨余垃圾',
|
||||||
|
'game-option-other': toolKey === 'anslajifenlei' && option.value === '其他垃圾',
|
||||||
}"
|
}"
|
||||||
@tap="handleOptionClick(option)"
|
@tap="handleOptionClick(option)"
|
||||||
>
|
>
|
||||||
@@ -610,6 +679,30 @@ function handleRestart() {
|
|||||||
<text class="game-explan-value">{{ result.note }}</text>
|
<text class="game-explan-value">{{ result.note }}</text>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<!-- 百科题库:显示正确答案和解析 -->
|
||||||
|
<template v-else-if="toolKey === 'baiketiku'">
|
||||||
|
<view class="game-answer">
|
||||||
|
<text class="game-answer-label">正确答案:</text>
|
||||||
|
<text class="game-answer-value">{{ result.answer }}</text>
|
||||||
|
</view>
|
||||||
|
<view v-if="result.analytic" class="game-explan">
|
||||||
|
<text class="game-explan-label">解析:</text>
|
||||||
|
<text class="game-explan-value">{{ result.analytic }}</text>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 垃圾分类问答:显示正确分类 -->
|
||||||
|
<template v-else-if="toolKey === 'anslajifenlei'">
|
||||||
|
<view class="game-answer">
|
||||||
|
<text class="game-answer-label">正确分类:</text>
|
||||||
|
<text class="game-answer-value garbage-answer-type">{{ result.type_name }}</text>
|
||||||
|
</view>
|
||||||
|
<view v-if="result.explain" class="game-explan">
|
||||||
|
<text class="game-explan-label">说明:</text>
|
||||||
|
<text class="game-explan-value">{{ result.explain }}</text>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -1473,4 +1566,50 @@ function handleRestart() {
|
|||||||
.chain-empty-text {
|
.chain-empty-text {
|
||||||
font-size: 24rpx;
|
font-size: 24rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 垃圾分类游戏样式 */
|
||||||
|
.game-question-garbage {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 16rpx;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.garbage-name {
|
||||||
|
font-size: 56rpx;
|
||||||
|
font-weight: 700;
|
||||||
|
color: #1d2129;
|
||||||
|
}
|
||||||
|
|
||||||
|
.garbage-prompt {
|
||||||
|
font-size: 30rpx;
|
||||||
|
color: #86909c;
|
||||||
|
font-weight: 400;
|
||||||
|
}
|
||||||
|
|
||||||
|
.garbage-answer-type {
|
||||||
|
color: #00b42a;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 垃圾分类选项布局 - 单列 */
|
||||||
|
.game-options-col {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 垃圾分类四个类别的默认色 */
|
||||||
|
.game-option-recyclable {
|
||||||
|
border-left: 6rpx solid #1768ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.game-option-hazardous {
|
||||||
|
border-left: 6rpx solid #f53f3f;
|
||||||
|
}
|
||||||
|
|
||||||
|
.game-option-kitchen {
|
||||||
|
border-left: 6rpx solid #00b42a;
|
||||||
|
}
|
||||||
|
|
||||||
|
.game-option-other {
|
||||||
|
border-left: 6rpx solid #86909c;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
BIN
src/static/tabbar/toolbox-active.png
Normal file
BIN
src/static/tabbar/toolbox-active.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 468 B |
BIN
src/static/tabbar/toolbox.png
Normal file
BIN
src/static/tabbar/toolbox.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 464 B |
3
uni-pages.d.ts
vendored
3
uni-pages.d.ts
vendored
@@ -10,6 +10,7 @@ type _LocationUrl =
|
|||||||
"/pages/report" |
|
"/pages/report" |
|
||||||
"/pages/inquire/example" |
|
"/pages/inquire/example" |
|
||||||
"/pages/inquire/index" |
|
"/pages/inquire/index" |
|
||||||
|
"/pages/inquire/list" |
|
||||||
"/pages/legal/authorization" |
|
"/pages/legal/authorization" |
|
||||||
"/pages/legal/privacy-policy" |
|
"/pages/legal/privacy-policy" |
|
||||||
"/pages/legal/user-agreement" |
|
"/pages/legal/user-agreement" |
|
||||||
@@ -24,7 +25,7 @@ interface NavigateToOptions {
|
|||||||
interface RedirectToOptions extends NavigateToOptions {}
|
interface RedirectToOptions extends NavigateToOptions {}
|
||||||
|
|
||||||
interface SwitchTabOptions {
|
interface SwitchTabOptions {
|
||||||
url: "/pages/index" | "/pages/report" | "/pages/mine"
|
url: "/pages/index" | "/pages/toolbox/index" | "/pages/mine"
|
||||||
}
|
}
|
||||||
|
|
||||||
type ReLaunchOptions = NavigateToOptions | SwitchTabOptions;
|
type ReLaunchOptions = NavigateToOptions | SwitchTabOptions;
|
||||||
|
|||||||
Reference in New Issue
Block a user