feat(shop): 新增用户管理模块- 添加用户记录表模型定义,包含用户基本信息、认证信息、统计信息等字段
- 实现用户记录表的增删改查接口,支持分页查询和批量删除功能 - 在医生申请页面集成用户信息提交功能,支持个人和企业用户类型- 优化用户表单验证逻辑,添加年龄必填校验- 调整用户类型单选框默认值为个人用户 - 添加证件上传功能,支持企业用户上传资质证明 - 移除文章分类和详情相关页面组件 - 调整请求工具中后台配置API地址的日志输出为注释状态
This commit is contained in:
105
src/api/shop/shopUser/index.ts
Normal file
105
src/api/shop/shopUser/index.ts
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
import request from '@/utils/request';
|
||||||
|
import type { ApiResult, PageResult } from '@/api';
|
||||||
|
import type { ShopUser, ShopUserParam } from './model';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页查询用户记录表
|
||||||
|
*/
|
||||||
|
export async function pageShopUser(params: ShopUserParam) {
|
||||||
|
const res = await request.get<ApiResult<PageResult<ShopUser>>>(
|
||||||
|
'/shop/shop-user/page',
|
||||||
|
{
|
||||||
|
params
|
||||||
|
}
|
||||||
|
);
|
||||||
|
if (res.code === 0) {
|
||||||
|
return res.data;
|
||||||
|
}
|
||||||
|
return Promise.reject(new Error(res.message));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询用户记录表列表
|
||||||
|
*/
|
||||||
|
export async function listShopUser(params?: ShopUserParam) {
|
||||||
|
const res = await request.get<ApiResult<ShopUser[]>>(
|
||||||
|
'/shop/shop-user',
|
||||||
|
{
|
||||||
|
params
|
||||||
|
}
|
||||||
|
);
|
||||||
|
if (res.code === 0 && res.data) {
|
||||||
|
return res.data;
|
||||||
|
}
|
||||||
|
return Promise.reject(new Error(res.message));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加用户记录表
|
||||||
|
*/
|
||||||
|
export async function addShopUser(data: ShopUser) {
|
||||||
|
const res = await request.post<ApiResult<unknown>>(
|
||||||
|
'http://127.0.0.1:9200/api/shop/shop-user',
|
||||||
|
data
|
||||||
|
);
|
||||||
|
if (res.code === 0) {
|
||||||
|
return res.message;
|
||||||
|
}
|
||||||
|
return Promise.reject(new Error(res.message));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改用户记录表
|
||||||
|
*/
|
||||||
|
export async function updateShopUser(data: ShopUser) {
|
||||||
|
const res = await request.put<ApiResult<unknown>>(
|
||||||
|
'/shop/shop-user',
|
||||||
|
data
|
||||||
|
);
|
||||||
|
if (res.code === 0) {
|
||||||
|
return res.message;
|
||||||
|
}
|
||||||
|
return Promise.reject(new Error(res.message));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除用户记录表
|
||||||
|
*/
|
||||||
|
export async function removeShopUser(id?: number) {
|
||||||
|
const res = await request.del<ApiResult<unknown>>(
|
||||||
|
'/shop/shop-user/' + id
|
||||||
|
);
|
||||||
|
if (res.code === 0) {
|
||||||
|
return res.message;
|
||||||
|
}
|
||||||
|
return Promise.reject(new Error(res.message));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量删除用户记录表
|
||||||
|
*/
|
||||||
|
export async function removeBatchShopUser(data: (number | undefined)[]) {
|
||||||
|
const res = await request.del<ApiResult<unknown>>(
|
||||||
|
'/shop/shop-user/batch',
|
||||||
|
{
|
||||||
|
data
|
||||||
|
}
|
||||||
|
);
|
||||||
|
if (res.code === 0) {
|
||||||
|
return res.message;
|
||||||
|
}
|
||||||
|
return Promise.reject(new Error(res.message));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据userId查询用户记录表
|
||||||
|
*/
|
||||||
|
export async function getShopUser(userId: number) {
|
||||||
|
const res = await request.get<ApiResult<ShopUser>>(
|
||||||
|
'/shop/shop-user/' + userId
|
||||||
|
);
|
||||||
|
if (res.code === 0 && res.data) {
|
||||||
|
return res.data;
|
||||||
|
}
|
||||||
|
return Promise.reject(new Error(res.message));
|
||||||
|
}
|
||||||
165
src/api/shop/shopUser/model/index.ts
Normal file
165
src/api/shop/shopUser/model/index.ts
Normal file
@@ -0,0 +1,165 @@
|
|||||||
|
import type { PageParam } from '@/api';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户记录表
|
||||||
|
*/
|
||||||
|
export interface ShopUser {
|
||||||
|
// 用户id
|
||||||
|
userId?: number;
|
||||||
|
// 用户类型 0个人用户 1企业用户 2其他
|
||||||
|
type?: number;
|
||||||
|
// 账号
|
||||||
|
username?: string;
|
||||||
|
// 密码
|
||||||
|
password?: string;
|
||||||
|
// 昵称
|
||||||
|
nickname?: string;
|
||||||
|
// 手机号
|
||||||
|
phone?: string;
|
||||||
|
// 性别 1男 2女
|
||||||
|
sex?: number;
|
||||||
|
// 职务
|
||||||
|
position?: string;
|
||||||
|
// 注册来源客户端 (APP、H5、MP-WEIXIN等)
|
||||||
|
platform?: string;
|
||||||
|
// 邮箱
|
||||||
|
email?: string;
|
||||||
|
// 邮箱是否验证, 0否, 1是
|
||||||
|
emailVerified?: number;
|
||||||
|
// 别名
|
||||||
|
alias?: string;
|
||||||
|
// 真实姓名
|
||||||
|
realName?: string;
|
||||||
|
// 证件号码
|
||||||
|
idCard?: string;
|
||||||
|
// 出生日期
|
||||||
|
birthday?: string;
|
||||||
|
// 所在国家
|
||||||
|
country?: string;
|
||||||
|
// 所在省份
|
||||||
|
province?: string;
|
||||||
|
// 所在城市
|
||||||
|
city?: string;
|
||||||
|
// 所在辖区
|
||||||
|
region?: string;
|
||||||
|
// 街道地址
|
||||||
|
address?: string;
|
||||||
|
// 经度
|
||||||
|
longitude?: string;
|
||||||
|
// 纬度
|
||||||
|
latitude?: string;
|
||||||
|
// 用户可用余额
|
||||||
|
balance?: string;
|
||||||
|
// 已提现金额
|
||||||
|
cashedMoney?: string;
|
||||||
|
// 用户可用积分
|
||||||
|
points?: number;
|
||||||
|
// 用户总支付的金额
|
||||||
|
payMoney?: string;
|
||||||
|
// 实际消费的金额(不含退款)
|
||||||
|
expendMoney?: string;
|
||||||
|
// 密码
|
||||||
|
payPassword?: string;
|
||||||
|
// 会员等级ID
|
||||||
|
gradeId?: number;
|
||||||
|
// 行业分类
|
||||||
|
category?: string;
|
||||||
|
// 个人简介
|
||||||
|
introduction?: string;
|
||||||
|
// 机构id
|
||||||
|
organizationId?: number;
|
||||||
|
// 会员分组ID
|
||||||
|
groupId?: number;
|
||||||
|
// 头像
|
||||||
|
avatar?: string;
|
||||||
|
// 背景图
|
||||||
|
bgImage?: string;
|
||||||
|
// 用户编码
|
||||||
|
userCode?: string;
|
||||||
|
// 是否已实名认证
|
||||||
|
certification?: number;
|
||||||
|
// 年龄
|
||||||
|
age?: number;
|
||||||
|
// 是否线下会员
|
||||||
|
offline?: string;
|
||||||
|
// 关注数
|
||||||
|
followers?: number;
|
||||||
|
// 粉丝数
|
||||||
|
fans?: number;
|
||||||
|
// 点赞数
|
||||||
|
likes?: number;
|
||||||
|
// 评论数
|
||||||
|
commentNumbers?: number;
|
||||||
|
// 是否推荐
|
||||||
|
recommend?: number;
|
||||||
|
// 微信openid
|
||||||
|
openid?: string;
|
||||||
|
// 微信公众号openid
|
||||||
|
officeOpenid?: string;
|
||||||
|
// 微信unionID
|
||||||
|
unionid?: string;
|
||||||
|
// 客户端ID
|
||||||
|
clientId?: string;
|
||||||
|
// 不允许办卡
|
||||||
|
notAllowVip?: string;
|
||||||
|
// 是否管理员
|
||||||
|
isAdmin?: string;
|
||||||
|
// 是否企业管理员
|
||||||
|
isOrganizationAdmin?: string;
|
||||||
|
// 累计登录次数
|
||||||
|
loginNum?: number;
|
||||||
|
// 企业ID
|
||||||
|
companyId?: number;
|
||||||
|
// 可管理的场馆
|
||||||
|
merchants?: string;
|
||||||
|
// 商户ID
|
||||||
|
merchantId?: number;
|
||||||
|
// 商户名称
|
||||||
|
merchantName?: string;
|
||||||
|
// 商户头像
|
||||||
|
merchantAvatar?: string;
|
||||||
|
// 第三方系统的用户ID
|
||||||
|
uid?: number;
|
||||||
|
// 专家角色
|
||||||
|
expertType?: string;
|
||||||
|
// 过期时间
|
||||||
|
expireTime?: number;
|
||||||
|
// 最后结算时间
|
||||||
|
settlementTime?: string;
|
||||||
|
// 资质
|
||||||
|
aptitude?: string;
|
||||||
|
// 行业类型(父级)
|
||||||
|
industryParent?: string;
|
||||||
|
// 行业类型(子级)
|
||||||
|
industryChild?: string;
|
||||||
|
// 头衔
|
||||||
|
title?: string;
|
||||||
|
// 安装的产品ID
|
||||||
|
templateId?: number;
|
||||||
|
// 插件安装状态(仅对超超管判断) 0未安装 1已安装
|
||||||
|
installed?: number;
|
||||||
|
// 特长
|
||||||
|
speciality?: string;
|
||||||
|
// 备注
|
||||||
|
comments?: string;
|
||||||
|
// 状态, 0在线, 1离线
|
||||||
|
status?: number;
|
||||||
|
// 是否删除, 0否, 1是
|
||||||
|
deleted?: number;
|
||||||
|
// 租户id
|
||||||
|
tenantId?: number;
|
||||||
|
// 注册时间
|
||||||
|
createTime?: string;
|
||||||
|
// 修改时间
|
||||||
|
updateTime?: string;
|
||||||
|
// 上传证件1
|
||||||
|
uploadImg1?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户记录表搜索条件
|
||||||
|
*/
|
||||||
|
export interface ShopUserParam extends PageParam {
|
||||||
|
userId?: number;
|
||||||
|
keywords?: string;
|
||||||
|
}
|
||||||
@@ -2,14 +2,14 @@ import {useEffect, useState, useRef} from "react";
|
|||||||
import {Loading, CellGroup, Input, Form, Radio, InputNumber, TextArea, ConfigProvider} from '@nutui/nutui-react-taro'
|
import {Loading, CellGroup, Input, Form, Radio, InputNumber, TextArea, ConfigProvider} from '@nutui/nutui-react-taro'
|
||||||
import {Edit} from '@nutui/icons-react-taro'
|
import {Edit} from '@nutui/icons-react-taro'
|
||||||
import Taro from '@tarojs/taro'
|
import Taro from '@tarojs/taro'
|
||||||
|
import {Image} from '@tarojs/components';
|
||||||
import FixedButton from "@/components/FixedButton";
|
import FixedButton from "@/components/FixedButton";
|
||||||
import {useUser} from "@/hooks/useUser";
|
|
||||||
import {updateUser} from "@/api/system/user";
|
|
||||||
import {User} from "@/api/system/user/model";
|
|
||||||
import {addShopDealerUser} from "@/api/shop/shopDealerUser";
|
|
||||||
import {listUserRole, updateUserRole} from "@/api/system/userRole";
|
|
||||||
import {DictData} from "@/api/system/dict-data/model";
|
import {DictData} from "@/api/system/dict-data/model";
|
||||||
import {listDictData} from "@/api/system/dict-data";
|
import {listDictData} from "@/api/system/dict-data";
|
||||||
|
import {addShopUser, getShopUser} from "@/api/shop/shopUser";
|
||||||
|
import {ShopUser} from "@/api/shop/shopUser/model";
|
||||||
|
import {uploadFile} from "@/api/system/file";
|
||||||
|
import {useUser} from "@/hooks/useUser";
|
||||||
|
|
||||||
const customTheme = {
|
const customTheme = {
|
||||||
nutuiInputnumberButtonWidth: '30px',
|
nutuiInputnumberButtonWidth: '30px',
|
||||||
@@ -21,97 +21,49 @@ const customTheme = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const AddApply = () => {
|
const AddApply = () => {
|
||||||
const {user, loginUser} = useUser()
|
const {user} = useUser()
|
||||||
const [loading, setLoading] = useState<boolean>(true)
|
const [loading, setLoading] = useState<boolean>(true)
|
||||||
const [FormData, setFormData] = useState<User>()
|
const [FormData, setFormData] = useState<ShopUser>()
|
||||||
const [userType, setUserType] = useState<DictData[]>()
|
const [userType, setUserType] = useState<DictData[]>()
|
||||||
const formRef = useRef<any>(null)
|
const formRef = useRef<any>(null)
|
||||||
|
|
||||||
const reload = async () => {
|
const reload = async () => {
|
||||||
listDictData({dictCode: 'UserType'}).then((data) => {
|
const userId = Taro.getStorageSync('UserId')
|
||||||
setUserType(data)
|
if(!userId || userId == '') return
|
||||||
|
const shopUser = await getShopUser(Number(Taro.getStorageSync('UserId')))
|
||||||
|
if(shopUser){
|
||||||
|
console.log(shopUser.type,'shopUsershopUsershopUsershopUsershopUsershopUsershopUser')
|
||||||
|
setFormData({
|
||||||
|
...shopUser,
|
||||||
|
type : Number(shopUser.type)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
const userType = await listDictData({dictCode: 'UserType'})
|
||||||
|
if(userType){
|
||||||
|
setUserType(userType)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 提交表单
|
// 提交表单
|
||||||
const submitSucceed = async (values: any) => {
|
const submitSucceed = async (values: any) => {
|
||||||
|
if (!FormData?.age || FormData?.age == 0) {
|
||||||
|
Taro.showToast({
|
||||||
|
title: `请填写年龄`,
|
||||||
|
icon: 'error'
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
// 验证必填字段
|
|
||||||
if (!values.phone && !FormData?.phone) {
|
|
||||||
Taro.showToast({
|
|
||||||
title: '请先获取手机号',
|
|
||||||
icon: 'error'
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 验证昵称:必须填写且不能是默认的微信昵称
|
|
||||||
const nickname = values.realName || FormData?.nickname || '';
|
|
||||||
if (!nickname || nickname.trim() === '') {
|
|
||||||
Taro.showToast({
|
|
||||||
title: '请填写昵称',
|
|
||||||
icon: 'error'
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 检查是否为默认的微信昵称(常见的默认昵称)
|
|
||||||
const defaultNicknames = ['微信用户', 'WeChat User', '微信昵称'];
|
|
||||||
if (defaultNicknames.includes(nickname.trim())) {
|
|
||||||
Taro.showToast({
|
|
||||||
title: '请填写真实昵称,不能使用默认昵称',
|
|
||||||
icon: 'error'
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 验证昵称长度
|
|
||||||
if (nickname.trim().length < 2) {
|
|
||||||
Taro.showToast({
|
|
||||||
title: '昵称至少需要2个字符',
|
|
||||||
icon: 'error'
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!values.avatar && !FormData?.avatar) {
|
|
||||||
Taro.showToast({
|
|
||||||
title: '请上传头像',
|
|
||||||
icon: 'error'
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
console.log(values,FormData)
|
|
||||||
|
|
||||||
const roles = await listUserRole({userId: user?.userId})
|
|
||||||
console.log(roles, 'roles...')
|
|
||||||
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// 准备提交的数据
|
// 准备提交的数据
|
||||||
await updateUser({
|
await addShopUser({
|
||||||
userId: user?.userId,
|
userId: Taro.getStorageSync('UserId'),
|
||||||
nickname: values.realName || FormData?.nickname,
|
type: values.type,
|
||||||
phone: values.phone || FormData?.phone,
|
username: user?.username,
|
||||||
avatar: values.avatar || FormData?.avatar,
|
nickname: user?.nickname,
|
||||||
refereeId: values.refereeId || FormData?.refereeId
|
|
||||||
});
|
|
||||||
|
|
||||||
await addShopDealerUser({
|
|
||||||
userId: user?.userId,
|
|
||||||
realName: values.realName || FormData?.nickname,
|
realName: values.realName || FormData?.nickname,
|
||||||
mobile: values.phone || FormData?.phone,
|
phone: values.phone || FormData?.phone
|
||||||
refereeId: values.refereeId || FormData?.refereeId
|
|
||||||
})
|
})
|
||||||
|
|
||||||
if (roles.length > 0) {
|
|
||||||
await updateUserRole({
|
|
||||||
...roles[0],
|
|
||||||
roleId: 1848
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Taro.showToast({
|
Taro.showToast({
|
||||||
title: `注册成功`,
|
title: `注册成功`,
|
||||||
icon: 'success'
|
icon: 'success'
|
||||||
@@ -136,17 +88,25 @@ const AddApply = () => {
|
|||||||
console.log(error, 'err...')
|
console.log(error, 'err...')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const uploadImg1 = () => {
|
||||||
|
uploadFile().then(data => {
|
||||||
|
setFormData({
|
||||||
|
...FormData,
|
||||||
|
uploadImg1: data.url
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
reload().then(() => {
|
reload().then(() => {
|
||||||
setLoading(false)
|
setLoading(false)
|
||||||
})
|
})
|
||||||
}, [user?.userId]); // 依赖用户ID,当用户变化时重新加载
|
}, []); // 依赖用户ID,当用户变化时重新加载
|
||||||
|
|
||||||
// 当FormData变化时,同步更新表单字段值
|
// 当FormData变化时,同步更新表单字段值
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (formRef.current && FormData) {
|
if (formRef.current && FormData) {
|
||||||
formRef.current.setFieldsValue({
|
formRef.current.setFieldsValue({
|
||||||
refereeId: FormData.refereeId,
|
|
||||||
phone: FormData.phone,
|
phone: FormData.phone,
|
||||||
avatar: FormData.avatar,
|
avatar: FormData.avatar,
|
||||||
realName: FormData.nickname
|
realName: FormData.nickname
|
||||||
@@ -172,7 +132,7 @@ const AddApply = () => {
|
|||||||
{JSON.stringify(FormData)}
|
{JSON.stringify(FormData)}
|
||||||
<Form.Item label="用户类型" name="type" initialValue={FormData?.type} required>
|
<Form.Item label="用户类型" name="type" initialValue={FormData?.type} required>
|
||||||
<Radio.Group
|
<Radio.Group
|
||||||
defaultValue="1"
|
defaultValue="0"
|
||||||
direction="horizontal"
|
direction="horizontal"
|
||||||
value={FormData?.type}
|
value={FormData?.type}
|
||||||
onChange={(value: any) => {
|
onChange={(value: any) => {
|
||||||
@@ -193,10 +153,10 @@ const AddApply = () => {
|
|||||||
<Input
|
<Input
|
||||||
placeholder={'请填写真实姓名'}
|
placeholder={'请填写真实姓名'}
|
||||||
value={FormData?.realName || ''}
|
value={FormData?.realName || ''}
|
||||||
onChange={(e) => {
|
onChange={(value) => {
|
||||||
setFormData({
|
setFormData({
|
||||||
...FormData,
|
...FormData,
|
||||||
realName: e.detail.value
|
realName: value
|
||||||
})
|
})
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
@@ -214,17 +174,17 @@ const AddApply = () => {
|
|||||||
</Radio>
|
</Radio>
|
||||||
</Radio.Group>
|
</Radio.Group>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item label="年龄" name="age" initialValue={FormData?.age || 18} required>
|
<Form.Item label="年龄" name="age" initialValue={FormData?.age} required>
|
||||||
<ConfigProvider theme={customTheme}>
|
<ConfigProvider theme={customTheme}>
|
||||||
<InputNumber
|
<InputNumber
|
||||||
value={FormData?.age || 18}
|
value={FormData?.age}
|
||||||
onChange={(value) => {
|
onChange={(value) => {
|
||||||
setFormData({
|
setFormData({
|
||||||
...FormData,
|
...FormData,
|
||||||
age: Number(value)
|
age: Number(value)
|
||||||
})
|
})
|
||||||
}}
|
}}
|
||||||
min={1}
|
min={0}
|
||||||
max={120}
|
max={120}
|
||||||
step={1}
|
step={1}
|
||||||
/>
|
/>
|
||||||
@@ -240,6 +200,34 @@ const AddApply = () => {
|
|||||||
value={FormData?.introduction || ''}
|
value={FormData?.introduction || ''}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
{FormData?.type == 1 && (
|
||||||
|
<>
|
||||||
|
<Form.Item label="证书编号" name="userCode" required>
|
||||||
|
<Input
|
||||||
|
placeholder={'请填证书编号'}
|
||||||
|
value={FormData?.userCode || ''}
|
||||||
|
onChange={(value) => {
|
||||||
|
setFormData({
|
||||||
|
...FormData,
|
||||||
|
idCard: value
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={'上传证件'}
|
||||||
|
name="uploadImg1"
|
||||||
|
required
|
||||||
|
rules={[{message: '请上传医师资格证书'}
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<div onClick={uploadImg1}>
|
||||||
|
<Image src={FormData.uploadImg1 || ''} mode={'scaleToFill'} lazyLoad={false} />
|
||||||
|
</div>
|
||||||
|
</Form.Item>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
|
||||||
</CellGroup>
|
</CellGroup>
|
||||||
</Form>
|
</Form>
|
||||||
|
|
||||||
|
|||||||
@@ -1,25 +0,0 @@
|
|||||||
import {Image, Cell} from '@nutui/nutui-react-taro'
|
|
||||||
import Taro from '@tarojs/taro'
|
|
||||||
|
|
||||||
const ArticleList = (props: any) => {
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<div className={'px-3'}>
|
|
||||||
{props.data.map((item, index) => {
|
|
||||||
return (
|
|
||||||
<Cell
|
|
||||||
title={item.title}
|
|
||||||
extra={
|
|
||||||
<Image src={item.image} mode={'aspectFit'} lazyLoad={false} width={100} height="100"/>
|
|
||||||
}
|
|
||||||
key={index}
|
|
||||||
onClick={() => Taro.navigateTo({url: '/cms/detail/index?id=' + item.articleId})}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
})}
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
export default ArticleList
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
import {useEffect, useState} from "react";
|
|
||||||
import {Tabs, Loading} from '@nutui/nutui-react-taro'
|
|
||||||
import {pageCmsArticle} from "@/api/cms/cmsArticle";
|
|
||||||
import {CmsArticle} from "@/api/cms/cmsArticle/model";
|
|
||||||
import ArticleList from "./ArticleList";
|
|
||||||
|
|
||||||
const ArticleTabs = (props: any) => {
|
|
||||||
const [loading, setLoading] = useState<boolean>(true)
|
|
||||||
const [tab1value, setTab1value] = useState<string | number>('0')
|
|
||||||
const [list, setList] = useState<CmsArticle[]>([])
|
|
||||||
|
|
||||||
const reload = async (value) => {
|
|
||||||
const {data} = props
|
|
||||||
pageCmsArticle({
|
|
||||||
categoryId: data[value].navigationId,
|
|
||||||
page: 1,
|
|
||||||
status: 0,
|
|
||||||
limit: 10
|
|
||||||
}).then((res) => {
|
|
||||||
res && setList(res?.list || [])
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
console.log(err)
|
|
||||||
})
|
|
||||||
.finally(() => {
|
|
||||||
setTab1value(value)
|
|
||||||
setLoading(false)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
reload(0).then()
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
if (loading) {
|
|
||||||
return (
|
|
||||||
<Loading className={'px-2'}>加载中</Loading>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Tabs
|
|
||||||
value={tab1value}
|
|
||||||
onChange={(value) => {
|
|
||||||
reload(value).then()
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{props.data?.map((item, index) => {
|
|
||||||
return (
|
|
||||||
<Tabs.TabPane title={item.categoryName} key={index}/>
|
|
||||||
)
|
|
||||||
})}
|
|
||||||
</Tabs>
|
|
||||||
<ArticleList data={list}/>
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
export default ArticleTabs
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
import { useEffect, useState } from 'react'
|
|
||||||
import { Swiper } from '@nutui/nutui-react-taro'
|
|
||||||
import {CmsAd} from "@/api/cms/cmsAd/model";
|
|
||||||
import {Image} from '@nutui/nutui-react-taro'
|
|
||||||
import {getCmsAd} from "@/api/cms/cmsAd";
|
|
||||||
|
|
||||||
const MyPage = () => {
|
|
||||||
const [item, setItem] = useState<CmsAd>()
|
|
||||||
const reload = () => {
|
|
||||||
getCmsAd(439).then(data => {
|
|
||||||
setItem(data)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
reload()
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Swiper defaultValue={0} height={item?.height} indicator style={{ height: item?.height + 'px', display: 'none' }}>
|
|
||||||
{item?.imageList?.map((item) => (
|
|
||||||
<Swiper.Item key={item}>
|
|
||||||
<Image width="100%" height="100%" src={item.url} mode={'scaleToFill'} lazyLoad={false} style={{ height: item.height + 'px' }} />
|
|
||||||
</Swiper.Item>
|
|
||||||
))}
|
|
||||||
</Swiper>
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
export default MyPage
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
export default definePageConfig({
|
|
||||||
navigationBarTitleText: '文章列表',
|
|
||||||
navigationBarTextStyle: 'black'
|
|
||||||
})
|
|
||||||
@@ -1,71 +0,0 @@
|
|||||||
import Taro from '@tarojs/taro'
|
|
||||||
import {useShareAppMessage} from "@tarojs/taro"
|
|
||||||
import {Loading} from '@nutui/nutui-react-taro'
|
|
||||||
import {useEffect, useState} from "react"
|
|
||||||
import {useRouter} from '@tarojs/taro'
|
|
||||||
import {getCmsNavigation, listCmsNavigation} from "@/api/cms/cmsNavigation";
|
|
||||||
import {CmsNavigation} from "@/api/cms/cmsNavigation/model";
|
|
||||||
import {pageCmsArticle} from "@/api/cms/cmsArticle";
|
|
||||||
import {CmsArticle} from "@/api/cms/cmsArticle/model";
|
|
||||||
import ArticleList from './components/ArticleList'
|
|
||||||
import ArticleTabs from "./components/ArticleTabs";
|
|
||||||
import './index.scss'
|
|
||||||
|
|
||||||
function Category() {
|
|
||||||
const {params} = useRouter();
|
|
||||||
const [categoryId, setCategoryId] = useState<number>(0)
|
|
||||||
const [category, setCategory] = useState<CmsNavigation[]>([])
|
|
||||||
const [loading, setLoading] = useState<boolean>(true)
|
|
||||||
const [nav, setNav] = useState<CmsNavigation>()
|
|
||||||
const [list, setList] = useState<CmsArticle[]>([])
|
|
||||||
|
|
||||||
const reload = async () => {
|
|
||||||
// 1.加载远程数据
|
|
||||||
const id = Number(params.id || 4328)
|
|
||||||
const nav = await getCmsNavigation(id)
|
|
||||||
const categoryList = await listCmsNavigation({parentId: id})
|
|
||||||
const shopGoods = await pageCmsArticle({categoryId: id})
|
|
||||||
|
|
||||||
// 2.赋值
|
|
||||||
setCategoryId(id)
|
|
||||||
setNav(nav)
|
|
||||||
setList(shopGoods?.list || [])
|
|
||||||
setCategory(categoryList)
|
|
||||||
Taro.setNavigationBarTitle({
|
|
||||||
title: `${nav?.categoryName}`
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
reload().then(() => {
|
|
||||||
setLoading(false)
|
|
||||||
})
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
useShareAppMessage(() => {
|
|
||||||
return {
|
|
||||||
title: `${nav?.categoryName}_通源堂健康生态平台`,
|
|
||||||
path: `/shop/category/index?id=${categoryId}`,
|
|
||||||
success: function () {
|
|
||||||
console.log('分享成功');
|
|
||||||
},
|
|
||||||
fail: function () {
|
|
||||||
console.log('分享失败');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
if (loading) {
|
|
||||||
return (
|
|
||||||
<Loading className={'px-2'}>加载中</Loading>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if(category.length > 0){
|
|
||||||
return <ArticleTabs data={category}/>
|
|
||||||
}
|
|
||||||
|
|
||||||
return <ArticleList data={list}/>
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Category
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
export default definePageConfig({
|
|
||||||
navigationBarTitleText: '文章详情'
|
|
||||||
})
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
import Taro from '@tarojs/taro'
|
|
||||||
import {useEffect, useState} from 'react'
|
|
||||||
import {useRouter} from '@tarojs/taro'
|
|
||||||
import {Loading} from '@nutui/nutui-react-taro'
|
|
||||||
import {View, RichText} from '@tarojs/components'
|
|
||||||
import {wxParse} from "@/utils/common";
|
|
||||||
import {getCmsArticle} from "@/api/cms/cmsArticle";
|
|
||||||
import {CmsArticle} from "@/api/cms/cmsArticle/model"
|
|
||||||
import Line from "@/components/Gap";
|
|
||||||
import './index.scss'
|
|
||||||
|
|
||||||
function Detail() {
|
|
||||||
const {params} = useRouter();
|
|
||||||
const [loading, setLoading] = useState<boolean>(true)
|
|
||||||
// 文章详情
|
|
||||||
const [item, setItem] = useState<CmsArticle>()
|
|
||||||
const reload = async () => {
|
|
||||||
const item = await getCmsArticle(Number(params.id))
|
|
||||||
|
|
||||||
if (item) {
|
|
||||||
item.content = wxParse(item.content)
|
|
||||||
setItem(item)
|
|
||||||
Taro.setNavigationBarTitle({
|
|
||||||
title: `${item?.categoryName}`
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
reload().then(() => {
|
|
||||||
setLoading(false)
|
|
||||||
});
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
if (loading) {
|
|
||||||
return (
|
|
||||||
<Loading className={'px-2'}>加载中</Loading>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className={'bg-white'}>
|
|
||||||
<div className={'p-4 font-bold text-lg'}>{item?.title}</div>
|
|
||||||
<div className={'text-gray-400 text-sm px-4 '}>{item?.createTime}</div>
|
|
||||||
<View className={'content p-4'}>
|
|
||||||
<RichText nodes={item?.content}/>
|
|
||||||
</View>
|
|
||||||
<Line height={44}/>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Detail
|
|
||||||
@@ -61,10 +61,10 @@ const getBaseUrl = (): string => {
|
|||||||
if (configStr) {
|
if (configStr) {
|
||||||
// 如果是字符串,需要解析为对象
|
// 如果是字符串,需要解析为对象
|
||||||
const config = typeof configStr === 'string' ? JSON.parse(configStr) : configStr;
|
const config = typeof configStr === 'string' ? JSON.parse(configStr) : configStr;
|
||||||
console.log('获取后台配置API地址:', config);
|
// console.log('获取后台配置API地址:', config);
|
||||||
// 注意属性名是 ApiUrl(首字母大写),不是 apiUrl
|
// 注意属性名是 ApiUrl(首字母大写),不是 apiUrl
|
||||||
if (config && config.ApiUrl) {
|
if (config && config.ApiUrl) {
|
||||||
console.log('使用后台配置的API地址:', config.ApiUrl);
|
// console.log('使用后台配置的API地址:', config.ApiUrl);
|
||||||
return config.ApiUrl;
|
return config.ApiUrl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user