- 将获取 STS Token 的接口地址由 paopao-api 改为 guilixu-api - 更新图片上传接口地址为新的 guilixu-api 域名 - 修改用户推广页面中邀请码链接和二维码接口的域名 - 更改注册页微信登录接口请求的域名为 guilixu-api
298 lines
10 KiB
TypeScript
298 lines
10 KiB
TypeScript
import { View, Text, ScrollView, Input, Button } from '@tarojs/components';
|
||
import { useState, useEffect, useCallback } from 'react';
|
||
import { useDidShow } from '@tarojs/taro';
|
||
import Taro from '@tarojs/taro';
|
||
import NavBar from '@/components/NavBar';
|
||
import LoadMore from '@/components/common/LoadMore';
|
||
import EmptyState from '@/components/common/EmptyState';
|
||
import {
|
||
listShopInvoiceTitle,
|
||
addShopInvoiceTitle,
|
||
updateShopInvoiceTitle,
|
||
removeShopInvoiceTitle,
|
||
setDefaultInvoiceTitle
|
||
} from '@/api/shop/shopInvoiceTitle';
|
||
import type { ShopInvoiceTitle, ShopInvoiceTitleParam } from '@/api/shop/shopInvoiceTitle/model';
|
||
|
||
export default function InvoiceTitlePage() {
|
||
const [titleList, setTitleList] = useState<ShopInvoiceTitle[]>([]);
|
||
const [loading, setLoading] = useState(true);
|
||
const [showAddModal, setShowAddModal] = useState(false);
|
||
const [editItem, setEditItem] = useState<ShopInvoiceTitle | null>(null);
|
||
const [formData, setFormData] = useState({
|
||
type: 'personal' as 'personal' | 'company',
|
||
name: '',
|
||
taxNumber: '',
|
||
email: '',
|
||
});
|
||
|
||
// 加载数据
|
||
const loadData = useCallback(async () => {
|
||
setLoading(true);
|
||
try {
|
||
const params: ShopInvoiceTitleParam = {};
|
||
const result = await listShopInvoiceTitle(params);
|
||
setTitleList(result || []);
|
||
} catch (e: any) {
|
||
console.error('获取发票抬头失败:', e);
|
||
Taro.showToast({ title: e.message || '获取数据失败', icon: 'none' });
|
||
} finally {
|
||
setLoading(false);
|
||
}
|
||
}, []);
|
||
|
||
useEffect(() => {
|
||
loadData();
|
||
}, [loadData]);
|
||
|
||
// 删除
|
||
const handleDelete = async (id: number) => {
|
||
Taro.showModal({
|
||
title: '确认删除',
|
||
content: '确定要删除该发票抬头吗?',
|
||
success: async (res) => {
|
||
if (res.confirm) {
|
||
try {
|
||
await removeShopInvoiceTitle(id);
|
||
Taro.showToast({ title: '删除成功', icon: 'success' });
|
||
loadData();
|
||
} catch (e: any) {
|
||
Taro.showToast({ title: e.message || '删除失败', icon: 'none' });
|
||
}
|
||
}
|
||
}
|
||
});
|
||
};
|
||
|
||
// 设置默认
|
||
const handleSetDefault = async (id: number) => {
|
||
try {
|
||
await setDefaultInvoiceTitle(id);
|
||
Taro.showToast({ title: '设置成功', icon: 'success' });
|
||
loadData();
|
||
} catch (e: any) {
|
||
Taro.showToast({ title: e.message || '设置失败', icon: 'none' });
|
||
}
|
||
};
|
||
|
||
// 编辑
|
||
const handleEdit = (item: ShopInvoiceTitle) => {
|
||
setEditItem(item);
|
||
setFormData({
|
||
type: (item.type as 'personal' | 'company') || 'personal',
|
||
name: item.name || '',
|
||
taxNumber: item.taxNumber || '',
|
||
email: item.email || '',
|
||
});
|
||
setShowAddModal(true);
|
||
};
|
||
|
||
// 添加/编辑提交
|
||
const handleSubmit = async () => {
|
||
if (!formData.name.trim()) {
|
||
Taro.showToast({ title: '请输入抬头名称', icon: 'none' });
|
||
return;
|
||
}
|
||
if (formData.type === 'company' && !formData.taxNumber.trim()) {
|
||
Taro.showToast({ title: '请输入税号', icon: 'none' });
|
||
return;
|
||
}
|
||
|
||
try {
|
||
if (editItem) {
|
||
await updateShopInvoiceTitle({
|
||
id: editItem.id,
|
||
...formData,
|
||
});
|
||
Taro.showToast({ title: '修改成功', icon: 'success' });
|
||
} else {
|
||
await addShopInvoiceTitle(formData);
|
||
Taro.showToast({ title: '添加成功', icon: 'success' });
|
||
}
|
||
setShowAddModal(false);
|
||
setEditItem(null);
|
||
setFormData({ type: 'personal', name: '', taxNumber: '', email: '' });
|
||
loadData();
|
||
} catch (e: any) {
|
||
Taro.showToast({ title: e.message || '操作失败', icon: 'none' });
|
||
}
|
||
};
|
||
|
||
// 取消编辑
|
||
const handleCancel = () => {
|
||
setShowAddModal(false);
|
||
setEditItem(null);
|
||
setFormData({ type: 'personal', name: '', taxNumber: '', email: '' });
|
||
};
|
||
|
||
return (
|
||
<View className="bg-gray-100 flex flex-col" style={{ minHeight: '100vh' }}>
|
||
<NavBar title="发票抬头管理" />
|
||
|
||
<View className='flex-1'>
|
||
{loading ? (
|
||
<LoadMore loading />
|
||
) : titleList.length === 0 ? (
|
||
<EmptyState message="暂无发票抬头" />
|
||
) : (
|
||
<ScrollView scrollY className="p-4">
|
||
{titleList.map(item => (
|
||
<View key={item.id} className="bg-white rounded-lg p-4 mb-4">
|
||
<View className="flex justify-between items-start mb-2">
|
||
<View className="flex-1">
|
||
<View className="flex items-center mb-2">
|
||
<Text className={`text-xs px-2 py-1 rounded mr-2 ${
|
||
item.type === 'personal' ? 'bg-blue-100 text-blue-600' : 'bg-orange-100 text-orange-600'
|
||
}`}>
|
||
{item.type === 'personal' ? '个人' : '企业'}
|
||
</Text>
|
||
{item.isDefault === 1 && (
|
||
<Text className="text-xs px-2 py-1 rounded bg-red-100 text-red-600">
|
||
默认
|
||
</Text>
|
||
)}
|
||
</View>
|
||
<Text className="text-lg font-medium">{item.name}</Text>
|
||
{item.type === 'company' && item.taxNumber && (
|
||
<Text className="text-sm text-gray-500 mt-1 block">税号:{item.taxNumber}</Text>
|
||
)}
|
||
{item.email && (
|
||
<Text className="text-sm text-gray-500 mt-1 block">邮箱:{item.email}</Text>
|
||
)}
|
||
</View>
|
||
</View>
|
||
|
||
<View className="flex justify-between items-center pt-3 border-t border-gray-100">
|
||
<View
|
||
className="flex items-center"
|
||
onClick={() => handleSetDefault(item.id!)}
|
||
>
|
||
<View className={`w-5 h-5 rounded border-2 flex items-center justify-center ${
|
||
item.isDefault === 1 ? 'bg-red-500 border-red-500' : 'border-gray-300'
|
||
}`}>
|
||
{item.isDefault === 1 && <Text className="text-white text-xs">✓</Text>}
|
||
</View>
|
||
<Text className="text-sm text-gray-600 ml-2">设为默认</Text>
|
||
</View>
|
||
<View className="flex" style={{ gap: '16px' }}>
|
||
<Text
|
||
className="text-sm text-blue-500"
|
||
onClick={() => handleEdit(item)}
|
||
>
|
||
编辑
|
||
</Text>
|
||
<Text
|
||
className="text-sm text-red-500"
|
||
onClick={() => handleDelete(item.id!)}
|
||
>
|
||
删除
|
||
</Text>
|
||
</View>
|
||
</View>
|
||
</View>
|
||
))}
|
||
</ScrollView>
|
||
)}
|
||
</View>
|
||
|
||
{/* 添加/编辑弹窗 */}
|
||
{showAddModal && (
|
||
<View className="absolute flex items-center justify-center z-50" style={{ top: 0, right: 0, bottom: 0, left: 0, backgroundColor: 'rgba(0,0,0,0.5)' }}>
|
||
<View className="bg-white rounded-lg p-6" style={{ width: '91.667%', maxWidth: '688px' }}>
|
||
<Text className="text-xl font-bold mb-4">{editItem ? '编辑发票抬头' : '添加发票抬头'}</Text>
|
||
|
||
{/* 抬头类型 */}
|
||
<View className="mb-4">
|
||
<Text className="text-sm text-gray-600 mb-2 block">抬头类型</Text>
|
||
<View className="flex">
|
||
<View
|
||
className={`flex-1 py-2 text-center border rounded-l ${
|
||
formData.type === 'personal' ? 'bg-red-50 border-red-500 text-red-500' : 'border-gray-300'
|
||
}`}
|
||
onClick={() => setFormData(prev => ({ ...prev, type: 'personal' }))}
|
||
>
|
||
<Text>个人</Text>
|
||
</View>
|
||
<View
|
||
className={`flex-1 py-2 text-center border rounded-r ${
|
||
formData.type === 'company' ? 'bg-red-50 border-red-500 text-red-500' : 'border-gray-300'
|
||
}`}
|
||
onClick={() => setFormData(prev => ({ ...prev, type: 'company' }))}
|
||
>
|
||
<Text>企业</Text>
|
||
</View>
|
||
</View>
|
||
</View>
|
||
|
||
{/* 抬头名称 */}
|
||
<View className="mb-4">
|
||
<Text className="text-sm text-gray-600 mb-2 block">抬头名称</Text>
|
||
<Input
|
||
className="border rounded px-3 py-2"
|
||
placeholder="请输入发票抬头名称"
|
||
value={formData.name}
|
||
onInput={(e: any) => setFormData(prev => ({ ...prev, name: e.detail.value }))}
|
||
/>
|
||
</View>
|
||
|
||
{/* 税号 */}
|
||
{formData.type === 'company' && (
|
||
<View className="mb-4">
|
||
<Text className="text-sm text-gray-600 mb-2 block">税号</Text>
|
||
<Input
|
||
className="border rounded px-3 py-2"
|
||
placeholder="请输入税号"
|
||
value={formData.taxNumber}
|
||
onInput={(e: any) => setFormData(prev => ({ ...prev, taxNumber: e.detail.value }))}
|
||
/>
|
||
</View>
|
||
)}
|
||
|
||
{/* 邮箱 */}
|
||
<View className="mb-4">
|
||
<Text className="text-sm text-gray-600 mb-2 block">接收邮箱(选填)</Text>
|
||
<Input
|
||
className="border rounded px-3 py-2"
|
||
type="email"
|
||
placeholder="用于接收电子发票"
|
||
value={formData.email}
|
||
onInput={(e: any) => setFormData(prev => ({ ...prev, email: e.detail.value }))}
|
||
/>
|
||
</View>
|
||
|
||
{/* 按钮 */}
|
||
<View className="flex" style={{ gap: '12px' }}>
|
||
<Button
|
||
className="flex-1 py-2 border border-gray-300 rounded"
|
||
onClick={handleCancel}
|
||
>
|
||
取消
|
||
</Button>
|
||
<Button
|
||
className="flex-1 py-2 bg-red-500 text-white rounded"
|
||
onClick={handleSubmit}
|
||
>
|
||
保存
|
||
</Button>
|
||
</View>
|
||
</View>
|
||
</View>
|
||
)}
|
||
|
||
{/* 底部添加按钮 */}
|
||
<View className="p-4 bg-white border-t border-gray-200" style={{ paddingBottom: '20px' }}>
|
||
<Button
|
||
className="bg-red-500 text-white rounded-full w-full h-12"
|
||
onClick={() => {
|
||
setEditItem(null);
|
||
setFormData({ type: 'personal', name: '', taxNumber: '', email: '' });
|
||
setShowAddModal(true);
|
||
}}
|
||
>
|
||
添加新抬头
|
||
</Button>
|
||
</View>
|
||
</View>
|
||
);
|
||
}
|