feat: refresh service and tool pages
This commit is contained in:
@@ -23,18 +23,16 @@ export default function ServicePage() {
|
||||
<View className={`theme-${resolvedTheme}`} style={{ minHeight: '100vh' }}>
|
||||
<ThemedPageMeta />
|
||||
<View className='service-page'>
|
||||
<View className='page-header dashed-card mt-20' style={{ marginTop: `${safe.headerPaddingTop}px` }}>
|
||||
<View className='star-badge' />
|
||||
<View className='page-header surface-card mt-20' style={{ marginTop: `${safe.headerPaddingTop}px` }}>
|
||||
<Text className='page-title'>联系客服</Text>
|
||||
</View>
|
||||
|
||||
{/* 客服入口 */}
|
||||
<View className='service-hero dashed-card mt-20'>
|
||||
<View className='star-badge' />
|
||||
<View className='service-hero surface-card mt-20'>
|
||||
<Image className='service-hero-icon' src={assetUrl('/icon/电话.png')} mode='aspectFit' />
|
||||
<Text className='service-title'>智绘微刻客服中心</Text>
|
||||
<Text className='service-desc'>工作日 09:00 - 18:00 在线为您服务</Text>
|
||||
<View className='btn-gradient service-btn' onTap={() => Taro.showToast({ title: '跳转客服会话', icon: 'none' })}>
|
||||
<View className='btn-primary service-btn' onTap={() => Taro.showToast({ title: '跳转客服会话', icon: 'none' })}>
|
||||
<Text>发起咨询</Text>
|
||||
</View>
|
||||
</View>
|
||||
@@ -43,24 +41,21 @@ export default function ServicePage() {
|
||||
<View className='mt-20'>
|
||||
<Text className='section-title'>联系方式</Text>
|
||||
<View className='contact-list'>
|
||||
<View className='contact-item dashed-card'>
|
||||
<View className='star-badge' />
|
||||
<View className='contact-item surface-card'>
|
||||
<Image className='contact-icon-img' src={assetUrl('/icon/电话.png')} mode='aspectFit' />
|
||||
<View className='contact-info'>
|
||||
<Text className='contact-label'>客服电话</Text>
|
||||
<Text className='contact-value'>400-XXX-XXXX</Text>
|
||||
</View>
|
||||
</View>
|
||||
<View className='contact-item dashed-card' onTap={() => Taro.setClipboardData({ data: 'smart_engraving' })}>
|
||||
<View className='star-badge' />
|
||||
<View className='contact-item surface-card' onTap={() => Taro.setClipboardData({ data: 'smart_engraving' })}>
|
||||
<Image className='contact-icon-img' src={assetUrl('/icon/词云生成.png')} mode='aspectFit' />
|
||||
<View className='contact-info'>
|
||||
<Text className='contact-label'>客服微信</Text>
|
||||
<Text className='contact-value'>smart_engraving(点击复制)</Text>
|
||||
</View>
|
||||
</View>
|
||||
<View className='contact-item dashed-card'>
|
||||
<View className='star-badge' />
|
||||
<View className='contact-item surface-card'>
|
||||
<Image className='contact-icon-img' src={assetUrl('/icon/使用帮助.png')} mode='aspectFit' />
|
||||
<View className='contact-info'>
|
||||
<Text className='contact-label'>商务邮箱</Text>
|
||||
@@ -74,8 +69,7 @@ export default function ServicePage() {
|
||||
<View className='mt-20'>
|
||||
<Text className='section-title'>常见问题</Text>
|
||||
{FAQ_ITEMS.map((item, idx) => (
|
||||
<View key={idx} className='faq-card dashed-card'>
|
||||
<View className='star-badge' />
|
||||
<View key={idx} className='faq-card surface-card'>
|
||||
<Text className='faq-q'>Q: {item.q}</Text>
|
||||
<Text className='faq-a'>A: {item.a}</Text>
|
||||
</View>
|
||||
@@ -83,14 +77,13 @@ export default function ServicePage() {
|
||||
</View>
|
||||
|
||||
{/* B端专属 */}
|
||||
<View className='enterprise-service dashed-card mt-20 mb-20'>
|
||||
<View className='star-badge' />
|
||||
<View className='enterprise-service surface-card mt-20 mb-20'>
|
||||
<View className='flex-center'>
|
||||
<Image className='enterprise-icon' src={assetUrl('/icon/企业批量定制.png')} mode='aspectFit' />
|
||||
<Text className='enterprise-title'>企业专属客户经理</Text>
|
||||
</View>
|
||||
<Text className='enterprise-desc'>批量订单(50件以上)享专属报价、优先排产、专人对接</Text>
|
||||
<View className='btn-outline enterprise-btn'>
|
||||
<View className='btn-secondary enterprise-btn'>
|
||||
<Text>预约企业咨询</Text>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
width: 100%;
|
||||
height: 80px;
|
||||
background: var(--bg-input);
|
||||
border: 2px solid var(--line-star);
|
||||
border: 1rpx solid var(--border);
|
||||
border-radius: 16px;
|
||||
padding: 0 24px;
|
||||
font-size: 30px;
|
||||
@@ -49,7 +49,7 @@
|
||||
|
||||
.udb-error {
|
||||
font-size: 24px;
|
||||
color: #e64340;
|
||||
color: var(--danger);
|
||||
margin-bottom: 20px;
|
||||
display: block;
|
||||
}
|
||||
@@ -75,7 +75,7 @@
|
||||
/* 数据表格 */
|
||||
.udb-table {
|
||||
background: var(--bg-card);
|
||||
border: var(--line-card);
|
||||
border: 1rpx solid var(--border);
|
||||
border-radius: 24px;
|
||||
overflow: hidden;
|
||||
}
|
||||
@@ -84,7 +84,7 @@
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 20px 16px;
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.04);
|
||||
border-bottom: 1rpx solid var(--border);
|
||||
}
|
||||
|
||||
.udb-row:last-child {
|
||||
@@ -134,25 +134,25 @@
|
||||
}
|
||||
|
||||
.udb-row.active {
|
||||
background: rgba(91, 140, 255, 0.06);
|
||||
background: var(--accent-secondary-soft);
|
||||
}
|
||||
|
||||
.udb-link {
|
||||
padding: 6px 14px;
|
||||
border-radius: 8px;
|
||||
font-size: 22px;
|
||||
color: var(--accent-blue);
|
||||
background: rgba(91, 140, 255, 0.08);
|
||||
color: var(--accent-secondary);
|
||||
background: var(--accent-secondary-soft);
|
||||
}
|
||||
|
||||
.udb-danger {
|
||||
color: #e64340;
|
||||
background: rgba(230, 67, 64, 0.08);
|
||||
color: var(--danger);
|
||||
background: var(--danger-soft);
|
||||
}
|
||||
|
||||
.udb-current {
|
||||
font-size: 22px;
|
||||
color: var(--accent-blue);
|
||||
color: var(--accent-secondary);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
@@ -182,7 +182,7 @@
|
||||
width: 100%;
|
||||
height: 80px;
|
||||
background: var(--bg-input);
|
||||
border: 2px solid var(--line-star);
|
||||
border: 1rpx solid var(--border);
|
||||
border-radius: 16px;
|
||||
padding: 0 24px;
|
||||
font-size: 28px;
|
||||
@@ -197,8 +197,8 @@
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.udb-add-actions .btn-outline,
|
||||
.udb-add-actions .btn-gradient {
|
||||
.udb-add-actions .btn-secondary,
|
||||
.udb-add-actions .btn-primary {
|
||||
flex: 1;
|
||||
padding: 18px 0;
|
||||
text-align: center;
|
||||
|
||||
@@ -56,7 +56,7 @@ export default function UserDatabasePage() {
|
||||
Taro.showModal({
|
||||
title: '确认删除',
|
||||
content: '删除后将清空该用户所有数据,无法恢复',
|
||||
confirmColor: '#e64340',
|
||||
confirmColor: resolvedTheme === 'dark' ? '#ef7a7a' : '#d85d5d',
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
deleteUser(openid)
|
||||
@@ -79,15 +79,15 @@ export default function UserDatabasePage() {
|
||||
Taro.showToast({ title: '创建成功', icon: 'success' })
|
||||
}
|
||||
|
||||
const activeOpenid = getUserInfo()?.openid || ''
|
||||
const currentUser = getUserInfo()
|
||||
const activeOpenid = (currentUser && currentUser.openid) || ''
|
||||
|
||||
if (!isUnlocked) {
|
||||
return (
|
||||
<View className={`theme-${resolvedTheme}`}>
|
||||
<ThemedPageMeta />
|
||||
<View className='udb-page'>
|
||||
<View className='udb-lock-card dashed-card mt-20'>
|
||||
<View className='star-badge' />
|
||||
<View className='udb-lock-card surface-card mt-20'>
|
||||
<Image className='udb-lock-icon' src={assetUrl('/icon/账号管理.png')} mode='aspectFit' />
|
||||
<Text className='udb-lock-title'>管理员验证</Text>
|
||||
<Text className='udb-lock-desc'>请输入密码以访问用户数据库</Text>
|
||||
@@ -102,7 +102,7 @@ export default function UserDatabasePage() {
|
||||
{pwdError && (
|
||||
<Text className='udb-error'>密码错误,请重试</Text>
|
||||
)}
|
||||
<View className='btn-gradient udb-btn' onTap={handleUnlock}>
|
||||
<View className='btn-primary udb-btn' onTap={handleUnlock}>
|
||||
<Text>进入数据库</Text>
|
||||
</View>
|
||||
</View>
|
||||
@@ -116,13 +116,12 @@ export default function UserDatabasePage() {
|
||||
<ThemedPageMeta />
|
||||
<View className='udb-page'>
|
||||
|
||||
<View className='page-header dashed-card mt-20' style={{ marginTop: `${safe.headerPaddingTop}px` }}>
|
||||
<View className='star-badge' />
|
||||
<View className='page-header surface-card mt-20' style={{ marginTop: `${safe.headerPaddingTop}px` }}>
|
||||
<Text className='page-title'>本地用户数据库</Text>
|
||||
</View>
|
||||
|
||||
<View className='udb-toolbar'>
|
||||
<View className='btn-gradient udb-add-btn' onTap={() => setShowAdd(true)}>
|
||||
<View className='btn-primary udb-add-btn' onTap={() => setShowAdd(true)}>
|
||||
<Text>+ 新建账号</Text>
|
||||
</View>
|
||||
</View>
|
||||
@@ -164,8 +163,7 @@ export default function UserDatabasePage() {
|
||||
{/* 新建账号弹窗 */}
|
||||
{showAdd && (
|
||||
<View className='modal-overlay'>
|
||||
<View className='udb-add-card dashed-card'>
|
||||
<View className='star-badge' />
|
||||
<View className='udb-add-card surface-card'>
|
||||
<Text className='udb-add-title'>新建本地账号</Text>
|
||||
<Input
|
||||
className='udb-add-input'
|
||||
@@ -175,10 +173,10 @@ export default function UserDatabasePage() {
|
||||
onInput={(e: any) => setNewNick(e.detail.value)}
|
||||
/>
|
||||
<View className='udb-add-actions'>
|
||||
<View className='btn-outline' onTap={() => setShowAdd(false)}>
|
||||
<View className='btn-secondary' onTap={() => setShowAdd(false)}>
|
||||
<Text>取消</Text>
|
||||
</View>
|
||||
<View className='btn-gradient' onTap={handleCreate}>
|
||||
<View className='btn-primary' onTap={handleCreate}>
|
||||
<Text>创建</Text>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
@@ -42,12 +42,12 @@
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-bottom: 12px;
|
||||
border: 4px dashed var(--bg-input);
|
||||
border: 1rpx solid var(--border);
|
||||
}
|
||||
|
||||
.step-circle.active {
|
||||
background: var(--btn-gradient);
|
||||
border-color: var(--accent-pink);
|
||||
background: var(--accent-primary);
|
||||
border-color: var(--accent-primary);
|
||||
}
|
||||
|
||||
.step-num {
|
||||
@@ -66,7 +66,7 @@
|
||||
}
|
||||
|
||||
.step-label.active {
|
||||
color: var(--accent-pink);
|
||||
color: var(--accent-primary);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
@@ -80,7 +80,7 @@
|
||||
}
|
||||
|
||||
.step-line.active {
|
||||
background: var(--btn-gradient);
|
||||
background: var(--accent-primary);
|
||||
}
|
||||
|
||||
/* 步骤内容 */
|
||||
@@ -94,6 +94,8 @@
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border: 1rpx solid var(--border);
|
||||
border-radius: 24rpx;
|
||||
}
|
||||
|
||||
.upload-placeholder {
|
||||
@@ -124,11 +126,11 @@
|
||||
|
||||
.upload-tip {
|
||||
font-size: 22px;
|
||||
color: var(--accent-blue);
|
||||
background: rgba(91, 140, 255, 0.1);
|
||||
color: var(--accent-secondary);
|
||||
background: var(--accent-secondary-soft);
|
||||
padding: 8px 20px;
|
||||
border-radius: 50px;
|
||||
border: var(--line-card);
|
||||
border-radius: 999rpx;
|
||||
border: 1rpx solid var(--border);
|
||||
}
|
||||
|
||||
.preview-image {
|
||||
@@ -148,6 +150,8 @@
|
||||
/* 输入区域 */
|
||||
.input-section {
|
||||
padding: 32px;
|
||||
border: 1rpx solid var(--border);
|
||||
border-radius: 24rpx;
|
||||
}
|
||||
|
||||
.names-input {
|
||||
@@ -159,7 +163,7 @@
|
||||
font-size: 28px;
|
||||
line-height: 1.6;
|
||||
box-sizing: border-box;
|
||||
border: var(--line-card);
|
||||
border: 1rpx solid var(--border);
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
@@ -218,14 +222,14 @@
|
||||
.progress-bar {
|
||||
width: 80%;
|
||||
height: 16px;
|
||||
background: rgba(255, 154, 158, 0.15);
|
||||
background: var(--accent-primary-soft);
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.progress-fill {
|
||||
height: 100%;
|
||||
background: var(--btn-gradient);
|
||||
background: var(--accent-primary);
|
||||
border-radius: 8px;
|
||||
transition: width 0.5s ease;
|
||||
}
|
||||
@@ -233,7 +237,7 @@
|
||||
.progress-text {
|
||||
font-size: 32px;
|
||||
font-weight: 700;
|
||||
color: var(--accent-pink);
|
||||
color: var(--accent-primary);
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
@@ -245,24 +249,26 @@
|
||||
.result-image-wrapper {
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
border: 1rpx solid var(--border);
|
||||
border-radius: 24rpx;
|
||||
}
|
||||
|
||||
.result-image {
|
||||
width: 100%;
|
||||
height: 500px;
|
||||
background: linear-gradient(135deg, rgba(255, 154, 158, 0.08) 0%, rgba(160, 196, 255, 0.08) 100%);
|
||||
background: linear-gradient(135deg, var(--accent-primary-soft) 0%, var(--accent-secondary-soft) 100%);
|
||||
}
|
||||
|
||||
.watermark-badge {
|
||||
position: absolute;
|
||||
bottom: 20px;
|
||||
right: 20px;
|
||||
background: rgba(255, 255, 255, 0.8);
|
||||
background: var(--glass);
|
||||
color: var(--text-primary);
|
||||
padding: 8px 20px;
|
||||
border-radius: 8px;
|
||||
font-size: 22px;
|
||||
border: var(--line-card);
|
||||
border: 1rpx solid var(--border);
|
||||
}
|
||||
|
||||
.result-actions {
|
||||
@@ -313,5 +319,5 @@
|
||||
|
||||
.diy-jump-arrow {
|
||||
font-size: 40px;
|
||||
color: var(--accent-pink);
|
||||
color: var(--accent-primary);
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ export default function WordCloudPage() {
|
||||
</View>
|
||||
|
||||
{/* 步骤指示器 */}
|
||||
<View className='step-indicator dashed-card'>
|
||||
<View className='step-indicator surface-card'>
|
||||
{steps.map((s, idx) => (
|
||||
<View key={s.num} className='step-item'>
|
||||
<View className={`step-circle ${step >= s.num ? 'active' : ''}`}>
|
||||
@@ -88,7 +88,7 @@ export default function WordCloudPage() {
|
||||
{/* 步骤1: 上传底图 */}
|
||||
{step === 1 && (
|
||||
<View className='step-content'>
|
||||
<View className='upload-area dashed-card' onTap={chooseImage}>
|
||||
<View className='upload-area surface-card' onTap={chooseImage}>
|
||||
{baseImage ? (
|
||||
<Image className='preview-image' src={baseImage} mode='aspectFit' />
|
||||
) : (
|
||||
@@ -102,10 +102,10 @@ export default function WordCloudPage() {
|
||||
</View>
|
||||
{baseImage && (
|
||||
<View className='action-btns'>
|
||||
<View className='btn-gradient' onTap={() => setStep(2)}>
|
||||
<View className='btn-primary' onTap={() => setStep(2)}>
|
||||
<Text>下一步:输入名单</Text>
|
||||
</View>
|
||||
<View className='btn-outline' onTap={() => setBaseImage('')}>
|
||||
<View className='btn-secondary' onTap={() => setBaseImage('')}>
|
||||
<Text>重新选择</Text>
|
||||
</View>
|
||||
</View>
|
||||
@@ -116,7 +116,7 @@ export default function WordCloudPage() {
|
||||
{/* 步骤2: 输入名单 */}
|
||||
{step === 2 && (
|
||||
<View className='step-content'>
|
||||
<View className='input-section dashed-card'>
|
||||
<View className='input-section surface-card'>
|
||||
<Text className='section-title'>输入名字名单</Text>
|
||||
<Textarea
|
||||
className='names-input'
|
||||
@@ -134,10 +134,10 @@ export default function WordCloudPage() {
|
||||
</View>
|
||||
</View>
|
||||
<View className='action-btns'>
|
||||
<View className='btn-gradient' onTap={handleGenerate}>
|
||||
<View className='btn-primary' onTap={handleGenerate}>
|
||||
<Text>开始生成词云</Text>
|
||||
</View>
|
||||
<View className='btn-outline' onTap={() => setStep(1)}>
|
||||
<View className='btn-secondary' onTap={() => setStep(1)}>
|
||||
<Text>上一步</Text>
|
||||
</View>
|
||||
</View>
|
||||
@@ -159,7 +159,7 @@ export default function WordCloudPage() {
|
||||
</View>
|
||||
) : (
|
||||
<View className='result-panel'>
|
||||
<View className='result-image-wrapper dashed-card'>
|
||||
<View className='result-image-wrapper surface-card'>
|
||||
<Image className='result-image' src={generatedImage || ''} mode='aspectFit' />
|
||||
<View className='watermark-badge'>
|
||||
<Text>智绘微刻预览</Text>
|
||||
|
||||
Reference in New Issue
Block a user