feat: add discovery tool cards, refactor AiTabSwitch and update client configs

- Update xiaoqi client configuration: adjust clientId, sync appid across config files and switch to production build by setting developVersion to false
- Refactor AiTabSwitch component to use background images instead of inline image tags, clean up redundant SCSS styles and replace tab icon assets
- Add three new Discovery page tool components: audio guide, map guide and photo generator cards
- Clean up unused code in Discovery page and ChatMainList component, remove unused scroll view and computed property
- Fix regex pattern and formatting issues in update-appid.js script
- Comment out unused SpriteAnimator component in ChatMainList
This commit is contained in:
duanshuwen
2026-07-06 20:51:45 +08:00
parent 190793b156
commit aa07286010
18 changed files with 1013 additions and 326 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 7.9 KiB

View File

@@ -1,51 +1,23 @@
<template>
<view class="ai-tab-wrapper">
<view class="tab-container">
<view
class="tab-item is-left"
:class="{ active: modelValue === 0 }"
@tap="handleSwitch(0)"
>
<view class="tab-content">
<image
v-if="leftSelected || leftUnselected"
:src="modelValue === 0 ? (leftSelected || leftUnselected) : (leftUnselected || leftSelected)"
class="tab-image"
mode="scaleToFill"
/>
<view class="tab-label">
<text class="tab-text">探索发现</text>
</view>
</view>
<view class="tab-item is-left" :class="{ active: modelValue === 0 }" :style="leftBackgroundStyle"
@tap="handleSwitch(0)">
<text class="tab-text">探索发现</text>
</view>
<view
class="tab-item is-right"
:class="{ active: modelValue === 1 }"
@tap="handleSwitch(1)"
>
<view class="tab-content">
<image
v-if="rightSelected || rightUnselected"
:src="modelValue === 1 ? (rightSelected || rightUnselected) : (rightUnselected || rightSelected)"
class="tab-image"
mode="scaleToFill"
/>
<view class="tab-label">
<text class="tab-text">AI伴游</text>
<view
v-if="showDot"
:class="['status-dot', modelValue === 1 ? 'status-dot--active' : 'status-dot--inactive']"
></view>
</view>
</view>
<view class="tab-item is-right" :class="{ active: modelValue === 1 }" :style="rightBackgroundStyle"
@tap="handleSwitch(1)">
<text class="tab-text">AI伴游</text>
<text v-if="showDot"
:class="['status-dot', modelValue === 1 ? 'status-dot--active' : 'status-dot--inactive']" />
</view>
</view>
</view>
</template>
<script setup>
import { computed } from "vue";
import leftSelected from "./images/L_02.png";
import leftUnselected from "./images/L_01.png";
import rightSelected from "./images/R_02.png";
@@ -55,11 +27,30 @@ const props = defineProps({
modelValue: { type: Number, default: 0 },
showDot: { type: Boolean, default: true },
});
const emit = defineEmits(["update:modelValue", "change"]);
const handleSwitch = (i) => {
emit("update:modelValue", i);
emit("change", i);
const getBackgroundStyle = (selectedImage, unselectedImage, active) => {
const image = active
? (selectedImage || unselectedImage)
: (unselectedImage || selectedImage);
return {
backgroundImage: image ? `url(${image})` : "none",
};
};
const leftBackgroundStyle = computed(() =>
getBackgroundStyle(leftSelected, leftUnselected, props.modelValue === 0)
);
const rightBackgroundStyle = computed(() =>
getBackgroundStyle(rightSelected, rightUnselected, props.modelValue === 1)
);
const handleSwitch = (index) => {
emit("update:modelValue", index);
emit("change", index);
};
</script>

View File

@@ -7,89 +7,47 @@
width: 100%;
height: 50px;
display: flex;
gap: 40px;
overflow: hidden;
}
.tab-item {
position: relative;
flex: 1;
height: 50px;
display: flex;
align-items: center;
justify-content: center;
background-position: center;
background-repeat: no-repeat;
background-size: 100% 100%;
transition: all 0.3s ease;
}
.tab-item.active {
z-index: 10;
}
.tab-content {
position: absolute;
inset: 0;
display: flex;
align-items: center;
justify-content: center;
line-height: 0;
transition: background 0.3s;
overflow: hidden;
}
.tab-text {
display: block;
font-size: 18px;
font-weight: 500;
color: rgba(255, 255, 255, 0.65);
}
.tab-image {
position: absolute;
left: 0;
right: 0;
top: auto;
bottom: 0;
width: 100%;
height: 48px;
display: block;
vertical-align: bottom;
z-index: 5;
}
.tab-label {
display: flex;
align-items: center;
justify-content: center;
position: relative;
z-index: 20;
}
.tab-item.active .tab-text {
color: #2e312f;
font-weight: bold;
}
.is-left {
margin-right: -24px;
}
.is-left .tab-label {
.is-left .tab-text {
transform: translateX(-20px);
}
.is-right {
margin-left: -24px;
}
.is-right .tab-label {
.is-right .tab-text {
transform: translateX(20px);
}
.status-dot {
display: inline-block;
margin-left: 6px;
margin-left: 26px;
width: 6px;
height: 6px;
border-radius: 50%;
z-index: 22;
transform: translateY(-1px);
}