功能、UI更新

This commit is contained in:
李琦
2026-10-09 13:11:28 +08:00
parent 8694fde44a
commit 4e87103099
73 changed files with 200 additions and 160 deletions

View File

@@ -16,7 +16,7 @@ import VipCard from '@/components/vip/VipCard.vue'
import type { ProjectItem } from '@/api/project'
import { apiProjectMine } from '@/api/project'
import { CARD_TONES } from '@/config/card-styles'
import { FEATURE_ENTRIES, type FeatureEntry } from '@/config/features'
import { FEATURE_ENTRIES_HOME, type FeatureEntry } from '@/config/features'
import { TOOL_REGISTRY } from '@/config/tools'
import { useCardStyleStore } from '@/stores/cardStyle'
import { useMessageStore } from '@/stores/message'
@@ -169,7 +169,7 @@ function goFeature(path: string) {
const covers = ref<Record<string, string>>({})
const featsMode = computed(() =>
FEATURE_ENTRIES.length >= 4 ? 'scroll' : FEATURE_ENTRIES.length === 3 ? 'mosaic' : 'grid',
FEATURE_ENTRIES_HOME.length >= 4 ? 'scroll' : FEATURE_ENTRIES_HOME.length === 3 ? 'mosaic' : 'grid',
)
/** 功能卡背景图(绝对 URL;空 = 未配置) */
@@ -210,7 +210,7 @@ function toolCard(key: string, section: string) {
function featureCard(key: string, section: string) {
const s = cardStyle.styleOf(`feature.${key}`, section)
const hasTone = !!cardStyle.explicitOf(`feature.${key}`, section).tone
const fallback = FEATURE_ENTRIES.find(f => f.key === key)?.tone
const fallback = FEATURE_ENTRIES_HOME.find(f => f.key === key)?.tone
return { ...s, tone: hasTone ? s.tone : (fallback || s.tone) }
}
@@ -336,7 +336,7 @@ function leadCard(key: string) {
<!-- ≤2 张:双列 CardTile(原排版) -->
<view v-if="featsMode === 'grid'" class="feats">
<view
v-for="fe in FEATURE_ENTRIES"
v-for="fe in FEATURE_ENTRIES_HOME"
:key="fe.key"
class="cttap press"
hover-class="press-active"
@@ -358,23 +358,23 @@ function leadCard(key: string) {
<view
class="fm__main press"
hover-class="press-active"
@tap="goFeature(FEATURE_ENTRIES[0].path)"
@tap="goFeature(FEATURE_ENTRIES_HOME[0].path)"
>
<image
v-if="coverOf(FEATURE_ENTRIES[0])"
v-if="coverOf(FEATURE_ENTRIES_HOME[0])"
class="fm__bg"
:src="coverOf(FEATURE_ENTRIES[0])"
:src="coverOf(FEATURE_ENTRIES_HOME[0])"
mode="aspectFill"
/>
<view v-else class="fm__bg" :style="fallbackStyle(FEATURE_ENTRIES[0])" />
<view v-else class="fm__bg" :style="fallbackStyle(FEATURE_ENTRIES_HOME[0])" />
<view class="fm__shade" />
<view class="fm__body">
<text class="fm__title">
{{ FEATURE_ENTRIES[0].name }}
{{ FEATURE_ENTRIES_HOME[0].name }}
</text>
<view class="fm__pill">
<text class="fm__pill-text">
{{ FEATURE_ENTRIES[0].desc }}
{{ FEATURE_ENTRIES_HOME[0].desc }}
</text>
<wd-icon name="arrow-right" size="20rpx" color="#E8531A" />
</view>
@@ -382,7 +382,7 @@ function leadCard(key: string) {
</view>
<view class="fm__side">
<view
v-for="fe in FEATURE_ENTRIES.slice(1)"
v-for="fe in FEATURE_ENTRIES_HOME.slice(1)"
:key="fe.key"
class="fm__sub press"
hover-class="press-active"
@@ -410,7 +410,7 @@ function leadCard(key: string) {
<scroll-view v-else scroll-x class="fs" :show-scrollbar="false">
<view class="fs__row">
<view
v-for="fe in FEATURE_ENTRIES"
v-for="fe in FEATURE_ENTRIES_HOME"
:key="fe.key"
class="fs__card press"
hover-class="press-active"

View File

@@ -2,7 +2,8 @@
* 环境配置
* 微信开发者工具联调需勾选「不校验合法域名」;生产改为 https 域名(需在小程序后台配置 request 合法域名)
*/
let baseUrl = 'http://127.0.0.1:8000'
// let baseUrl = 'http://127.0.0.1:8000'
let baseUrl = 'https://wx.util.nailaoyun.cn/api'
// #ifdef H5
baseUrl = '/api'
// #endif

View File

@@ -87,15 +87,52 @@ export const FEATURE_ENTRIES: FeatureEntry[] = [
color: '#0FA385',
tone: 'mint',
},
// {
// key: 'cardLibrary',
// name: '卡片样式库',
// icon: 'photo',
// illustration: 'sparkle',
// desc: '20 组卡片设计复刻',
// path: '/pkg-style/showcase',
// bg: '#ECE2FF',
// color: '#5B2E9E',
// tone: 'violet',
// },
{
key: 'cardLibrary',
name: '卡片样式库',
icon: 'photo',
illustration: 'sparkle',
desc: '20 组卡片设计复刻',
path: '/pkg-style/showcase',
bg: '#ECE2FF',
color: '#5B2E9E',
tone: 'violet',
},
]
/** 功能入口列表(我的页渲染来源) */
export const FEATURE_ENTRIES_HOME: FeatureEntry[] = [
{
key: 'note',
name: '我的笔记',
icon: 'edit-outline',
illustration: 'note',
desc: '随手记录 · 定时提醒',
path: '/pkg-note/list',
bg: '#FFF4D6',
color: '#B57F00',
tone: 'gold',
},
{
key: 'event',
name: '年会查座',
icon: 'location',
illustration: 'pin',
desc: '选活动查座位',
path: '/pkg-event/list',
bg: '#E3F2FF',
color: '#1677D9',
tone: 'blue',
},
{
key: 'service',
name: '软件开发',
icon: 'computer',
illustration: 'rocket',
desc: '定制开发 · 在线报价',
path: '/pkg-service/home',
bg: '#DFF7F0',
color: '#0FA385',
tone: 'mint',
},
]

View File

@@ -1,73 +1,73 @@
{
"name": "",
"appid": "",
"description": "",
"versionName": "1.0.0",
"versionCode": "100",
"transformPx": false,
"uniStatistics": {
"enable": false
},
"app-plus": {
"usingComponents": true,
"nvueStyleCompiler": "uni-app",
"compilerVersion": 3,
"splashscreen": {
"alwaysShowBeforeRender": true,
"waiting": true,
"autoclose": true,
"delay": 0
"name" : "qitongxue",
"appid" : "__UNI__C867330",
"description" : "",
"versionName" : "1.0.0",
"versionCode" : "100",
"transformPx" : false,
"uniStatistics" : {
"enable" : false
},
"modules": {},
"distribute": {
"android": {
"permissions": [
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
"<uses-feature android:name=\"android.hardware.camera\"/>",
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
]
},
"ios": {},
"sdkConfigs": {}
}
},
"h5": {
"darkmode": true,
"themeLocation": "theme.json"
},
"quickapp": {},
"mp-weixin": {
"appid": "wx8f3891eaad380949",
"setting": {
"urlCheck": false
"app-plus" : {
"usingComponents" : true,
"nvueStyleCompiler" : "uni-app",
"compilerVersion" : 3,
"splashscreen" : {
"alwaysShowBeforeRender" : true,
"waiting" : true,
"autoclose" : true,
"delay" : 0
},
"modules" : {},
"distribute" : {
"android" : {
"permissions" : [
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
"<uses-feature android:name=\"android.hardware.camera\"/>",
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
]
},
"ios" : {},
"sdkConfigs" : {}
}
},
"optimization": {
"subPackages": true
"h5" : {
"darkmode" : true,
"themeLocation" : "theme.json"
},
"usingComponents": true,
"darkmode": true,
"themeLocation": "theme.json"
},
"mp-alipay": {
"usingComponents": true
},
"mp-baidu": {
"usingComponents": true
},
"mp-toutiao": {
"usingComponents": true
},
"vueVersion": "3"
"quickapp" : {},
"mp-weixin" : {
"appid" : "wx8f3891eaad380949",
"setting" : {
"urlCheck" : false
},
"optimization" : {
"subPackages" : true
},
"usingComponents" : true,
"darkmode" : true,
"themeLocation" : "theme.json"
},
"mp-alipay" : {
"usingComponents" : true
},
"mp-baidu" : {
"usingComponents" : true
},
"mp-toutiao" : {
"usingComponents" : true
},
"vueVersion" : "3"
}

View File

@@ -9,74 +9,76 @@
* 命名 = 语义 kebab-case;`hero-` 前缀为 288px 大图。
* ⚠️ ImageGen 不保证按 prompt 顺序出图——每张 sheet 切完必须目验蒙太奇核对名实。
*/
import avatarWoman from './static/icons/avatar-woman.png'
import anchor from './static/icons/anchor.png'
import atom from './static/icons/atom.png'
import badgeBolt from './static/icons/badge-bolt.png'
import badgeCrown from './static/icons/badge-crown.png'
import badgeHeart from './static/icons/badge-heart.png'
import badgeStar from './static/icons/badge-star.png'
import balloon from './static/icons/balloon.png'
import bell from './static/icons/bell.png'
import bookA from './static/icons/bookA.png'
import brain from './static/icons/brain.png'
import broballoon from './static/icons/broballoon.png'
import briefcase from './static/icons/briefcase.png'
import burger from './static/icons/burger.png'
import cake from './static/icons/cake.png'
import camera from './static/icons/camera.png'
import cameraretro from './static/icons/cameraretro.png'
import cart from './static/icons/cart.png'
import chart from './static/icons/chart.png'
import chat from './static/icons/chat.png'
import chatdots from './static/icons/chatdots.png'
import clipboard from './static/icons/clipboard.png'
import clock from './static/icons/clock.png'
import cloudDown from './static/icons/cloud-down.png'
import cloudVideo from './static/icons/cloud-video.png'
import coffee from './static/icons/coffee.png'
import college from './static/icons/college.png'
import community from './static/icons/community.png'
import compass from './static/icons/compass.png'
import dinner from './static/icons/dinner.png'
import docscheck from './static/icons/docscheck.png'
import donut from './static/icons/donut.png'
import exampaper from './static/icons/exampaper.png'
import film from './static/icons/film.png'
import folder from './static/icons/folder.png'
import gamepad from './static/icons/gamepad.png'
import gift from './static/icons/gift.png'
import gradcap from './static/icons/gradcap.png'
import hearts from './static/icons/hearts.png'
import heroBot from './static/icons/hero-bot.png'
import icepop from './static/icons/icepop.png'
import live from './static/icons/live.png'
import lovepop from './static/icons/lovepop.png'
import majorbag from './static/icons/majorbag.png'
import mask from './static/icons/mask.png'
import message from './static/icons/message.png'
import mic from './static/icons/mic.png'
import miniapp from './static/icons/miniapp.png'
import notes from './static/icons/notes.png'
import notebook from './static/icons/notebook.png'
import orangeFruit from './static/icons/orange-fruit.png'
import papers from './static/icons/papers.png'
import pear from './static/icons/pear.png'
import pencil from './static/icons/pencil.png'
import persona from './static/icons/persona.png'
import plane from './static/icons/plane.png'
import planet from './static/icons/planet.png'
import resume from './static/icons/resume.png'
import scan from './static/icons/scan.png'
import script from './static/icons/script.png'
import selfbook from './static/icons/selfbook.png'
import shield from './static/icons/shield.png'
import shrimp from './static/icons/shrimp.png'
import store from './static/icons/store.png'
import suitcase from './static/icons/suitcase.png'
import vinyl from './static/icons/vinyl.png'
import wework from './static/icons/wework.png'
import wordbook from './static/icons/wordbook.png'
let isDev = false;
let baseUrl = isDev === true? 'http://127.0.0.1:8000': 'https://wx.util.nailaoyun.cn';
let avatarWoman = baseUrl + '/static/icons/avatar-woman.png'
let anchor = baseUrl + '/static/icons/anchor.png'
let atom = baseUrl + '/static/icons/atom.png'
let badgeBolt = baseUrl + '/static/icons/badge-bolt.png'
let badgeCrown = baseUrl + '/static/icons/badge-crown.png'
let badgeHeart = baseUrl + '/static/icons/badge-heart.png'
let badgeStar = baseUrl + '/static/icons/badge-star.png'
let balloon = baseUrl + '/static/icons/balloon.png'
let bell = baseUrl + '/static/icons/bell.png'
let bookA = baseUrl + '/static/icons/bookA.png'
let brain = baseUrl + '/static/icons/brain.png'
let broballoon = baseUrl + '/static/icons/broballoon.png'
let briefcase = baseUrl + '/static/icons/briefcase.png'
let burger = baseUrl + '/static/icons/burger.png'
let cake = baseUrl + '/static/icons/cake.png'
let camera = baseUrl + '/static/icons/camera.png'
let cameraretro = baseUrl + '/static/icons/cameraretro.png'
let cart = baseUrl + '/static/icons/cart.png'
let chart = baseUrl + '/static/icons/chart.png'
let chat = baseUrl + '/static/icons/chat.png'
let chatdots = baseUrl + '/static/icons/chatdots.png'
let clipboard = baseUrl + '/static/icons/clipboard.png'
let clock = baseUrl + '/static/icons/clock.png'
let cloudDown = baseUrl + '/static/icons/cloud-down.png'
let cloudVideo = baseUrl + '/static/icons/cloud-video.png'
let coffee = baseUrl + '/static/icons/coffee.png'
let college = baseUrl + '/static/icons/college.png'
let community = baseUrl + '/static/icons/community.png'
let compass = baseUrl + '/static/icons/compass.png'
let dinner = baseUrl + '/static/icons/dinner.png'
let docscheck = baseUrl + '/static/icons/docscheck.png'
let donut = baseUrl + '/static/icons/donut.png'
let exampaper = baseUrl + '/static/icons/exampaper.png'
let film = baseUrl + '/static/icons/film.png'
let folder = baseUrl + '/static/icons/folder.png'
let gamepad = baseUrl + '/static/icons/gamepad.png'
let gift = baseUrl + '/static/icons/gift.png'
let gradcap = baseUrl + '/static/icons/gradcap.png'
let hearts = baseUrl + '/static/icons/hearts.png'
let heroBot = baseUrl + '/static/icons/hero-bot.png'
let icepop = baseUrl + '/static/icons/icepop.png'
let live = baseUrl + '/static/icons/live.png'
let lovepop = baseUrl + '/static/icons/lovepop.png'
let majorbag = baseUrl + '/static/icons/majorbag.png'
let mask = baseUrl + '/static/icons/mask.png'
let message = baseUrl + '/static/icons/message.png'
let mic = baseUrl + '/static/icons/mic.png'
let miniapp = baseUrl + '/static/icons/miniapp.png'
let notes = baseUrl + '/static/icons/notes.png'
let notebook = baseUrl + '/static/icons/notebook.png'
let orangeFruit = baseUrl + '/static/icons/orange-fruit.png'
let papers = baseUrl + '/static/icons/papers.png'
let pear = baseUrl + '/static/icons/pear.png'
let pencil = baseUrl + '/static/icons/pencil.png'
let persona = baseUrl + '/static/icons/persona.png'
let plane = baseUrl + '/static/icons/plane.png'
let planet = baseUrl + '/static/icons/planet.png'
let resume = baseUrl + '/static/icons/resume.png'
let scan = baseUrl + '/static/icons/scan.png'
let script = baseUrl + '/static/icons/script.png'
let selfbook = baseUrl + '/static/icons/selfbook.png'
let shield = baseUrl + '/static/icons/shield.png'
let shrimp = baseUrl + '/static/icons/shrimp.png'
let store = baseUrl + '/static/icons/store.png'
let suitcase = baseUrl + '/static/icons/suitcase.png'
let vinyl = baseUrl + '/static/icons/vinyl.png'
let wework = baseUrl + '/static/icons/wework.png'
let wordbook = baseUrl + '/static/icons/wordbook.png'
export const ICONS = {
'hero-bot': heroBot,

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB