提交 87957d9f 作者: ZhangLingKun

Merge branch 'develop'

...@@ -47,6 +47,7 @@ ...@@ -47,6 +47,7 @@
], ],
"jsx-a11y/click-events-have-key-events": "off", "jsx-a11y/click-events-have-key-events": "off",
"jsx-a11y/no-static-element-interactions": "off", "jsx-a11y/no-static-element-interactions": "off",
"react/display-name": "off" "react/display-name": "off",
"jsx-a11y/no-noninteractive-element-interactions": 'off'
} }
} }
...@@ -31,6 +31,14 @@ jobs: ...@@ -31,6 +31,14 @@ jobs:
- name: Checkout - name: Checkout
uses: actions/checkout@v3 uses: actions/checkout@v3
- name: WeChat Work notification by text
uses: chf007/action-wechat-work@master
env:
WECHAT_WORK_BOT_WEBHOOK: https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=9be1b073-1760-442d-8e3d-faa0fd32ea16
with:
msgtype: text
content: "GitHub提交信息\n - 提交人: ${{github.actor}}\n - 提交信息: ${{ github.event.head_commit.message }}\n - 提交到仓库: ${{github.repository}}\n - 提交到分支: ${{github.ref}}\n 即将开始更新,请关注Argocd同步状态..."
- name: Login to ACR EE with the AccessKey pair - name: Login to ACR EE with the AccessKey pair
uses: aliyun/acr-login@v1 uses: aliyun/acr-login@v1
with: with:
......
#请求接口地址 #请求接口地址
#VITE_REQUEST_BASE_URL='https://www.iuav.shop' #VITE_REQUEST_BASE_URL='https://www.iuav.shop'
VITE_REQUEST_BASE_URL='https://test.iuav.shop' VITE_REQUEST_BASE_URL='https://test.iuav.shop' // 测试服
#VITE_REQUEST_BASE_URL='https://iuav.mmcuav.cn' #VITE_REQUEST_BASE_URL='https://iuav.mmcuav.cn'
#VITE_REQUEST_BASE_URL='/api' #VITE_REQUEST_BASE_URL='/api'
#旧版接口地址 #旧版接口地址
......
...@@ -4,7 +4,7 @@ metadata: ...@@ -4,7 +4,7 @@ metadata:
name: admin-deployment name: admin-deployment
namespace: default namespace: default
spec: spec:
minReadySeconds: 5 minReadySeconds: 10
revisionHistoryLimit: 2 revisionHistoryLimit: 2
replicas: 1 replicas: 1
selector: selector:
...@@ -27,6 +27,7 @@ spec: ...@@ -27,6 +27,7 @@ spec:
cpu: 100m cpu: 100m
ports: ports:
- containerPort: 80 - containerPort: 80
name: admin-port
volumes: volumes:
- name: log-of-nginx - name: log-of-nginx
hostPath: hostPath:
......
...@@ -3,9 +3,9 @@ kind: Deployment ...@@ -3,9 +3,9 @@ kind: Deployment
metadata: metadata:
name: admin-deployment name: admin-deployment
spec: spec:
replicas: 2 replicas: 1
strategy: strategy:
type: RollingUpdate type: RollingUpdate
rollingUpdate: rollingUpdate:
maxSurge: 1 maxSurge: 1
maxUnavailable: 1 maxUnavailable: 0
\ No newline at end of file
...@@ -14,4 +14,4 @@ patches: ...@@ -14,4 +14,4 @@ patches:
images: images:
- name: REGISTRY/NAMESPACE/IMAGE:TAG - name: REGISTRY/NAMESPACE/IMAGE:TAG
newName: mmc-registry.cn-shenzhen.cr.aliyuncs.com/sharefly-dev/admin newName: mmc-registry.cn-shenzhen.cr.aliyuncs.com/sharefly-dev/admin
newTag: c533f36fd07802ddc4791dbaaf1a0b66e0a38222 newTag: 682d7c8f7979b4524ab8018ee5e4ffc04baf18ed
...@@ -60,7 +60,7 @@ ...@@ -60,7 +60,7 @@
"prettier": "^2.6.2", "prettier": "^2.6.2",
"sass": "^1.62.0", "sass": "^1.62.0",
"typescript": "^4.6.3", "typescript": "^4.6.3",
"vite": "^4.3.5", "vite": "^4.3.9",
"vite-tsconfig-paths": "^3.5.0" "vite-tsconfig-paths": "^3.5.0"
} }
} }
...@@ -10,6 +10,8 @@ import { CategoryManageAPI } from './modules/categoryManage'; ...@@ -10,6 +10,8 @@ import { CategoryManageAPI } from './modules/categoryManage';
import { SystemManageAPI } from './modules/systemManage'; import { SystemManageAPI } from './modules/systemManage';
import { CustomManageAPI } from './modules/customManage'; import { CustomManageAPI } from './modules/customManage';
import { MallManageAPI } from './modules/mallManage'; import { MallManageAPI } from './modules/mallManage';
import { ResourceManageAPI } from './modules/resourceManageAPI';
import { ForumManageAPI } from './modules/forumManageAPI';
export { export {
CommonAPI, CommonAPI,
...@@ -24,4 +26,6 @@ export { ...@@ -24,4 +26,6 @@ export {
SystemManageAPI, SystemManageAPI,
CustomManageAPI, CustomManageAPI,
MallManageAPI, MallManageAPI,
ResourceManageAPI,
ForumManageAPI,
}; };
...@@ -29,6 +29,14 @@ export type listAppUserType = InterListFunction< ...@@ -29,6 +29,14 @@ export type listAppUserType = InterListFunction<
cooperationTagId: number; cooperationTagId: number;
companyName: null; companyName: null;
tagName: null; tagName: null;
cooperationTagVOS: {
createTime: string;
id: number;
tagDescription: string;
tagImg: string;
tagName: string;
tagRequire: string;
}[];
} }
>; >;
// 加盟标签列表 // 加盟标签列表
...@@ -75,3 +83,78 @@ export type changeUserTagType = InterFunction< ...@@ -75,3 +83,78 @@ export type changeUserTagType = InterFunction<
}, },
NonNullable<unknown> NonNullable<unknown>
>; >;
// 后台设置小程序用户标签
export type changeUserTagNew = InterFunction<
{
cooperationTagIds: number[];
userAccountId: number;
},
NonNullable<unknown>
>;
// 加盟标签列表
export type cooperationListTag = InterFunction<
NonNullable<unknown>,
{
createTime: string;
id: number;
tagDescription: string;
tagImg: string;
tagName: string;
}[]
>;
// 后台申请列表
export type listUserApplyTag = InterListFunction<
{
applyStatus?: number;
cooperationTagId?: number;
endTime?: string;
startTime?: string;
},
{
applyName: string;
applyPhone: string;
applyTime: string;
approvalStatus: number;
attachmentList: null;
cooperationTagId: number;
cooperationTagName: string;
id: number;
remark: string;
userAccountId: number;
}
>;
// 审批详情
export type applyTagDetails = InterFunction<
{
id?: number;
userAccountId?: number;
},
{
attachmentList: {
/**
* 附件类型:0:图片 1:文件
*/
type: number;
url: string;
}[];
companyName: string;
creditCode: string;
licenseImg: string;
remark: string;
}
>;
// 审批
export type approvalApplyTag = InterFunction<
{
id: number;
status: boolean;
},
NonNullable<unknown>
>;
// 强制删除
export type deleteApplyTag = InterFunction<
{
id: number;
},
NonNullable<unknown>
>;
import { InterFunction, InterItemFunction } from '~/api/interface';
//论坛-列表
export type forumListType = InterItemFunction<
{ keyword?: string },
{
description: string;
userBaseInfo: {
nickName: string;
phone: string;
uid: string;
userImg: string;
userName: string;
};
show: number;
id: number;
}[]
>;
//论坛-删除
export type deleteForumType = InterFunction<{ dynamicId: number }, any>;
//论坛-隐藏
export type hiddenForumType = InterFunction<{ dynamicId: number }, any>;
//论坛-详情
type detailResponseType = {
userBaseInfo: {
nickName: string;
phone: string;
uid: string;
userImg: string;
userName: string;
};
description: string;
dynamicPublishTime: string;
id: number;
likes: boolean;
likesCount: number;
mediaVO: { type: number; url: string }[];
commentCount: number;
commentAndReplyVO: detailResponseType[];
};
export type forumDetailType = InterFunction<{ dynamicId: number }, detailResponseType>;
//论坛-点赞信息
export type likeUserInfoType = InterFunction<
{ dynamicId: number },
{ nickName: string; userImg: string; userName: string }[]
>;
...@@ -305,19 +305,19 @@ export type orderDetailType = InterFunction< ...@@ -305,19 +305,19 @@ export type orderDetailType = InterFunction<
// 后台管理——发货-订单/ 卖家发货 // 后台管理——发货-订单/ 卖家发货
export type sendOrderWareType = InterFunction< export type sendOrderWareType = InterFunction<
{ {
authPwd: string; authPwd?: string;
imgs: Array<string>; imgs?: Array<string>;
orderInfoId: number; orderInfoId?: number;
orderRefundId: number; orderRefundId?: number;
remark: string; remark?: string;
renAddress: string; renAddress?: string;
renName: string; renName?: string;
renPhone: string; renPhone?: string;
sendAddress: string; sendAddress?: string;
sendExCode: string; sendExCode?: string;
sendExNo: string; sendExNo?: string;
vcuSatus: number; vcuSatus?: number;
videoUrl: string; videoUrl?: string;
}, },
NonNullable<unknown> NonNullable<unknown>
>; >;
......
import { InterFunction, InterItemFunction, InterListFunction } from '~/api/interface';
//需求列表
export type listPublishPageType = InterItemFunction<
{ requirementTypeId?: number; keyword?: string },
{
id: number;
publishName: string;
publishPhone: string;
requireDescription: string;
requirementTypeId: number;
requirementTypeName: string;
}[]
>;
//需求类型列表
export type requirementsListType = InterFunction<any, { id: number; typeName: string }[]>;
//需求-强制删除
export type deleteRequirementsType = InterFunction<{ requirementsInfoId: number }, any>;
// 查询招标快讯列表-分页
export type releaseTenderNews = InterListFunction<
{
endTime?: string;
startTime?: string;
tenderName?: string;
using?: number;
},
{
createTime: Date;
id: number;
port: number;
tenderName: string;
using: number;
}
>;
// 新增招标快讯
export type releaseTenderNewsAdd = InterFunction<any, any>;
// 修改招标快讯
export type releaseTenderNewsUpdate = InterFunction<any, any>;
// 删除招标快讯
export type releaseTenderNewsDelete = InterFunction<{ id: number }, any>;
// 查询-招标快讯详情列表-分页
export type releaseTenderNewsInfo = InterListFunction<
{
tenderNewsId?: number;
},
{
createTime: string;
id: number;
tenderContent: string;
tenderInfoNo: string;
tenderNewsId: number;
tenderPrice: number;
tenderTitle: string;
}
>;
// 修改-招标快讯详情
export type releaseTenderNewsInfoUpdate = InterListFunction<
{
id: number;
tenderContent?: string;
tenderPrice?: number;
tenderTitle?: string;
},
NonNullable<unknown>
>;
// 用户反馈列表-分页
export type releaseTenderNewsApplyList = InterListFunction<
{
tenderInfoId?: number;
tenderNewsId?: number;
userName?: string;
},
{
createTime: string;
id: number;
nickName: string;
phoneNum: string;
tenderInfoId: number;
tenderInfoNo: string;
tenderTitle: string;
userName: string;
}
>;
//行业新闻-列表
export type industryNewsListType = InterItemFunction<
{ newsTitle?: string },
{
id: number;
createTime: string;
newsAuthor: string;
newsContents: string;
newsTitle: string;
origin: string;
surfaceImg: string;
}[]
>;
//行业新闻-新增
export type addIndustryNewsType = InterFunction<
{
newsAuthor: string;
newsContents?: string;
newsTitle: string;
origin: string;
surfaceImg: string;
},
any
>;
//行业新闻-编辑
export type editIndustryNews = InterFunction<
{
newsAuthor: string;
newsContents?: string;
newsTitle: string;
origin: string;
surfaceImg: string;
id?: number;
},
any
>;
//行业新闻-删除
export type deleteIndustryNewsType = InterFunction<{ id: number }, any>;
//行业新闻-详情
export type industryNewsDetailType = InterFunction<
{ id: number },
{
id: number;
createTime: string;
newsAuthor: string;
newsContents: string;
newsTitle: string;
origin: string;
surfaceImg: string;
}
>;
// 案例列表
export type industryCaseListCasePage = InterListFunction<
{
cityCode?: number;
date?: string;
districtCode?: number;
keyword?: string;
provinceCode?: number;
requirementTypeId?: number;
},
{
caseAuthor: string;
caseContents: string;
caseTitle: string;
createTime: string;
id: number;
origin: string;
surfaceImg: null;
updateTime: string;
userAccountId: number;
}
>;
// 添加业务案例
export type industryCaseAddCase = InterFunction<
{
caseAuthor?: string;
caseContents?: string;
caseTitle?: string;
createTime?: string;
id?: number;
origin?: string;
surfaceImg?: string;
updateTime?: string;
userAccountId?: number;
},
NonNullable<unknown>
>;
// 修改业务案例
export type industryCaseUpdateCase = InterFunction<
{
caseAuthor?: string;
caseContents?: string;
caseTitle?: string;
createTime?: string;
id?: number;
origin?: string;
surfaceImg?: string;
updateTime?: string;
userAccountId?: number;
},
NonNullable<unknown>
>;
// 删除业务案例
export type industryCaseDeleteDetails = InterFunction<{ id: number }, NonNullable<unknown>>;
import axios from '../request'; import axios from '../request';
import { import {
applyTagDetails,
approvalApplyTag,
changeUserTagNew,
changeUserTagType, changeUserTagType,
CompanyListTag, CompanyListTag,
cooperationListTag,
deleteApplyTag,
listAppUserType, listAppUserType,
listUserApplyTag,
userAccountUpdateType, userAccountUpdateType,
} from '~/api/interface/customManageType'; } from '~/api/interface/customManageType';
...@@ -19,4 +25,22 @@ export class CustomManageAPI { ...@@ -19,4 +25,22 @@ export class CustomManageAPI {
// 后台设置小程序用户标签 // 后台设置小程序用户标签
static changeUserTag: changeUserTagType = (params) => static changeUserTag: changeUserTagType = (params) =>
axios.get('/userapp/cooperation/changeUserTag', { params }); axios.get('/userapp/cooperation/changeUserTag', { params });
// 后台设置小程序用户标签
static changeUserTagNew: changeUserTagNew = (params) =>
axios.post('/userapp/cooperation/changeUserTag', params);
// 加盟标签列表
static cooperationListTag: cooperationListTag = (params) =>
axios.get('/userapp/cooperation/listTag', { params });
// 后台申请列表
static listUserApplyTag: listUserApplyTag = (params) =>
axios.post('/userapp/cooperation/listUserApplyTag', params);
// 审批详情
static applyTagDetails: applyTagDetails = (params) =>
axios.get('/userapp/cooperation/applyTagDetails', { params });
// 审批
static approvalApplyTag: approvalApplyTag = (params) =>
axios.get('/userapp/cooperation/approvalApplyTag', { params });
// 强制删除
static deleteApplyTag: deleteApplyTag = (params) =>
axios.get('/userapp/cooperation/deleteApplyTag', { params });
} }
import {
deleteForumType,
forumDetailType,
forumListType,
hiddenForumType,
likeUserInfoType,
} from '~/api/interface/forumManageType';
import axios from '~/api/request';
export class ForumManageAPI {
//论坛-列表
static getForumList: forumListType = (data) =>
axios.post('/release/backstage/forum/listDynamic', data);
//论坛-删除
static deleteForum: deleteForumType = (params) =>
axios.get('/release/backstage/forum/deleteDynamic', { params });
//论坛-隐藏
static hiddenForum: hiddenForumType = (params) =>
axios.get('/release/backstage/forum/hiddenDynamic', { params });
// 论坛-详情
static getForumDetail: forumDetailType = (params) =>
axios.get('/release/dynamic/dynamicDetails', { params });
// 论坛-点赞人信息
static getLikeUserInfoList: likeUserInfoType = (params) =>
axios.get('/release/backstage/forum/likeUserInfo', { params });
}
import {
listPublishPageType,
requirementsListType,
releaseTenderNews,
releaseTenderNewsAdd,
releaseTenderNewsDelete,
releaseTenderNewsUpdate,
releaseTenderNewsInfo,
releaseTenderNewsInfoUpdate,
releaseTenderNewsApplyList,
addIndustryNewsType,
industryNewsListType,
editIndustryNews,
industryNewsDetailType,
industryCaseListCasePage,
industryCaseAddCase,
industryCaseUpdateCase,
industryCaseDeleteDetails,
deleteIndustryNewsType,
deleteRequirementsType,
} from '~/api/interface/resourceManageType';
import axios from '../request';
export class ResourceManageAPI {
//需求列表
static getListPublishPage: listPublishPageType = (data) =>
axios.post('/release/requirements/listPublishPage', data);
// 需求类型列表
static getRequirementTypeList: requirementsListType = () =>
axios.get('/release/requirements/listType');
//需求-强制删除
static deleteRequirement: deleteRequirementsType = (params) =>
axios.get('/release/requirements/deleteRequire', { params });
// 查询招标快讯列表-分页
static releaseTenderNews: releaseTenderNews = (params) =>
axios.get('/release/tender/news', { params });
// 新增招标快讯
static releaseTenderNewsAdd: releaseTenderNewsAdd = (params) =>
axios.post('/release/tender/news', params);
// 修改招标快讯
static releaseTenderNewsUpdate: releaseTenderNewsUpdate = (params) =>
axios.put('/release/tender/news', params);
// 删除招标快讯
static releaseTenderNewsDelete: releaseTenderNewsDelete = (params) =>
axios.delete(`/release/tender/news/${params?.id}`);
// 查询-招标快讯详情列表-分页
static releaseTenderNewsInfo: releaseTenderNewsInfo = (params) =>
axios.get('/release/tender/info', { params });
// 修改-招标快讯详情
static releaseTenderNewsInfoUpdate: releaseTenderNewsInfoUpdate = (params) =>
axios.put('/release/tender/info', params);
// 用户反馈列表-分页
static releaseTenderNewsApplyList: releaseTenderNewsApplyList = (params) =>
axios.post('/release/tender/applyList', params);
// 行业新闻-新增
static addIndustryNews: addIndustryNewsType = (data) =>
axios.post('/release/industry-news/insertIndustryNews', data);
// 行业新闻-列表
static getIndustryNewsList: industryNewsListType = (data) =>
axios.post('/release/industry-news/backgroundListNewsPage', data);
// 行业新闻-编辑
static editIndustryNews: editIndustryNews = (data) =>
axios.post('/release/industry-news/upDateIndustryNews', data);
// 行业新闻-详情
static getIndustryNewsDetail: industryNewsDetailType = (params) =>
axios.get('/release/industry-news/details', { params });
// 行业新闻-删除
static removeIndustryNews: deleteIndustryNewsType = (params) =>
axios.get('/release/industry-news/deleteIndustryNews', { params });
// 案例列表
static industryCaseListCasePage: industryCaseListCasePage = (params) =>
axios.post('/release/industry-case/listCasePage', params);
// 添加业务案例
static industryCaseAddCase: industryCaseAddCase = (params) =>
axios.post('/release/industry-case/addCase', params);
// 修改业务案例
static industryCaseUpdateCase: industryCaseUpdateCase = (params) =>
axios.post('/release/industry-case/updateCase', params);
// 删除业务案例
static industryCaseDeleteDetails: industryCaseDeleteDetails = (params) =>
axios.get('/release/industry-case/deleteDetails', { params });
}
...@@ -18,7 +18,7 @@ export class SystemManageAPI { ...@@ -18,7 +18,7 @@ export class SystemManageAPI {
// 账号-删除 // 账号-删除
static removeBAccount: removeBAccountType = (params) => static removeBAccount: removeBAccountType = (params) =>
axios.get('/userapp/back-user/removeBAccount', { params }); axios.get('/userapp/user-account/removeAppAccount', { params });
// 账号-修改 // 账号-修改
static updateBAccount: updateBAccountType = (params) => static updateBAccount: updateBAccountType = (params) =>
......
import React, { useEffect } from 'react'; import React, { useEffect } from 'react';
import E from 'wangeditor'; import E from 'wangeditor';
import { message } from 'antd'; import { message } from 'antd';
// import events from '@/events';
import { CommonAPI } from '~/api'; import { CommonAPI } from '~/api';
let editor: any = null; let editor: any = null;
interface PropsType { interface PropsType {
onChange: (html?: string) => void; onChange?: (html?: string) => void;
value: string | undefined; value: string | undefined;
// eslint-disable-next-line react/require-default-props // eslint-disable-next-line react/require-default-props
isDetail?: boolean; isDetail?: boolean;
height?: number; height?: number;
} }
const RichText: React.FC<PropsType> = ({ onChange, value, isDetail, height }) => { const RichText: React.FC<PropsType> = ({ onChange, value, isDetail, height }) => {
RichText.defaultProps = {
// eslint-disable-next-line @typescript-eslint/no-empty-function
onChange: () => {},
};
useEffect(() => { useEffect(() => {
// 注:class写法需要在componentDidMount 创建编辑器 // 注:class写法需要在componentDidMount 创建编辑器
editor = new E('.edit'); editor = new E('.edit');
...@@ -40,9 +42,9 @@ const RichText: React.FC<PropsType> = ({ onChange, value, isDetail, height }) => ...@@ -40,9 +42,9 @@ const RichText: React.FC<PropsType> = ({ onChange, value, isDetail, height }) =>
}; };
editor.config.onchange = (newHtml: string) => { editor.config.onchange = (newHtml: string) => {
if (newHtml) { if (newHtml) {
onChange(newHtml); onChange?.(newHtml);
} else { } else {
onChange(undefined); onChange?.(undefined);
} }
}; };
......
...@@ -2,6 +2,8 @@ import React, { useEffect, useState } from 'react'; ...@@ -2,6 +2,8 @@ import React, { useEffect, useState } from 'react';
import { message, Upload, UploadProps } from 'antd'; import { message, Upload, UploadProps } from 'antd';
import { CommonAPI } from '~/api'; import { CommonAPI } from '~/api';
import './index.scss'; import './index.scss';
import Viewer from '~/components/viewer';
import saveAs from 'file-saver';
interface PropsType { interface PropsType {
listType?: 'text' | 'picture' | 'picture-card'; // 上传列表的内建样式 listType?: 'text' | 'picture' | 'picture-card'; // 上传列表的内建样式
...@@ -19,6 +21,7 @@ interface PropsType { ...@@ -19,6 +21,7 @@ interface PropsType {
}[], }[],
) => void; // 上传文件改变时的状态 ) => void; // 上传文件改变时的状态
defaultFileList?: any[]; // 默认文件列表 defaultFileList?: any[]; // 默认文件列表
disabled?: boolean; // 是否禁用
} }
export const Uploader: React.FC<PropsType> = (props) => { export const Uploader: React.FC<PropsType> = (props) => {
Uploader.defaultProps = { Uploader.defaultProps = {
...@@ -29,6 +32,7 @@ export const Uploader: React.FC<PropsType> = (props) => { ...@@ -29,6 +32,7 @@ export const Uploader: React.FC<PropsType> = (props) => {
// eslint-disable-next-line @typescript-eslint/no-empty-function // eslint-disable-next-line @typescript-eslint/no-empty-function
onChange: () => {}, onChange: () => {},
defaultFileList: [], defaultFileList: [],
disabled: false,
}; };
const { const {
fileType = ['image/png', 'image/jpeg', 'image/jpg', 'image/gif', 'image/bmp'], fileType = ['image/png', 'image/jpeg', 'image/jpg', 'image/gif', 'image/bmp'],
...@@ -39,7 +43,13 @@ export const Uploader: React.FC<PropsType> = (props) => { ...@@ -39,7 +43,13 @@ export const Uploader: React.FC<PropsType> = (props) => {
fileLength, fileLength,
onChange, onChange,
defaultFileList, defaultFileList,
disabled,
} = props; } = props;
// 是否上传图片
const [visible, setVisible] = useState<boolean>(false);
// 当前选择的文件
const [currentFile, setCurrentFile] = useState<string>();
// 文件列表
const [fileList, setFileList] = useState<any[]>([]); const [fileList, setFileList] = useState<any[]>([]);
// 上传文件配置 // 上传文件配置
const uploadProps: UploadProps = { const uploadProps: UploadProps = {
...@@ -111,7 +121,20 @@ export const Uploader: React.FC<PropsType> = (props) => { ...@@ -111,7 +121,20 @@ export const Uploader: React.FC<PropsType> = (props) => {
setFileList(newFileList); setFileList(newFileList);
onChange?.(newFileList); onChange?.(newFileList);
}, },
// onPreview: { onPreview }, onPreview: (res) => {
const { url } = res;
const fileType = url?.substring(url?.lastIndexOf('.') + 1) || '';
if (['png', 'jpg', 'bmp', 'gif', 'jpeg', 'webp'].includes(fileType)) {
setCurrentFile(url);
setVisible(true);
} else {
if (url) {
saveAs(url.replace(/^http:/, 'https:'));
} else {
window.open(url);
}
}
},
}; };
useEffect(() => { useEffect(() => {
// 如果有默认文件列表 // 如果有默认文件列表
...@@ -124,14 +147,27 @@ export const Uploader: React.FC<PropsType> = (props) => { ...@@ -124,14 +147,27 @@ export const Uploader: React.FC<PropsType> = (props) => {
return ( return (
<div className='uploader-view'> <div className='uploader-view'>
{listType === 'text' ? ( {listType === 'text' ? (
<Upload {...uploadProps} style={{ width: '100%' }}> <Upload {...uploadProps} style={{ width: '100%' }} disabled={disabled}>
<>{fileList.length < (fileLength || 1) && children}</> <>{fileList.length < (fileLength || 1) && children}</>
</Upload> </Upload>
) : ( ) : (
<Upload {...uploadProps} style={{ width: '100%' }}> <Upload {...uploadProps} style={{ width: '100%' }} disabled={disabled}>
{fileList.length < (fileLength || 1) && children} {fileList.length < (fileLength || 1) && children}
</Upload> </Upload>
)} )}
<Viewer
visible={visible}
currentImgList={[
{
src: currentFile,
alt: '图片',
},
]}
activeViewerIndex={0}
setVisible={() => {
setVisible(false);
}}
/>
</div> </div>
); );
}; };
...@@ -5,6 +5,7 @@ interface propsType { ...@@ -5,6 +5,7 @@ interface propsType {
visible: boolean; visible: boolean;
currentImgList: any; currentImgList: any;
activeViewerIndex: number; activeViewerIndex: number;
// eslint-disable-next-line @typescript-eslint/ban-types
setVisible: Function; setVisible: Function;
} }
......
...@@ -23,7 +23,7 @@ import Viewer from '~/components/viewer'; ...@@ -23,7 +23,7 @@ import Viewer from '~/components/viewer';
import './index.scss'; import './index.scss';
import events from '~/events'; import events from '~/events';
const Category: FC = (props: any) => { const Category: FC = () => {
const location = useLocation(); const location = useLocation();
console.log('location', location); console.log('location', location);
const navigate = useNavigate(); const navigate = useNavigate();
...@@ -57,7 +57,7 @@ const Category: FC = (props: any) => { ...@@ -57,7 +57,7 @@ const Category: FC = (props: any) => {
width: '12%', width: '12%',
editable: true, editable: true,
ellipsis: true, ellipsis: true,
render: (text: string, record: categoryEntity, index: number) => { render: (_text: string, record: categoryEntity) => {
return ( return (
<Tooltip placement='top' title={<span>{record.classifyName}</span>}> <Tooltip placement='top' title={<span>{record.classifyName}</span>}>
<span <span
...@@ -84,12 +84,13 @@ const Category: FC = (props: any) => { ...@@ -84,12 +84,13 @@ const Category: FC = (props: any) => {
key: 'icon', key: 'icon',
width: '12%', width: '12%',
align: 'center', align: 'center',
render: (text: string, record: categoryEntity, index: number) => { render: (_text: string, record: categoryEntity) => {
return record.icon ? ( return record.icon ? (
<img <img
src={record.icon} src={record.icon}
style={{ width: '25px', height: '25px' }} style={{ width: '25px', height: '25px' }}
onClick={() => imgClick(record.icon)} onClick={() => imgClick(record.icon)}
alt='图片'
/> />
) : ( ) : (
'' ''
...@@ -104,7 +105,7 @@ const Category: FC = (props: any) => { ...@@ -104,7 +105,7 @@ const Category: FC = (props: any) => {
align: 'center', align: 'center',
editable: true, editable: true,
ellipsis: true, ellipsis: true,
render: (text: string, record: categoryEntity, index: number) => { render: (_text: string, record: categoryEntity) => {
return ( return (
<Tooltip placement='right' title={<span>{record.description}</span>}> <Tooltip placement='right' title={<span>{record.description}</span>}>
<span>{record.description}</span> <span>{record.description}</span>
...@@ -124,7 +125,7 @@ const Category: FC = (props: any) => { ...@@ -124,7 +125,7 @@ const Category: FC = (props: any) => {
width: '55%', width: '55%',
key: 'option', key: 'option',
align: 'center', align: 'center',
render: (text: string, record: categoryEntity, index: number) => { render: (_text: string, record: categoryEntity) => {
return ( return (
<div className='table-option-wrap'> <div className='table-option-wrap'>
{record.level == 1 ? ( {record.level == 1 ? (
...@@ -165,7 +166,7 @@ const Category: FC = (props: any) => { ...@@ -165,7 +166,7 @@ const Category: FC = (props: any) => {
确定 确定
</Button> </Button>
<Button type='link' onClick={() => cancelAddCldCgy(record, index)}> <Button type='link' onClick={() => cancelAddCldCgy(record)}>
取消 取消
</Button> </Button>
</> </>
...@@ -232,8 +233,6 @@ const Category: FC = (props: any) => { ...@@ -232,8 +233,6 @@ const Category: FC = (props: any) => {
const [activeViewerIndex] = useState<number>(0); const [activeViewerIndex] = useState<number>(0);
// 新增弹窗 // 新增弹窗
const [isVisible, setIsVisible] = useState<boolean>(false); const [isVisible, setIsVisible] = useState<boolean>(false);
// 删除分类id
const [cgyId, setCgyId] = useState<number>(0);
// 弹窗title // 弹窗title
const [title, setTitle] = useState<string>(''); const [title, setTitle] = useState<string>('');
// 当前修改的行 // 当前修改的行
...@@ -245,13 +244,13 @@ const Category: FC = (props: any) => { ...@@ -245,13 +244,13 @@ const Category: FC = (props: any) => {
// 分享码弹窗显示/隐藏 // 分享码弹窗显示/隐藏
const [isShareCodeVble, setShareCodeVble] = useState<boolean>(false); const [isShareCodeVble, setShareCodeVble] = useState<boolean>(false);
const [shareCodeUrl, setShareCodeUrl] = useState<string>(''); const [shareCodeUrl] = useState<string>('');
// 按钮权限 // 按钮权限
const btnAdd = true; //useOption(22101); const btnAdd = true; //useOption(22101);
const btnUpperDown = true; //useOption(22102); const btnUpperDown = true; //useOption(22102);
const btnDir = true; //useOption(22103); // const btnDir = true; //useOption(22103);
const btnAddChildCgy = true; //useOption(22104); const btnAddChildCgy = true; //useOption(22104);
const btnShareCode = true; //useOption(22105); // const btnShareCode = true; //useOption(22105);
const btnEdit = true; //useOption(22106); const btnEdit = true; //useOption(22106);
const btnDelete = true; //useOption(22107); const btnDelete = true; //useOption(22107);
const btnDetail = true; //useOption(22108); const btnDetail = true; //useOption(22108);
...@@ -328,44 +327,38 @@ const Category: FC = (props: any) => { ...@@ -328,44 +327,38 @@ const Category: FC = (props: any) => {
const handleOk = () => { const handleOk = () => {
const addForm = baseRef.current.getForm(); const addForm = baseRef.current.getForm();
if (title === '新增分类') { if (title === '新增分类') {
addForm addForm.validateFields().then(async (values: any) => {
.validateFields() const res = await CategoryManageAPI.addClassification({
.then(async (values: any) => { ...values,
const res = await CategoryManageAPI.addClassification({ pid: 0,
...values, directoryId: activeTabKey,
pid: 0, type,
directoryId: activeTabKey, });
type, if (res.code == 200) {
}); events.emit('removeFileList');
if (res.code == 200) { message.success('新增成功');
events.emit('removeFileList'); setIsVisible(false);
message.success('新增成功'); getCategoryList(Number(activeTabKey));
setIsVisible(false); addForm.resetFields();
getCategoryList(Number(activeTabKey)); }
addForm.resetFields(); });
}
})
.catch((err: any) => {});
} else { } else {
addForm addForm.validateFields().then(async (values: any) => {
.validateFields() const res = await CategoryManageAPI.updateClassification({
.then(async (values: any) => { ...values,
const res = await CategoryManageAPI.updateClassification({ id: currentRecord.id,
...values, pid: currentRecord.pid,
id: currentRecord.id, directoryId: activeTabKey,
pid: currentRecord.pid, type,
directoryId: activeTabKey, });
type, if (res.code === '200') {
}); message.success('修改成功');
if (res.code === '200') { getCategoryList(Number(activeTabKey));
message.success('修改成功'); setIsVisible(false);
getCategoryList(Number(activeTabKey)); events.emit('removeFileList');
setIsVisible(false); addForm.resetFields();
events.emit('removeFileList'); }
addForm.resetFields(); });
}
})
.catch((err: any) => {});
} }
}; };
const handleCancel = () => { const handleCancel = () => {
...@@ -403,7 +396,7 @@ const Category: FC = (props: any) => { ...@@ -403,7 +396,7 @@ const Category: FC = (props: any) => {
} }
}; };
// 展开监听 // 展开监听
const onExpand = (expanded: boolean, record: categoryEntity) => { const onExpand = (_expanded: boolean, record: categoryEntity) => {
const index = expandedRowKeys.findIndex((item: any) => item === record.id); const index = expandedRowKeys.findIndex((item: any) => item === record.id);
if (index != -1) { if (index != -1) {
expandedRowKeys.splice(index, 1); expandedRowKeys.splice(index, 1);
...@@ -461,7 +454,7 @@ const Category: FC = (props: any) => { ...@@ -461,7 +454,7 @@ const Category: FC = (props: any) => {
}); });
}; };
// 取消新增子分类 // 取消新增子分类
const cancelAddCldCgy = (record: categoryEntity, index: number) => { const cancelAddCldCgy = (record: categoryEntity) => {
categoryList.map((item: categoryEntity) => { categoryList.map((item: categoryEntity) => {
if (item.children && item.children.length != 0) { if (item.children && item.children.length != 0) {
const index: number = item.children.findIndex( const index: number = item.children.findIndex(
...@@ -599,7 +592,7 @@ const Category: FC = (props: any) => { ...@@ -599,7 +592,7 @@ const Category: FC = (props: any) => {
selectedRowKeys, selectedRowKeys,
onChange: onSelectChange, onChange: onSelectChange,
hideSelectAll: true, hideSelectAll: true,
renderCell: (checked: boolean, record: categoryEntity) => { renderCell: (_checked: boolean, record: categoryEntity) => {
return <>{record.level === 1 ? <Checkbox onChange={() => onSelectChange(record)} /> : ''}</>; return <>{record.level === 1 ? <Checkbox onChange={() => onSelectChange(record)} /> : ''}</>;
}, },
}; };
...@@ -621,14 +614,14 @@ const Category: FC = (props: any) => { ...@@ -621,14 +614,14 @@ const Category: FC = (props: any) => {
}); });
}; };
// 分享码弹窗显示 // 分享码弹窗显示
const showShareCode = async (record: any) => { // const showShareCode = async (record: any) => {
const res: any = await CategoryManageAPI.getAppletQRCode({ // const res: any = await CategoryManageAPI.getAppletQRCode({
page: 'page-sort/sortDetail/index', // page: 'page-sort/sortDetail/index',
scene: `?id=${record.id}&backTip=1`, // scene: `?id=${record.id}&backTip=1`,
}); // });
setShareCodeUrl(`data:image/png;base64,${res.result}`); // setShareCodeUrl(`data:image/png;base64,${res.result}`);
setShareCodeVble(true); // setShareCodeVble(true);
}; // };
const shareCodeHandleCancel = () => { const shareCodeHandleCancel = () => {
setShareCodeVble(false); setShareCodeVble(false);
}; };
...@@ -690,7 +683,7 @@ const Category: FC = (props: any) => { ...@@ -690,7 +683,7 @@ const Category: FC = (props: any) => {
rowKey='id' rowKey='id'
bordered bordered
loading={isLoading} loading={isLoading}
rowClassName={(record: any, index: number) => { rowClassName={(record: any) => {
if (record.children) { if (record.children) {
return ''; return '';
} }
......
.apply-detail{
position: relative;
.detail-title{
font-size: 13px;
font-weight: bold;
margin-bottom: 10px;
}
.detail-text{
width: 100%;
text-align: center;
margin: 30px 0;
}
.detail-action{
width: 100%;
display: flex;
justify-content: flex-end;
align-items: center;
margin-bottom: 20px;
.ant-btn{
width: 100px;
}
.ant-btn:first-child{
margin-right: 20px;
}
}
.detail-item{
width: 100%;
display: flex;
justify-content: flex-start;
align-items: flex-start;
margin-bottom: 15px;
.item-label{
width: 100px;
font-weight: normal;
text-align: right;
box-sizing: border-box;
padding-right: 20px;
}
}
}
import { FC, useEffect, useState } from 'react';
import { Button, message, Modal } from 'antd';
import { InterDataType, InterListType, InterReqType } from '~/api/interface';
import { CustomManageAPI } from '~/api';
import {
applyTagDetails,
approvalApplyTag,
listUserApplyTag,
} from '~/api/interface/customManageType';
import './index.scss';
import { PlusOutlined } from '@ant-design/icons';
import { Uploader } from '~/components/uploader';
// 列表的类型
type DataType = InterDataType<applyTagDetails>;
// 列表的类型
type TableType = InterListType<listUserApplyTag>;
// 请求的表单类型
type ReqType = InterReqType<approvalApplyTag>;
// 传参类型
interface propType {
title: string;
open: boolean;
closed: any;
data?: TableType[0];
}
const AddEditModal: FC<propType> = (props) => {
AddEditModal.defaultProps = {
data: undefined,
};
// 参数
const { title, open, closed, data } = props;
const [applyTagDetail, setApplyTagDetail] = useState<DataType>();
// 关闭弹窗
const handleCancel = () => {
closed();
};
// 点击事件
const handleOk = async (status: boolean) => {
await handleSubmit({ id: Number(data?.id), status });
};
// 提交事件
const handleSubmit = async (values: ReqType) => {
const res = await CustomManageAPI.approvalApplyTag(values);
if (res && res.code === '200') {
message.success('操作成功');
handleCancel();
}
};
// 获取审批详情
const getApplyTagDetails = async () => {
const res = await CustomManageAPI.applyTagDetails({
id: data?.id,
userAccountId: data?.userAccountId,
});
if (res && res.code === '200') {
const { result } = res;
setApplyTagDetail(result);
}
};
// componentDidMount
useEffect(() => {
if (!open) return;
if (!data) return;
getApplyTagDetails().then();
// console.log('data --->', data);
}, [open]);
return (
<Modal open={open} title={title} onCancel={handleCancel} destroyOnClose footer={null}>
<div className='apply-detail'>
<div className='detail-text'>确定通过用户提交的加盟申请成为加盟商吗?</div>
<div className='detail-action'>
<Button type={'default'} onClick={() => handleOk(false)}>
驳回
</Button>
<Button type={'primary'} onClick={() => handleOk(true)}>
通过
</Button>
</div>
<div className='detail-title'>企业认证信息</div>
<div className='detail-item'>
<div className='item-label'>企业名称:</div>
<div className='item-value'>{applyTagDetail?.companyName || '无'}</div>
</div>
<div className='detail-item'>
<div className='item-label'>社会信用代码:</div>
<div className='item-value'>{applyTagDetail?.creditCode || '无'}</div>
</div>
<div className='detail-item'>
<div className='item-label'>工商营业执照:</div>
<div className='item-value'>
<Uploader
listType={'picture-card'}
fileUpload
fileLength={1}
fileSize={10}
fileType={['image/png', 'image/jpeg', 'image/jpg', 'image/gif', 'image/bmp']}
defaultFileList={
applyTagDetail?.licenseImg ? [{ url: applyTagDetail?.licenseImg }] : []
}
disabled={true}
>
<PlusOutlined />
</Uploader>
</div>
</div>
<div className='detail-item'>
<div className='item-label'>附件信息:</div>
<div className='item-value'>
<Uploader
listType={'picture-card'}
fileUpload
fileLength={1}
fileSize={10}
fileType={['image/png', 'image/jpeg', 'image/jpg', 'image/gif', 'image/bmp']}
defaultFileList={
applyTagDetail?.attachmentList?.length
? applyTagDetail?.attachmentList.map((i) => ({ url: i.url }))
: []
}
disabled={true}
>
<PlusOutlined />
</Uploader>
</div>
</div>
<div className='detail-item'>
<div className='item-label'>备注:</div>
<div className='item-value'>{applyTagDetail?.remark || '无'}</div>
</div>
</div>
</Modal>
);
};
export default AddEditModal;
import { useEffect, useState } from 'react';
import SearchBox from '~/components/search-box';
import { CustomManageAPI } from '~/api';
import { Button, message, Modal, Table } from 'antd';
import { ColumnsType } from 'antd/es/table';
import { InterListType, InterReqListType } from '~/api/interface';
import { listUserApplyTag } from '~/api/interface/customManageType';
import AddEditModal from './comp/addEditModal';
// 列表类型
type TableType = InterListType<listUserApplyTag>;
// 请求的参数
type ReqType = InterReqListType<listUserApplyTag>;
// 搜索表单的数据
let query: ReqType = {};
// 审批状态
const applyStatusList = [
{ label: '待审核', value: 0 },
{ label: '已通过', value: 1 },
{ label: '不通过', value: 2 },
];
const CustomIdentityView = () => {
const { confirm } = Modal;
// 加盟列表
const [cooperationList, setCooperationList] = useState<{ label: string; value: number }[]>([]);
// 新增弹窗
const [addModalVisible, setAddModalVisible] = useState<boolean>(false);
// 需要编辑的数据
const [editData, setEditData] = useState<TableType[0]>();
// 表格数据
const [tableData, setTableData] = useState<TableType>([]);
// 表格分页配置
const [pagination, setPagination] = useState({
total: 0,
pageSize: 10,
current: 1,
totalPage: 0,
});
// 加载列表
const getTableList = async (value = {}) => {
// 只需要修改这个地方的接口即可
const res = await CustomManageAPI.listUserApplyTag({
pageNo: pagination.current,
pageSize: pagination.pageSize,
...value,
...query,
});
if (res && res.code === '200') {
const { list, pageNo, totalCount, pageSize, totalPage } = res.result; // 解构
setPagination({
total: totalCount,
current: pageNo,
pageSize,
totalPage,
});
setTableData(list);
}
};
// 翻页
const paginationChange = (pageNo: number, pageSize: number) => {
getTableList({ pageNo, pageSize }).then();
};
// 表单提交
const onFinish = (data: ReqType) => {
pagination.current = 1;
query = data;
getTableList(data).then();
};
// 获取加盟列表
const getCooperationList = async () => {
const res = await CustomManageAPI.cooperationListTag({});
if (res && res.code === '200') {
const list = res.result || [];
setCooperationList(list.map((i) => ({ label: i.tagName, value: i.id })));
}
};
// 删除数据
const handleDelete = (record: TableType[0]) => {
confirm({
title: '提示',
content: '是否删除该记录?',
onOk: async () => {
const res = await CustomManageAPI.deleteApplyTag({ id: record.id });
if (res && res.code === '200') {
message.success('删除成功');
paginationChange(
tableData.length === 1 ? pagination.current - 1 : pagination.current,
pagination.pageSize,
);
}
},
});
};
useEffect(() => {
getCooperationList().then();
getTableList().then();
}, []);
// 表格结构
const columns: ColumnsType<TableType[0]> = [
{
title: '序号',
dataIndex: 'accountNo',
align: 'center',
width: '50px',
render: (_text, _record, index) => (pagination.current - 1) * pagination.pageSize + index + 1,
},
{
title: '申请加盟类型',
dataIndex: 'cooperationTagId',
align: 'center',
render: (text) => cooperationList.find((i) => i.value === text)?.label || text,
},
{
title: '联系人',
dataIndex: 'applyName',
align: 'center',
},
{
title: '联系方式',
dataIndex: 'applyPhone',
align: 'center',
},
{
title: '申请时间',
dataIndex: 'applyTime',
align: 'center',
},
{
title: '审核状态',
dataIndex: 'approvalStatus',
align: 'center',
render: (text) => applyStatusList.find((i) => i.value === text)?.label || text,
},
{
title: '操作',
dataIndex: 'action',
align: 'center',
fixed: 'right',
width: '120px',
render: (_text, record) => (
<>
<Button
type={'link'}
onClick={() => {
setAddModalVisible(true);
setEditData(JSON.parse(JSON.stringify(record)));
}}
disabled={record.approvalStatus !== 0}
>
审批
</Button>
<Button type={'link'} danger onClick={() => handleDelete(record)}>
强制删除
</Button>
</>
),
},
];
return (
<>
<SearchBox
search={[
{
name: 'cooperationTagId',
label: '申请加盟类型',
type: 'Select',
placeholder: '请选择加盟类型',
options: cooperationList,
},
{
name: 'applyStatus',
label: '申请状态',
type: 'Select',
placeholder: '请选择申请状态',
options: applyStatusList,
},
{
name: 'rangeTime',
label: '申请时间',
type: 'rangePicker',
placeholder: '请选择开始时间和结束时间',
},
]}
searchData={onFinish}
/>
<Table
size='small'
dataSource={tableData}
columns={columns}
rowKey='id'
// scroll={{ x: 1500 }}
bordered
pagination={{
total: pagination.total,
pageSize: pagination.pageSize,
current: pagination.current,
showSizeChanger: true,
showQuickJumper: true,
onChange: (page: number, pageSize: number) => paginationChange(page, pageSize),
showTotal: (total, range) => `当前 ${range[0]}-${range[1]} 条记录 / 共 ${total} 条数据`,
}}
/>
<AddEditModal
open={addModalVisible}
title={editData?.id ? '审批' : '新增'}
data={editData}
closed={() => {
setAddModalVisible(false);
setEditData(undefined);
paginationChange(pagination.current, pagination.pageSize);
}}
/>
</>
);
};
export default CustomIdentityView;
import { FC, useEffect, useState } from 'react'; import { FC, useEffect, useState } from 'react';
import { Form, Modal, Select } from 'antd'; import { Form, Modal, Select } from 'antd';
import { InterListType } from '~/api/interface'; import { InterListType, InterReqType } from '~/api/interface';
import { listAppUserType } from '~/api/interface/customManageType'; import { changeUserTagNew, listAppUserType } from '~/api/interface/customManageType';
import { CustomManageAPI } from '~/api'; import { CustomManageAPI } from '~/api';
// 表单参数
type ReqType = InterReqType<changeUserTagNew>;
// 表格数据类型 // 表格数据类型
type TableType = InterListType<listAppUserType>; type TableType = InterListType<listAppUserType>;
// 数据的类型 // 数据的类型
...@@ -13,11 +15,6 @@ interface PropsType { ...@@ -13,11 +15,6 @@ interface PropsType {
data?: TableType[0]; data?: TableType[0];
} }
// 修改等级标签
interface tagLevelForm {
cooperationTagId: number;
}
export const ChangeModal: FC<PropsType> = (props) => { export const ChangeModal: FC<PropsType> = (props) => {
ChangeModal.defaultProps = { ChangeModal.defaultProps = {
data: undefined, data: undefined,
...@@ -25,7 +22,7 @@ export const ChangeModal: FC<PropsType> = (props) => { ...@@ -25,7 +22,7 @@ export const ChangeModal: FC<PropsType> = (props) => {
// 父组件传参 // 父组件传参
const { open, closed, data } = props; const { open, closed, data } = props;
// 个人等级标签 // 个人等级标签
const [form] = Form.useForm<tagLevelForm>(); const [form] = Form.useForm<ReqType>();
// 相关运营列表 // 相关运营列表
const [operationList] = useState<{ value: number; label: string }[]>([]); const [operationList] = useState<{ value: number; label: string }[]>([]);
// 等级标签列表 // 等级标签列表
...@@ -40,9 +37,9 @@ export const ChangeModal: FC<PropsType> = (props) => { ...@@ -40,9 +37,9 @@ export const ChangeModal: FC<PropsType> = (props) => {
// 提交数据 // 提交数据
const handleSubmit = () => { const handleSubmit = () => {
form.validateFields().then(async (value) => { form.validateFields().then(async (value) => {
const res = await CustomManageAPI.changeUserTag({ const res = await CustomManageAPI.changeUserTagNew({
userAccountId: Number(data?.id), userAccountId: Number(data?.id),
cooperationTagId: value.cooperationTagId, cooperationTagIds: value?.cooperationTagIds || [],
}); });
if (res && res.code === '200') { if (res && res.code === '200') {
handleClosed(); handleClosed();
...@@ -62,18 +59,19 @@ export const ChangeModal: FC<PropsType> = (props) => { ...@@ -62,18 +59,19 @@ export const ChangeModal: FC<PropsType> = (props) => {
if (!data) return; if (!data) return;
getCompanyListTag().then(); getCompanyListTag().then();
form.setFieldsValue({ form.setFieldsValue({
cooperationTagId: data.cooperationTagId, cooperationTagIds: data.cooperationTagVOS?.map((i) => i.id),
}); });
}, [open]); }, [open]);
return ( return (
<Modal open={open} title='变更' onCancel={handleClosed} destroyOnClose onOk={handleSubmit}> <Modal open={open} title='变更' onCancel={handleClosed} destroyOnClose onOk={handleSubmit}>
<Form form={form} labelCol={{ span: 5 }} wrapperCol={{ span: 16 }}> <Form form={form} labelCol={{ span: 5 }} wrapperCol={{ span: 16 }}>
<Form.Item label='等级标签' name='cooperationTagId'> <Form.Item label='加盟身份' name='cooperationTagIds'>
<Select <Select
placeholder='请选择等级标签' placeholder='请选择加盟身份'
disabled={!data?.userName && !data?.companyName} disabled={!data?.userName && !data?.companyName}
allowClear allowClear
options={cooperationTagIdList} options={cooperationTagIdList}
mode='multiple'
/> />
</Form.Item> </Form.Item>
<Form.Item label='相关运营' name='mallOperator'> <Form.Item label='相关运营' name='mallOperator'>
......
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
import SearchBox from '~/components/search-box'; import SearchBox from '~/components/search-box';
import { Button, message, Modal, Table } from 'antd'; import { Button, message, Modal, Table, Tag } from 'antd';
import { ColumnsType } from 'antd/es/table'; import { ColumnsType } from 'antd/es/table';
import { ChangeModal } from '~/pages/customManage/customList/comp/changeModal'; import { ChangeModal } from '~/pages/customManage/customList/comp/changeModal';
import { InterListType, InterReqType } from '~/api/interface'; import { InterListType, InterReqType } from '~/api/interface';
...@@ -25,10 +25,6 @@ const portTypeList = [ ...@@ -25,10 +25,6 @@ const portTypeList = [
function CustomListView() { function CustomListView() {
const { confirm } = Modal; const { confirm } = Modal;
// 等级标签列表
const [cooperationTagIdList, setCooperationTagIdList] = useState<
{ value: number; label: string }[]
>([]);
// 是否打开变更弹窗 // 是否打开变更弹窗
const [isChangeVisModal, setIsChangeVisModal] = useState<boolean>(false); const [isChangeVisModal, setIsChangeVisModal] = useState<boolean>(false);
// 表格分页配置 // 表格分页配置
...@@ -73,14 +69,6 @@ function CustomListView() { ...@@ -73,14 +69,6 @@ function CustomListView() {
query = data; query = data;
getTableList(data).then(); getTableList(data).then();
}; };
// 获取加盟列表
const getCompanyListTag = async () => {
const res = await CustomManageAPI.CompanyListTag({});
if (res && res.code === '200') {
setCooperationTagIdList(res.result.map((i) => ({ value: i.id, label: i.tagName })));
// console.log(res.result);
}
};
// 删除用户 // 删除用户
const handleDelete = (value: TableType[0]) => { const handleDelete = (value: TableType[0]) => {
confirm({ confirm({
...@@ -102,7 +90,6 @@ function CustomListView() { ...@@ -102,7 +90,6 @@ function CustomListView() {
useEffect(() => { useEffect(() => {
query = {}; query = {};
(async () => { (async () => {
await getCompanyListTag();
await getTableList(); await getTableList();
})(); })();
}, []); }, []);
...@@ -160,10 +147,15 @@ function CustomListView() { ...@@ -160,10 +147,15 @@ function CustomListView() {
render: (text) => (text ? '普通用户' : '游客用户'), render: (text) => (text ? '普通用户' : '游客用户'),
}, },
{ {
title: '渠道等级', title: '加盟身份',
dataIndex: 'cooperationTagId', dataIndex: 'cooperationTagVOS',
align: 'center', align: 'center',
render: (text) => cooperationTagIdList.find((i) => i.value === text)?.label || text, render: (_text, record) =>
record.cooperationTagVOS?.map((i, j) => (
<Tag color='processing' key={j} style={{ marginBottom: '10px' }}>
{i.tagName}
</Tag>
)),
}, },
{ {
title: '上级推荐人', title: '上级推荐人',
......
.dynamic-detail{
padding: 20px 0;
&-media{
display: flex;
align-items: center;
flex-wrap: wrap;
.media-item{
margin-right: 10px;
margin-bottom: 10px;
}
}
&-info{
.info-title{
color: #000;
font-size: 15px;
font-weight: bold;
}
.info-meta{
margin-top: 10px;
}
.info-footer{
margin-top: 20px;
display: flex;
align-items: center;
justify-content: space-between;
border-bottom: 1px solid #999;
.operate{
display: flex;
align-items: center;
padding-bottom: 15px;
div:first-child{
margin-right: 10px;
}
}
}
}
&-comment{
margin-top: 40px;
.comment-title{
color: #000;
font-size: 15px;
font-weight: bold;
}
.comment-item{
margin-top: 10px;
&-header{
display: flex;
align-items: center;
.user-avatar{
margin-right: 10px;
img{
width: 20px;
height: 20px;
border-radius: 50%;
}
}
.user-name{
}
}
&-info{
margin-left: 30px;
border-bottom: 1px solid #999;
.info-content{
margin: 10px 0;
}
}
}
}
.no-comment{
text-align: center;
margin-top: 50px;
font-size: 15px;
color: rgba(0,0,0,0.5);
font-weight: bold;
}
}
.dynamic-like-user{
display: flex;
width: 200px;
min-height: 100px;
.user-info{
display: flex;
margin: 10px;
img{
width: 20px;
height: 20px;
border-radius: 50%;
margin-right: 5px;
}
}
}
import { FC, useEffect, useState } from 'react';
import { Button, Image, Modal, ModalProps, Tooltip } from 'antd';
import './index.scss';
import { InterDataType } from '~/api/interface';
import { forumDetailType, likeUserInfoType } from '~/api/interface/forumManageType';
import { ForumManageAPI } from '~/api';
//论坛详情返回类型
type detailType = InterDataType<forumDetailType>;
interface selfProps {
forumDetail?: detailType;
}
//点赞人返回类型
type likeUserType = InterDataType<likeUserInfoType>;
const DynamicDetailModal: FC<ModalProps & selfProps> = ({ open, onCancel, forumDetail }) => {
//点赞人列表
const [likeUserList, setLikeUserList] = useState<likeUserType>([]);
const getLikeUserInfo = (dynamicId: number) => {
ForumManageAPI.getLikeUserInfoList({ dynamicId }).then(({ result }) => {
setLikeUserList(result || []);
});
};
useEffect(() => {
if (forumDetail && forumDetail.likesCount) {
getLikeUserInfo(forumDetail.id);
} else {
setLikeUserList([]);
}
}, [forumDetail]);
return (
<Modal open={open} onCancel={onCancel} title='查看详情' width={800} footer={null}>
<div className='dynamic-detail'>
<div className='dynamic-detail-media'>
{forumDetail?.mediaVO?.map((v, index: number) => {
if (v.type === 0) {
return (
<div className='media-item' key={index}>
<Image src={v.url} width={200} height={200} />
</div>
);
} else {
return (
<div className='media-item' key={index}>
<video
src={v.url}
style={{
width: '200px',
height: '200px',
verticalAlign: 'top',
}}
controls
/>
</div>
);
}
})}
</div>
<div className='dynamic-detail-info'>
<div className='info-title'>{forumDetail?.description}</div>
<div className='info-footer'>
<div className='time'>发布于{forumDetail?.dynamicPublishTime}</div>
<div className='operate'>
<div>{forumDetail?.commentCount}人回答</div>
<Tooltip
placement='bottom'
title={
likeUserList.length ? (
<div className='dynamic-like-user'>
{likeUserList.map((v, index: number) => (
<div key={index} className='user-info'>
<img src={v.userImg} alt='头像' />
<span>{v.userName || v.nickName}</span>
</div>
))}
</div>
) : (
'暂无点赞'
)
}
>
<Button type='link'>{forumDetail?.likesCount}人爱心赞</Button>
</Tooltip>
</div>
</div>
</div>
{forumDetail?.commentAndReplyVO.length ? (
<div className='dynamic-detail-comment'>
<div className='comment-title'>{forumDetail?.commentCount}条评论</div>
{forumDetail.commentAndReplyVO.map((v, index: number) => (
<div className='comment-item' key={index}>
<div className='comment-item-header'>
<div className='user-avatar'>
<img src={v.userBaseInfo.userImg} alt='头像' />
</div>
<div className='user-name'>{v.userBaseInfo.nickName}</div>
</div>
<div className='comment-item-info'>
<div className='info-content'>{v.description}</div>
<div className='info-time'>{v.dynamicPublishTime}</div>
</div>
</div>
))}
</div>
) : (
<div className='no-comment'>暂无评论</div>
)}
</div>
</Modal>
);
};
export default DynamicDetailModal;
.forum-description{
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
cursor: pointer;
}
import SearchBox, { searchColumns } from '~/components/search-box';
import { Button, message, Modal, Table, Tooltip } from 'antd';
import { ColumnsType } from 'antd/es/table';
import { useEffect, useState } from 'react';
import DynamicDetailModal from './components/dynamicDetailModal';
import { ForumManageAPI } from '../../../api';
import { InterDataType, InterReqListType, PaginationProps } from '../../../api/interface';
import { forumDetailType, forumListType } from '../../../api/interface/forumManageType';
import './index.scss';
//论坛列表返回类型
type forumType = InterDataType<forumListType>['list'];
//论坛列表参数类型
type forumParameters = InterReqListType<forumListType>;
//论坛详情返回类型
type detailType = InterDataType<forumDetailType>;
const DynamicList = () => {
const searchColumnsData: searchColumns[] = [
{
label: '作者',
type: 'input',
name: 'keyword',
placeholder: '用户名称/用户UID/用户手机号码',
},
];
const tableColumns: ColumnsType<forumType[0]> = [
{
title: '动态描述信息',
align: 'center',
dataIndex: 'description',
width: '20%',
ellipsis: true,
render: (text: string) => (
<Tooltip title={text}>
<div className='forum-description'>{text}</div>
</Tooltip>
),
},
{
title: '作者(用户名称)',
align: 'center',
render: (_text: string, record) => (
<div>{record.userBaseInfo?.userName || record.userBaseInfo?.nickName || ''}</div>
),
},
{
title: '用户UID',
align: 'center',
render: (_text: string, record) => <div>{record.userBaseInfo?.uid || ''}</div>,
},
{
title: '用户手机号',
align: 'center',
render: (_text: string, record) => <div>{record.userBaseInfo?.phone || ''}</div>,
},
{
title: '操作',
align: 'center',
render: (_text: string, record) => (
<>
<Button type='link' onClick={() => lookDynamicDetail(record)}>
查看详情
</Button>
<Button type='link' onClick={() => deleteForumClick(record)}>
强制删除
</Button>
<Button type='link' onClick={() => hiddenForumClick(record)}>
{record.show ? '恢复显示' : '强制隐藏'}
</Button>
</>
),
},
];
const [tableData, setTableData] = useState<forumType>([]);
const [pagination, setPagination] = useState<PaginationProps & { totalCount: number }>({
pageNo: 1,
pageSize: 10,
totalCount: 0,
});
const [forumDetail, setForumDetail] = useState<detailType>();
const [query, setQuery] = useState<forumParameters>();
const [dynamicDetailModalShow, setDynamicDetailModalShow] = useState<boolean>(false);
//动态列表
const getDynamicList = (query?: forumParameters) => {
ForumManageAPI.getForumList({
pageNo: pagination.pageNo,
pageSize: pagination.pageSize,
...query,
}).then(({ result }) => {
setTableData(result.list || []);
pagination.totalCount = result.totalCount;
setPagination(pagination);
});
};
//筛选
const searchSuccess = (data: any) => {
pagination.pageNo = 1;
pagination.pageSize = 10;
setQuery(data);
getDynamicList(data);
};
//分页
const paginationChange = (pageNo: number, pageSize: number) => {
pagination.pageNo = pageNo;
pagination.pageSize = pageSize;
getDynamicList(query);
};
//强制删除论坛
const deleteForumClick = (record: forumType[0]) => {
Modal.confirm({
title: '强制删除',
content: '确认删除这条动态?',
onOk: () => {
ForumManageAPI.deleteForum({ dynamicId: record.id }).then(({ code }) => {
if (code === '200') {
message.success('删除成功');
if (pagination.pageNo !== 1 && tableData.length === 1) {
pagination.pageNo -= 1;
}
getDynamicList(query);
}
});
},
});
};
//强制隐藏
const hiddenForumClick = (record: forumType[0]) => {
Modal.confirm({
title: `${record.show ? '恢复显示' : '强制隐藏'}`,
content: `确认${record.show ? '显示' : '隐藏'}这条动态?`,
onOk: () => {
ForumManageAPI.hiddenForum({ dynamicId: record.id }).then(({ code }) => {
if (code === '200') {
message.success(`${record.show ? '显示' : '隐藏'}成功`);
getDynamicList(query);
}
});
},
});
};
const dynamicDetailModalOnCancel = () => {
setDynamicDetailModalShow(false);
};
//查看详情
const lookDynamicDetail = (record: forumType[0]) => {
getForumDetail(record.id);
};
//获取论坛-详情
const getForumDetail = (id: number) => {
ForumManageAPI.getForumDetail({ dynamicId: id }).then(({ code, result }) => {
if (code === '200') {
setDynamicDetailModalShow(true);
setForumDetail(result);
}
});
};
useEffect(() => {
getDynamicList();
}, []);
return (
<div className='dynamic-list'>
<SearchBox search={searchColumnsData} searchData={searchSuccess} />
<Table
bordered
columns={tableColumns}
dataSource={tableData}
rowKey='id'
pagination={{
total: pagination.totalCount,
pageSize: pagination.pageSize,
current: pagination.pageNo,
showSizeChanger: true,
showQuickJumper: true,
onChange: (page: number, pageSize: number) => paginationChange(page, pageSize),
showTotal: (total, range) => `当前 ${range[0]}-${range[1]} 条记录 / 共 ${total} 条数据`,
}}
/>
<DynamicDetailModal
open={dynamicDetailModalShow}
onCancel={dynamicDetailModalOnCancel}
forumDetail={forumDetail}
/>
</div>
);
};
export default DynamicList;
import { FC, useEffect } from 'react';
import { Form, Input, message, Modal } from 'antd';
import { InterListType, InterReqType } from '~/api/interface';
import { industryCaseAddCase, industryCaseListCasePage } from '~/api/interface/resourceManageType';
import { ResourceManageAPI } from '~/api';
import RichText from '~/components/richText';
// 列表的类型
type TableType = InterListType<industryCaseListCasePage>;
// 请求的表单类型
type ReqType = InterReqType<industryCaseAddCase>;
// 传参类型
interface propType {
title: string;
open: boolean;
closed: any;
data?: TableType[0];
}
const AddEditModal: FC<propType> = (props) => {
AddEditModal.defaultProps = {
data: undefined,
};
// 参数
const { title, open, closed, data } = props;
// 表单钩子
const [form] = Form.useForm<ReqType>();
// 关闭弹窗
const handleCancel = () => {
form.resetFields();
closed();
};
// 确认事件
const handleOk = () => {
form
.validateFields()
.then(async (values) => {
await handleSubmit(values as ReqType & { file: any[] });
})
.catch((err) => {
message
.warning({
content: err.errorFields[0].errors[0],
})
.then();
});
};
// 提交事件
const handleSubmit = async (values: ReqType) => {
const res = await ResourceManageAPI[
data?.id ? 'industryCaseUpdateCase' : 'industryCaseAddCase'
]({
...values,
id: data?.id ? Number(data?.id) : undefined,
});
if (res && res.code === '200') {
message.success('操作成功');
handleCancel();
}
};
// componentDidMount
useEffect(() => {
if (!open) return;
if (!data) return;
form.setFieldsValue(data);
// console.log('data --->', data);
}, [open]);
return (
<Modal
open={open}
title={title}
onCancel={handleCancel}
onOk={handleOk}
destroyOnClose
width={768}
>
<Form
name='Form'
form={form}
labelAlign='right'
labelCol={{ span: 3 }}
wrapperCol={{ span: 20 }}
>
<Form.Item
label='文章标题'
name='caseTitle'
rules={[{ required: true, message: '请输入文章标题' }]}
>
<Input placeholder={'请输入文章标题'} maxLength={50} allowClear />
</Form.Item>
<Form.Item
label='文章来源'
name='origin'
rules={[{ required: true, message: '请输入文章来源' }]}
>
<Input placeholder={'请输入文章来源'} maxLength={50} allowClear />
</Form.Item>
<Form.Item
label='文章详情'
name='caseContents'
rules={[{ required: true, message: '请输入文章详情' }]}
>
<RichText
value={form.getFieldValue('caseContents')}
onChange={(e) => form.setFieldValue('caseContents', e)}
height={250}
/>
</Form.Item>
</Form>
</Modal>
);
};
export default AddEditModal;
import { FC, useEffect } from 'react';
import { Modal } from 'antd';
import { InterListType } from '~/api/interface';
import { industryCaseListCasePage } from '~/api/interface/resourceManageType';
import RichText from '~/components/richText';
// 列表的类型
type TableType = InterListType<industryCaseListCasePage>;
// 传参类型
interface propType {
title: string;
open: boolean;
closed: any;
data?: TableType[0];
}
const PreviewModal: FC<propType> = (props) => {
PreviewModal.defaultProps = {
data: undefined,
};
// 参数
const { title, open, closed, data } = props;
// 关闭弹窗
const handleCancel = () => {
closed();
};
// componentDidMount
useEffect(() => {
if (!open) return;
if (!data) return;
// console.log('data --->', data);
}, [open]);
return (
<Modal
open={open}
title={title}
onCancel={handleCancel}
destroyOnClose
width={768}
footer={null}
>
<div
style={{
display: 'flex',
justifyContent: 'center',
alignItems: 'flex-start',
flexDirection: 'column',
}}
>
<div style={{ fontSize: '20px', fontWeight: 'bold' }}>{data?.caseTitle}</div>
<div style={{ fontSize: '15px', marginBottom: '10px' }}>
{data?.updateTime || data?.createTime}
</div>
</div>
<RichText value={data?.caseContents} height={350} isDetail={true} />
</Modal>
);
};
export default PreviewModal;
import { useEffect, useState } from 'react';
import SearchBox from '~/components/search-box';
import { Button, message, Modal, Table } from 'antd';
import { PlusOutlined } from '@ant-design/icons';
import { InterListType, InterReqListType } from '~/api/interface';
import { ResourceManageAPI } from '~/api';
import { industryCaseListCasePage } from '~/api/interface/resourceManageType';
import { ColumnsType } from 'antd/es/table';
import AddEditModal from '~/pages/resourceManage/businessCaseManage/comp/addEditModal';
import PreviewModal from '~/pages/resourceManage/businessCaseManage/comp/previewModal';
// 列表类型
type TableType = InterListType<industryCaseListCasePage>;
// 请求的参数
type ReqType = InterReqListType<industryCaseListCasePage>;
// 搜索表单的数据
let query: ReqType = {};
const BusinessCaseManage = () => {
const { confirm } = Modal;
// 新增弹窗
const [addModalVisible, setAddModalVisible] = useState<boolean>(false);
// 预览弹窗
const [previewVisible, setPreviewVisible] = useState<boolean>(false);
// 需要编辑的数据
const [editData, setEditData] = useState<TableType[0]>();
// 表格数据
const [tableData, setTableData] = useState<TableType>([]);
// 表格分页配置
const [pagination, setPagination] = useState({
total: 0,
pageSize: 10,
current: 1,
totalPage: 0,
});
// 加载列表
const getTableList = async (value = {}) => {
// 只需要修改这个地方的接口即可
const res = await ResourceManageAPI.industryCaseListCasePage({
pageNo: pagination.current,
pageSize: pagination.pageSize,
...value,
...query,
});
if (res && res.code === '200') {
const { list, pageNo, totalCount, pageSize, totalPage } = res.result; // 解构
setPagination({
total: totalCount,
current: pageNo,
pageSize,
totalPage,
});
setTableData(list);
}
};
// 翻页
const paginationChange = (pageNo: number, pageSize: number) => {
getTableList({ pageNo, pageSize }).then();
};
// 表单提交
const onFinish = (data: ReqType) => {
pagination.current = 1;
query = data;
getTableList(data).then();
};
// 删除数据
const handleDelete = (record: TableType[0]) => {
confirm({
title: '提示',
content: '是否删除该记录?',
onOk: async () => {
const res = await ResourceManageAPI.industryCaseDeleteDetails({ id: record.id });
if (res && res.code === '200') {
message.success('删除成功');
paginationChange(
tableData.length === 1 ? pagination.current - 1 : pagination.current,
pagination.pageSize,
);
}
},
});
};
// componentDidMount
useEffect(() => {
query = {};
getTableList().then();
}, []);
// 表格结构
const columns: ColumnsType<TableType[0]> = [
{
title: '序号',
dataIndex: 'accountNo',
align: 'center',
width: '50px',
render: (_text, _record, index) => (pagination.current - 1) * pagination.pageSize + index + 1,
},
{
title: '文章名称',
dataIndex: 'caseTitle',
align: 'center',
ellipsis: true,
},
{
title: '发布时间',
dataIndex: 'updateTime',
align: 'center',
render: (text, record) => text || record.createTime,
},
{
title: '来源',
dataIndex: 'origin',
align: 'center',
},
{
title: '操作',
dataIndex: 'action',
align: 'center',
width: '150px',
fixed: 'right',
render: (_text, record) => (
<>
<Button
type={'link'}
onClick={() => {
setEditData(JSON.parse(JSON.stringify(record)));
setAddModalVisible(true);
}}
>
编辑
</Button>
<Button
type={'link'}
onClick={() => {
setEditData(JSON.parse(JSON.stringify(record)));
setPreviewVisible(true);
}}
>
预览
</Button>
<Button type={'link'} danger onClick={() => handleDelete(record)}>
删除
</Button>
</>
),
},
];
return (
<>
<SearchBox
search={[
{ name: 'keyword', label: '文章名称', type: 'input', placeholder: '请输入文章名称' },
]}
child={
<>
<Button
type={'primary'}
icon={<PlusOutlined />}
onClick={() => {
setAddModalVisible(true);
}}
>
新增
</Button>
</>
}
searchData={onFinish}
/>
<Table
size='small'
dataSource={tableData}
columns={columns}
rowKey='id'
// scroll={{ x: 1500 }}
bordered
pagination={{
total: pagination.total,
pageSize: pagination.pageSize,
current: pagination.current,
showSizeChanger: true,
showQuickJumper: true,
onChange: (page: number, pageSize: number) => paginationChange(page, pageSize),
showTotal: (total, range) => `当前 ${range[0]}-${range[1]} 条记录 / 共 ${total} 条数据`,
}}
/>
<AddEditModal
open={addModalVisible}
title={editData?.id ? '编辑' : '新增'}
data={editData}
closed={() => {
setAddModalVisible(false);
setEditData(undefined);
paginationChange(pagination.current, pagination.pageSize);
}}
/>
<PreviewModal
open={previewVisible}
title={editData?.id ? '预览' : '新增'}
data={editData}
closed={() => {
setPreviewVisible(false);
setEditData(undefined);
paginationChange(pagination.current, pagination.pageSize);
}}
/>
</>
);
};
export default BusinessCaseManage;
import { FC, useEffect, useState } from 'react';
import { Form, Input, message, Modal, ModalProps } from 'antd';
import { Uploader } from '~/components/uploader';
import { UploadOutlined } from '@ant-design/icons';
import RichText from '~/components/richText';
import { InterDataType, InterReqType } from '~/api/interface';
import { addIndustryNewsType, industryNewsListType } from '~/api/interface/resourceManageType';
import { ResourceManageAPI } from '~/api';
//行业新闻返回类型
type industryNewsType = InterDataType<industryNewsListType>['list'];
//新增请求类型
type addNewsParameters = InterReqType<addIndustryNewsType>;
interface selfProps {
handleOk: () => void;
onCancel: () => void;
currentIndustryNews?: industryNewsType[0];
}
const AddOrEditNewsModal: FC<ModalProps & selfProps> = ({
open,
onCancel,
handleOk,
currentIndustryNews,
}) => {
const [form] = Form.useForm<addNewsParameters>();
const [richTextValue, setRichTextValue] = useState<string>('');
//封面图文件
const [surfaceImgList, setSurfaceImgList] = useState<
{
id: number;
name: string;
uid: number;
url: string;
}[]
>([]);
const richTextChange = (html?: string) => {
form.setFieldValue('newsContents', html || undefined);
};
//封面图-上传成功
const uploadSuccess = (
fileList: {
id: number;
name: string;
uid: number;
url: string;
}[],
) => {
setSurfaceImgList(fileList);
form.setFieldValue('surfaceImg', fileList[0].url);
};
//提交-新增或编辑行业新闻
const addOrEditModalOk = () => {
form.validateFields().then((value: any) => {
ResourceManageAPI[currentIndustryNews ? 'editIndustryNews' : 'addIndustryNews']({
...value,
id: currentIndustryNews ? currentIndustryNews.id : undefined,
}).then(({ code }) => {
if (code === '200') {
message.success(currentIndustryNews ? '编辑成功' : '新增成功');
handleOk();
}
});
});
};
const addOrEditModalCancel = () => {
form.resetFields();
setSurfaceImgList([]);
setRichTextValue('');
onCancel();
};
useEffect(() => {
if (currentIndustryNews) {
form.setFieldsValue({
newsTitle: currentIndustryNews.newsTitle,
origin: currentIndustryNews.origin,
newsAuthor: currentIndustryNews.newsAuthor,
surfaceImg: currentIndustryNews.surfaceImg,
newsContents: currentIndustryNews.newsContents || undefined,
});
setSurfaceImgList([
{
id: Math.random(),
name: 'surfaceImg',
uid: Math.random(),
url: currentIndustryNews.surfaceImg,
},
]);
setRichTextValue(currentIndustryNews.newsContents || '');
}
}, [currentIndustryNews]);
return (
<Modal
open={open}
onCancel={addOrEditModalCancel}
onOk={addOrEditModalOk}
title={currentIndustryNews ? '编辑' : '新建'}
width={800}
>
<Form labelCol={{ span: 4 }} wrapperCol={{ span: 16 }} form={form}>
<Form.Item
label='文章标题'
name='newsTitle'
rules={[{ required: true, message: '请输入文章标题' }]}
>
<Input placeholder='请输入文章标题' maxLength={30} />
</Form.Item>
<Form.Item
label='文章来源'
name='origin'
rules={[{ required: true, message: '请输入文章来源' }]}
>
<Input placeholder='请输入文章来源' maxLength={30} />
</Form.Item>
<Form.Item
label='作者'
name='newsAuthor'
rules={[{ required: true, message: '请输入文章作者' }]}
>
<Input placeholder='请输入文章作者' maxLength={30} />
</Form.Item>
<Form.Item
label='封面图'
name='surfaceImg'
rules={[{ required: true, message: '请上传封面图' }]}
>
<Uploader
fileUpload
listType='picture-card'
onChange={uploadSuccess}
defaultFileList={surfaceImgList}
fileType={['image/png', 'image/jpeg', 'image/jpg', 'image/gif', 'image/bmp']}
>
<UploadOutlined />
</Uploader>
</Form.Item>
<Form.Item label='主题内容' name='newsContents'>
<RichText onChange={richTextChange} value={richTextValue} />
</Form.Item>
</Form>
</Modal>
);
};
export default AddOrEditNewsModal;
.industry-news-detail{
width: 600px;
margin: 0 auto;
&-title{
font-weight: 500;
font-size: 18px;
color: #000;
text-align: center;
line-height: 50px;
}
&-img{
text-align: center;
}
&-content{
margin-top: 10px;
}
}
import { FC, useEffect, useRef, useState } from 'react';
import { Image, Modal, ModalProps } from 'antd';
import { InterDataType } from '~/api/interface';
import { industryNewsDetailType, industryNewsListType } from '~/api/interface/resourceManageType';
import { ResourceManageAPI } from '~/api';
import './index.scss';
//行业新闻返回类型
type industryNewsType = InterDataType<industryNewsListType>['list'];
//行业新闻详情返回类型
type detailType = InterDataType<industryNewsDetailType>;
interface selfProps {
currentIndustryNews?: industryNewsType[0];
}
const PreviewNewsModal: FC<ModalProps & selfProps> = ({ open, onCancel, currentIndustryNews }) => {
const newsContentsRef = useRef<any>();
//行业新闻详情
const [industryNewsDetail, setIndustryNewsDetail] = useState<detailType>();
//获取行业详情
const getIndustryNewsDetail = (id: number) => {
ResourceManageAPI.getIndustryNewsDetail({ id }).then(({ result }) => {
setIndustryNewsDetail(result);
newsContentsRef.current.innerHTML = result.newsContents;
});
};
useEffect(() => {
if (currentIndustryNews) {
getIndustryNewsDetail(currentIndustryNews.id);
}
}, [currentIndustryNews]);
return (
<Modal open={open} onCancel={onCancel} title='预览' width={800} footer={null}>
<div className='industry-news-detail'>
<div className='industry-news-detail-title'>{industryNewsDetail?.newsTitle}</div>
<div className='industry-news-detail-img'>
<Image src={industryNewsDetail?.surfaceImg} height={200} width={600} />
</div>
<div className='industry-news-detail-content' ref={newsContentsRef}></div>
</div>
</Modal>
);
};
export default PreviewNewsModal;
import SearchBox, { searchColumns } from '~/components/search-box';
import { Button, Image, message, Modal, Table } from 'antd';
import { PlusOutlined } from '@ant-design/icons';
import { ColumnsType } from 'antd/es/table';
import AddOrEditNewsModal from './components/addOrEditNewsModal';
import PreviewNewsModal from './components/previewNewsModal';
import { useEffect, useState } from 'react';
import { ResourceManageAPI } from '~/api';
import { InterDataType, InterReqListType, PaginationProps } from '~/api/interface';
import { industryNewsListType } from '~/api/interface/resourceManageType';
//行业新闻返回类型
type industryNewsType = InterDataType<industryNewsListType>['list'];
//行业新闻列表参数类型
type industryNewsParameters = InterReqListType<industryNewsListType>;
const IndustryNews = () => {
const searchColumnsData: searchColumns[] = [
{
label: '文章名称',
type: 'input',
name: 'newsTitle',
placeholder: '请输入文章名称',
},
];
const tableColumns: ColumnsType<industryNewsType[0]> = [
{
title: '序号',
align: 'center',
render: (_text: string, _record, index: number) =>
(pagination.pageNo - 1) * pagination.pageSize + index + 1,
},
{
title: '文章名称',
align: 'center',
dataIndex: 'newsTitle',
width: '20%',
},
{
title: '发布时间',
align: 'center',
dataIndex: 'createTime',
width: '15%',
},
{
title: '来源',
align: 'center',
dataIndex: 'origin',
},
{
title: '作者',
align: 'center',
dataIndex: 'newsAuthor',
},
{
title: '封图片',
align: 'center',
dataIndex: 'surfaceImg',
render: (text: string) => <Image src={text} width={50} height={50} />,
},
{
title: '操作',
align: 'center',
width: '20%',
render: (_text: string, record) => (
<>
<Button type='link' onClick={() => addOrEditIndustryNewsClick(record)}>
编辑
</Button>
<Button type='link' onClick={() => previewClick(record)}>
预览
</Button>
<Button type='link' danger onClick={() => deleteIndustryNews(record)}>
删除
</Button>
</>
),
},
];
const [tableData, setTableData] = useState<industryNewsType>([]);
const [loading, setLoading] = useState<boolean>(false);
const [currentIndustryNews, setCurrentIndustryNews] = useState<industryNewsType[0]>();
const [addOrEditNewsModalShow, setAddOrEditNewsModalShow] = useState<boolean>(false);
const [previewNewsModalShow, setPreviewNewsModalShow] = useState<boolean>(false);
const [query, setQuery] = useState<industryNewsParameters>();
const [pagination, setPagination] = useState<PaginationProps & { totalCount: number }>({
pageNo: 1,
pageSize: 10,
totalCount: 0,
});
//获取行业新闻-列表
const getIndustryNewsList = (query?: industryNewsParameters) => {
setLoading(true);
ResourceManageAPI.getIndustryNewsList({
pageNo: pagination.pageNo,
pageSize: pagination.pageSize,
...query,
}).then(({ result }) => {
setLoading(false);
setTableData(result.list || []);
pagination.totalCount = result.totalCount;
setPagination(pagination);
});
};
//分页
const paginationChange = (pageNo: number, pageSize: number) => {
pagination.pageNo = pageNo;
pagination.pageSize = pageSize;
getIndustryNewsList(query);
};
//筛选
const searchSuccessEvent = (value?: industryNewsParameters) => {
pagination.pageNo = 1;
pagination.pageSize = 10;
setQuery(value);
getIndustryNewsList(value);
};
//新增、编辑
const addOrEditIndustryNewsClick = (record?: industryNewsType[0]) => {
setCurrentIndustryNews(record ? { ...record } : undefined);
setAddOrEditNewsModalShow(true);
};
const addOrEditNewsModalCancel = () => {
setAddOrEditNewsModalShow(false);
};
const addOrEditNewsModalOk = () => {
getIndustryNewsList();
setAddOrEditNewsModalShow(false);
};
//预览
const previewClick = (record: industryNewsType[0]) => {
setCurrentIndustryNews({ ...record });
setPreviewNewsModalShow(true);
};
const previewNewsModalCancel = () => {
setPreviewNewsModalShow(false);
};
//删除
const deleteIndustryNews = (record: industryNewsType[0]) => {
Modal.confirm({
title: '行业新闻删除',
content: '确认删除该行业新闻?',
onOk: () => {
ResourceManageAPI.removeIndustryNews({ id: record.id }).then(({ code }) => {
if (code === '200') {
message.success('删除成功');
if (pagination.pageNo !== 1 && tableData.length === 1) {
pagination.pageNo -= 1;
}
getIndustryNewsList(query);
}
});
},
});
};
useEffect(() => {
getIndustryNewsList();
}, []);
return (
<div className='industry-news'>
<SearchBox
search={searchColumnsData}
child={
<Button
type='primary'
icon={<PlusOutlined />}
onClick={() => addOrEditIndustryNewsClick()}
>
新建
</Button>
}
searchData={searchSuccessEvent}
/>
<Table
bordered
columns={tableColumns}
dataSource={tableData}
loading={loading}
rowKey='id'
pagination={{
total: pagination.totalCount,
pageSize: pagination.pageSize,
current: pagination.pageNo,
showSizeChanger: true,
showQuickJumper: true,
onChange: (page: number, pageSize: number) => paginationChange(page, pageSize),
showTotal: (total, range) => `当前 ${range[0]}-${range[1]} 条记录 / 共 ${total} 条数据`,
}}
/>
<AddOrEditNewsModal
open={addOrEditNewsModalShow}
onCancel={addOrEditNewsModalCancel}
handleOk={addOrEditNewsModalOk}
currentIndustryNews={currentIndustryNews}
/>
<PreviewNewsModal
open={previewNewsModalShow}
onCancel={previewNewsModalCancel}
currentIndustryNews={currentIndustryNews}
/>
</div>
);
};
export default IndustryNews;
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import { Form, Input, message, Modal, Select } from 'antd'; import { DatePicker, Form, Input, message, Modal, Select, Space } from 'antd';
import { InterListType, InterReqType } from '~/api/interface'; import { InterListType, InterReqType } from '~/api/interface';
import { insertBannerInfo, listBannerInfoPage } from '~/api/interface/commonType'; import { insertBannerInfo, listBannerInfoPage } from '~/api/interface/commonType';
import { CommonAPI } from '~/api'; import { CommonAPI } from '~/api';
import { PlusOutlined } from '@ant-design/icons'; import { PlusOutlined } from '@ant-design/icons';
import { Uploader } from '~/components/uploader'; import { Uploader } from '~/components/uploader';
import RichText from '~/components/richText'; import RichText from '~/components/richText';
import dayjs from 'dayjs';
// 列表的类型 // 列表的类型
type TableType = InterListType<listBannerInfoPage>; type TableType = InterListType<listBannerInfoPage>;
...@@ -45,6 +46,8 @@ const AddEditModal: React.FC<propType> = (props) => { ...@@ -45,6 +46,8 @@ const AddEditModal: React.FC<propType> = (props) => {
const [form] = Form.useForm<ReqType>(); const [form] = Form.useForm<ReqType>();
// 上传图片 // 上传图片
const [bannerTypeValue, setBannerTypeValue] = useState(0); const [bannerTypeValue, setBannerTypeValue] = useState(0);
// 是否有效
const [validTime, setValidTime] = useState<number>(0);
// 关闭弹窗 // 关闭弹窗
const handleCancel = () => { const handleCancel = () => {
setBannerTypeValue(0); setBannerTypeValue(0);
...@@ -56,7 +59,7 @@ const AddEditModal: React.FC<propType> = (props) => { ...@@ -56,7 +59,7 @@ const AddEditModal: React.FC<propType> = (props) => {
form form
.validateFields() .validateFields()
.then(async (values) => { .then(async (values) => {
await handleSubmit(values); await handleSubmit(values as ReqType & { timeRange: string[] });
}) })
.catch((err) => { .catch((err) => {
message message
...@@ -67,9 +70,15 @@ const AddEditModal: React.FC<propType> = (props) => { ...@@ -67,9 +70,15 @@ const AddEditModal: React.FC<propType> = (props) => {
}); });
}; };
// 提交事件 // 提交事件
const handleSubmit = async (values: ReqType) => { const handleSubmit = async (values: ReqType & { timeRange: string[] }) => {
const res = await CommonAPI[data?.id ? 'updateBannerInfo' : 'insertBannerInfo']({ const res = await CommonAPI[data?.id ? 'updateBannerInfo' : 'insertBannerInfo']({
...values, ...values,
startTime: values.timeRange
? dayjs(values.timeRange[0]).format('YYYY-MM-DD HH:mm:ss')
: undefined,
endTime: values.timeRange
? dayjs(values.timeRange[1]).format('YYYY-MM-DD HH:mm:ss')
: undefined,
moduleId, moduleId,
id: data?.id, id: data?.id,
}); });
...@@ -84,6 +93,11 @@ const AddEditModal: React.FC<propType> = (props) => { ...@@ -84,6 +93,11 @@ const AddEditModal: React.FC<propType> = (props) => {
if (!data) return; if (!data) return;
form.setFieldsValue(data); form.setFieldsValue(data);
setBannerTypeValue(data?.bannerType); setBannerTypeValue(data?.bannerType);
if (data?.endTime && data?.startTime) {
setValidTime(1);
form.setFieldValue('validTime', 1);
form.setFieldValue('timeRange', [dayjs(data?.startTime), dayjs(data?.endTime)]);
}
// console.log('data --->', data); // console.log('data --->', data);
}, [open]); }, [open]);
return ( return (
...@@ -110,8 +124,50 @@ const AddEditModal: React.FC<propType> = (props) => { ...@@ -110,8 +124,50 @@ const AddEditModal: React.FC<propType> = (props) => {
{ label: '下架', value: 0 }, { label: '下架', value: 0 },
]} ]}
allowClear allowClear
onChange={(e) => {
if (e === 1) {
form.setFieldValue('timeRange', undefined);
}
}}
/> />
</Form.Item> </Form.Item>
<Form.Item label='有效时间' required wrapperCol={{ span: 18 }}>
<Space.Compact>
<Form.Item
name={'validTime'}
noStyle
rules={[{ required: true, message: '请选择是否有效' }]}
initialValue={0}
>
<Select
placeholder='请选择是否有效'
options={[
{ label: '永久有效', value: 0 },
{ label: '有效期限', value: 1 },
]}
style={{ width: '30%' }}
value={validTime}
onChange={(e) => {
setValidTime(e);
if (e === 0) {
form.setFieldValue('timeRange', undefined);
}
}}
/>
</Form.Item>
<Form.Item
name={'timeRange'}
noStyle
rules={[{ required: validTime === 1, message: '请选择有效期限' }]}
>
<DatePicker.RangePicker
showTime={{ format: 'HH:mm:ss' }}
format='YYYY-MM-DD HH:mm:ss'
disabled={validTime === 0}
/>
</Form.Item>
</Space.Compact>
</Form.Item>
<Form.Item <Form.Item
label='封面图' label='封面图'
name='bannerImg' name='bannerImg'
...@@ -207,7 +263,10 @@ const AddEditModal: React.FC<propType> = (props) => { ...@@ -207,7 +263,10 @@ const AddEditModal: React.FC<propType> = (props) => {
<Form.Item <Form.Item
label='链接地址' label='链接地址'
name='bannerUrl' name='bannerUrl'
rules={[{ required: true, message: '请输入链接地址' }]} rules={[
{ required: true, message: '请输入链接地址' },
{ pattern: /^[^\s]*$/, message: '地址不能包含空格' },
]}
> >
<Input placeholder={'请输入链接地址'} maxLength={100} allowClear /> <Input placeholder={'请输入链接地址'} maxLength={100} allowClear />
</Form.Item> </Form.Item>
......
...@@ -17,10 +17,11 @@ interface propType { ...@@ -17,10 +17,11 @@ interface propType {
} }
// 所属产品 // 所属产品
const moduleType = [ const moduleType = [
{ label: '云享飞', value: 0 }, { label: '云享飞Pro', value: 0 },
{ label: '云飞手', value: 1 }, { label: '云享飞Web', value: 1 },
{ label: '云仓', value: 2 }, // { label: '云飞手', value: 1 },
{ label: '无人机城', value: 3 }, // { label: '云仓', value: 2 },
// { label: '无人机城', value: 3 },
]; ];
const AddModuleModal: React.FC<propType> = (props) => { const AddModuleModal: React.FC<propType> = (props) => {
......
...@@ -17,10 +17,11 @@ type ReqType = InterReqListType<listBannerInfoPage>; ...@@ -17,10 +17,11 @@ type ReqType = InterReqListType<listBannerInfoPage>;
let query: ReqType = {}; let query: ReqType = {};
// 所属产品 // 所属产品
const moduleType = [ const moduleType = [
{ label: '云享飞', value: '0' }, { label: '云享飞Pro', value: '0' },
{ label: '云飞手', value: '1' }, { label: '云享飞Web', value: '1' },
{ label: '云仓', value: '2' }, // { label: '云飞手', value: '1' },
{ label: '无人机城', value: '3' }, // { label: '云仓', value: '2' },
// { label: '无人机城', value: '3' },
]; ];
// 详情类型 // 详情类型
const bannerType = [ const bannerType = [
...@@ -37,6 +38,8 @@ const bannerType = [ ...@@ -37,6 +38,8 @@ const bannerType = [
{ label: '链接', value: 8 }, { label: '链接', value: 8 },
{ label: '富文本', value: 11 }, { label: '富文本', value: 11 },
]; ];
// 全部数据
// let tableDataAll: TableType = [];
const MaterielManageDetail = () => { const MaterielManageDetail = () => {
const { confirm } = Modal; const { confirm } = Modal;
...@@ -120,6 +123,7 @@ const MaterielManageDetail = () => { ...@@ -120,6 +123,7 @@ const MaterielManageDetail = () => {
if (res && res.code === '200') { if (res && res.code === '200') {
const { list } = res.result; // 解构 const { list } = res.result; // 解构
setTableDataAll(list || []); setTableDataAll(list || []);
// tableDataAll = list || [];
} }
}; };
// 切换排序 // 切换排序
...@@ -147,24 +151,30 @@ const MaterielManageDetail = () => { ...@@ -147,24 +151,30 @@ const MaterielManageDetail = () => {
setSortBtnDisabled(true); setSortBtnDisabled(true);
// 转换位置 // 转换位置
const res = await CommonAPI.exchangeBannerInfo( const res = await CommonAPI.exchangeBannerInfo(
from === 'up' ? [tableDataAll[index - 1], item] : [tableDataAll[index + 1], item], from === 'up'
? [tableDataAll[index - 1], tableDataAll[index]]
: [tableDataAll[index + 1], tableDataAll[index]],
); );
if (res && res.code === '200') { if (res && res.code === '200') {
message.success('操作成功').then(); message.success('操作成功').then();
setSortBtnDisabled(false);
// setSelectedRows(from === 'up' ? [tableDataAll[index - 1]] : [tableDataAll[index + 1]]); // setSelectedRows(from === 'up' ? [tableDataAll[index - 1]] : [tableDataAll[index + 1]]);
// 如果是当前页的第一条数据 // 如果是当前页的第一条数据
if (tableIndex === 0 && from === 'up') { if (tableIndex === 0 && from === 'up') {
paginationChange(pagination.current - 1, pagination.pageSize); paginationChange(pagination.current - 1, pagination.pageSize);
await getAllData();
await setSortBtnDisabled(false);
return; return;
} }
// 如果是当前页的最后一条数据 // 如果是当前页的最后一条数据
if (tableIndex === tableData.length - 1 && from === 'down') { if (tableIndex === tableData.length - 1 && from === 'down') {
paginationChange(pagination.current + 1, pagination.pageSize); paginationChange(pagination.current + 1, pagination.pageSize);
await getAllData();
await setSortBtnDisabled(false);
return; return;
} }
paginationChange(pagination.current, pagination.pageSize); paginationChange(pagination.current, pagination.pageSize);
getAllData().then(); await getAllData();
await setSortBtnDisabled(false);
} }
}; };
// 修改提交数据 // 修改提交数据
...@@ -208,6 +218,13 @@ const MaterielManageDetail = () => { ...@@ -208,6 +218,13 @@ const MaterielManageDetail = () => {
width: '50px', width: '50px',
render: (_text, _record, index) => (pagination.current - 1) * pagination.pageSize + index + 1, render: (_text, _record, index) => (pagination.current - 1) * pagination.pageSize + index + 1,
}, },
// {
// title: 'sort',
// dataIndex: 'sort',
// align: 'center',
// width: '100px',
// ellipsis: true,
// },
{ {
title: '名称', title: '名称',
dataIndex: 'bannerName', dataIndex: 'bannerName',
...@@ -254,6 +271,23 @@ const MaterielManageDetail = () => { ...@@ -254,6 +271,23 @@ const MaterielManageDetail = () => {
render: (text) => (text === 1 ? '上架' : '下架'), render: (text) => (text === 1 ? '上架' : '下架'),
}, },
{ {
title: '有效时间',
dataIndex: 'createTime',
align: 'center',
width: '120px',
ellipsis: true,
render: (_text, record) =>
record.startTime && record.endTime ? (
<>
<div>{record?.startTime}</div>
<div></div>
<div>{record?.endTime}</div>
</>
) : (
'永久'
),
},
{
title: '操作', title: '操作',
dataIndex: 'action', dataIndex: 'action',
align: 'center', align: 'center',
...@@ -393,6 +427,7 @@ const MaterielManageDetail = () => { ...@@ -393,6 +427,7 @@ const MaterielManageDetail = () => {
setAddModalVisible(false); setAddModalVisible(false);
setEditData(undefined); setEditData(undefined);
paginationChange(pagination.current, pagination.pageSize); paginationChange(pagination.current, pagination.pageSize);
getAllData().then();
}} }}
moduleId={Number(qs.parse(location.search).id)} moduleId={Number(qs.parse(location.search).id)}
/> />
......
...@@ -19,10 +19,10 @@ type ReqType = InterReqListType<listModuleInfoPage>; ...@@ -19,10 +19,10 @@ type ReqType = InterReqListType<listModuleInfoPage>;
let query: ReqType = {}; let query: ReqType = {};
// 所属产品 // 所属产品
const moduleType = [ const moduleType = [
{ label: '云享飞', value: 0 }, { label: '云享飞Pro', value: 0 },
{ label: '云飞手', value: 1 }, { label: '云享飞Web', value: 1 },
{ label: '云仓', value: 2 }, // { label: '云仓', value: 2 },
{ label: '无人机城', value: 3 }, // { label: '无人机城', value: 3 },
]; ];
const MaterielManageView = () => { const MaterielManageView = () => {
...@@ -184,7 +184,7 @@ const MaterielManageView = () => { ...@@ -184,7 +184,7 @@ const MaterielManageView = () => {
search={[ search={[
{ {
label: '模块名称', label: '模块名称',
name: 'keyword', name: 'moduleName',
type: 'input', type: 'input',
placeholder: '请输入模块名称', placeholder: '请输入模块名称',
}, },
......
.require-description{
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
cursor: pointer;
}
import SearchBox, { searchColumns } from '~/components/search-box';
import { useEffect, useState } from 'react';
import { Button, message, Modal, Table, Tooltip } from 'antd';
import { ColumnsType } from 'antd/es/table';
import { ResourceManageAPI } from '~/api';
import { InterDataType, InterReqType, PaginationProps } from '~/api/interface';
import './index.scss';
import { listPublishPageType } from '~/api/interface/resourceManageType';
//需求列表返回类型
type requirementsType = InterDataType<listPublishPageType>['list'];
type requirementsParameter = Omit<InterReqType<listPublishPageType>, 'pageSize' | 'pageNo'>;
const RequirementsGathering = () => {
const [searchColumnsData, setSearchColumnsData] = useState<searchColumns[]>([
{
label: '需求类型',
type: 'select',
placeholder: '请选择需求类型',
name: 'requirementTypeId',
options: [],
},
{
label: '需求发起人',
type: 'input',
placeholder: '输入姓名/手机号搜索',
name: 'keyword',
},
]);
const tableColumn: ColumnsType<requirementsType[0]> = [
{
title: '需求类型',
align: 'center',
dataIndex: 'requirementTypeName',
},
{
title: '姓名',
align: 'center',
dataIndex: 'publishName',
},
{
title: '手机号',
align: 'center',
dataIndex: 'publishPhone',
},
{
title: '需求描述',
align: 'center',
dataIndex: 'requireDescription',
width: '20%',
ellipsis: true,
render: (text: string) => (
<Tooltip placement='top' title={text}>
<div className='require-description'>{text}</div>
</Tooltip>
),
},
{
title: '操作',
align: 'center',
render: (_text: string, record) => (
<>
<Button type='link' danger onClick={() => deleteRequirements(record)}>
强制删除
</Button>
<Button type='link'>联系客户</Button>
</>
),
},
];
const [tableData, setTableData] = useState<requirementsType>([]);
const [loading, setLoading] = useState<boolean>(false);
const [pagination, setPagination] = useState<PaginationProps & { totalCount: number }>({
pageNo: 1,
pageSize: 10,
totalCount: 0,
});
const [query, setQuery] = useState<requirementsParameter>();
//筛选
const searchSuccessEvent = (value: any) => {
pagination.pageSize = 10;
pagination.pageNo = 1;
setQuery(value);
getRequirementsList(value);
};
//分页
const paginationChange = (pageNo: number, pageSize: number) => {
pagination.pageNo = pageNo;
pagination.pageSize = pageSize;
getRequirementsList(query);
};
//需求列表
const getRequirementsList = (query?: requirementsParameter) => {
setLoading(true);
ResourceManageAPI.getListPublishPage({
pageSize: pagination.pageSize,
pageNo: pagination.pageNo,
...query,
}).then(({ result }) => {
setLoading(false);
setTableData(result.list || []);
pagination.totalCount = result.totalCount;
setPagination(pagination);
});
};
//需求类型列表
const getRequirementsTypeList = () => {
ResourceManageAPI.getRequirementTypeList().then(({ result }) => {
searchColumnsData[0].options = result.map((v) => ({ id: v.id, name: v.typeName }));
setSearchColumnsData([...searchColumnsData]);
});
};
//需求删除
const deleteRequirements = (record: requirementsType[0]) => {
Modal.confirm({
title: '需求删除',
content: '确认删除该需求?',
onOk: () => {
ResourceManageAPI.deleteRequirement({ requirementsInfoId: record.id }).then(({ code }) => {
if (code === '200') {
message.success('删除成功');
if (pagination.pageNo !== 1 && tableData.length === 1) {
pagination.pageNo -= 1;
}
getRequirementsList(query);
}
});
},
});
};
useEffect(() => {
getRequirementsList();
getRequirementsTypeList();
}, []);
return (
<div className='requirements-gathering'>
<SearchBox search={searchColumnsData} searchData={searchSuccessEvent} />
<Table
bordered
columns={tableColumn}
dataSource={tableData}
rowKey='id'
loading={loading}
pagination={{
total: pagination.totalCount,
pageSize: pagination.pageSize,
current: pagination.pageNo,
showSizeChanger: true,
showQuickJumper: true,
onChange: (page: number, pageSize: number) => paginationChange(page, pageSize),
showTotal: (total, range) => `当前 ${range[0]}-${range[1]} 条记录 / 共 ${total} 条数据`,
}}
/>
</div>
);
};
export default RequirementsGathering;
import { FC } from 'react';
import { Form, Input, Modal, ModalProps, Select } from 'antd';
import { Uploader } from '~/components/uploader';
import { UploadOutlined } from '@ant-design/icons';
interface selfProps {}
const AddOrEditTagModal: FC<ModalProps & selfProps> = ({ open, onCancel }) => {
return (
<Modal open={open} onCancel={onCancel} title='新建标签'>
<Form labelCol={{ span: 4 }} wrapperCol={{ span: 16 }}>
<Form.Item label='标签名称'>
<Input placeholder='请输入标签名称' />
</Form.Item>
<Form.Item label='标签类型'>
<Select placeholder='请选择标签类型'>
<Select.Option>1111</Select.Option>
</Select>
</Form.Item>
<Form.Item label='标签等级图标'>
<Uploader fileUpload listType='picture-card'>
<UploadOutlined />
</Uploader>
</Form.Item>
</Form>
</Modal>
);
};
export default AddOrEditTagModal;
import SearchBox, { searchColumns } from '~/components/search-box';
import { Button, Table } from 'antd';
import { PlusOutlined } from '@ant-design/icons';
import { ColumnsType } from 'antd/es/table';
import { useState } from 'react';
import AddOrEditTagModal from './components/addOrEditTagModal';
//行业新闻
const TagManage = () => {
const searchColumnsData: searchColumns[] = [
{
label: '标签名称',
placeholder: '请输入标签名称',
name: '',
type: 'input',
},
];
const tableColumns: ColumnsType<any> = [
{
title: '序号',
align: 'center',
},
{
title: '标签名称',
align: 'center',
},
{
title: '标签类型',
align: 'center',
},
{
title: '标签等级图标',
align: 'center',
},
{
title: '操作',
align: 'center',
render: () => (
<>
<Button type='link'>编辑</Button>
<Button type='link'>删除</Button>
</>
),
},
];
const [tableData, setTableData] = useState<any>([{ id: 1 }]);
const [addOrEditTagModalShow, setAddOrEditTagModalShow] = useState<boolean>(false);
const addOrEditTagClick = () => {
setAddOrEditTagModalShow(true);
};
const addOrEditTagModalCancel = () => {
setAddOrEditTagModalShow(false);
};
return (
<div className='tag-manage'>
<SearchBox
search={searchColumnsData}
child={
<Button type='primary' icon={<PlusOutlined />} onClick={addOrEditTagClick}>
新建
</Button>
}
/>
<Table bordered columns={tableColumns} dataSource={tableData} rowKey='id'></Table>
<AddOrEditTagModal open={addOrEditTagModalShow} onCancel={addOrEditTagModalCancel} />
</div>
);
};
export default TagManage;
import React, { useEffect } from 'react';
import { Form, Input, message, Modal } from 'antd';
import { InterListType, InterReqType } from '~/api/interface';
import {
releaseTenderNewsInfoUpdate,
releaseTenderNewsInfo,
} from '~/api/interface/resourceManageType';
import { ResourceManageAPI } from '~/api';
import RichText from '~/components/richText';
// 列表的类型
type TableType = InterListType<releaseTenderNewsInfo>;
// 请求的表单类型
type ReqType = InterReqType<releaseTenderNewsInfoUpdate>;
// 传参类型
interface propType {
title: string;
open: boolean;
closed: any;
data?: TableType[0];
}
const AddEditDetailModal: React.FC<propType> = (props) => {
AddEditDetailModal.defaultProps = {
data: undefined,
};
// 参数
const { title, open, closed, data } = props;
// 表单钩子
const [form] = Form.useForm<ReqType>();
// 关闭弹窗
const handleCancel = () => {
form.resetFields();
closed();
};
// 确认事件
const handleOk = () => {
form
.validateFields()
.then(async (values) => {
await handleSubmit(values as ReqType & { file: any[] });
})
.catch((err) => {
message
.warning({
content: err.errorFields[0].errors[0],
})
.then();
});
};
// 提交事件
const handleSubmit = async (values: ReqType) => {
const res = await ResourceManageAPI.releaseTenderNewsInfoUpdate({
...values,
id: Number(data?.id),
});
if (res && res.code === '200') {
message.success('操作成功');
handleCancel();
}
};
// componentDidMount
useEffect(() => {
if (!open) return;
if (!data) return;
form.setFieldsValue(data);
// console.log('data --->', data);
}, [open]);
return (
<Modal
open={open}
title={title}
onCancel={handleCancel}
onOk={handleOk}
destroyOnClose
width={768}
>
<Form
name='Form'
form={form}
labelAlign='right'
labelCol={{ span: 2 }}
wrapperCol={{ span: 21 }}
>
<Form.Item
label='标题'
name='tenderTitle'
rules={[{ required: true, message: '请输入标题' }]}
>
<Input placeholder={'请输入标题'} maxLength={50} allowClear />
</Form.Item>
<Form.Item
label='价格'
name='tenderPrice'
rules={[
{ required: true, message: '请输入价格' },
() => ({
validator(_, value) {
if (value && value.length > 10) {
return Promise.reject('金额不能超过十位数');
}
return Promise.resolve();
},
}),
]}
>
<Input
type={'number'}
placeholder={'请输入价格'}
maxLength={10}
allowClear
suffix={'万元'}
/>
</Form.Item>
<Form.Item
label='详情'
name='tenderContent'
rules={[{ required: true, message: '请输入详情' }]}
>
<RichText
value={form.getFieldValue('tenderContent')}
onChange={(e) => form.setFieldValue('tenderContent', e)}
height={250}
/>
</Form.Item>
</Form>
</Modal>
);
};
export default AddEditDetailModal;
import React, { useEffect } from 'react';
import { Button, Form, Input, message, Modal, Select } from 'antd';
import { InterListType, InterReqType } from '~/api/interface';
import { releaseTenderNewsUpdate, releaseTenderNews } from '~/api/interface/resourceManageType';
import { ResourceManageAPI } from '~/api';
import { Uploader } from '~/components/uploader';
import { UploadOutlined } from '@ant-design/icons';
// 列表的类型
type TableType = InterListType<releaseTenderNews>;
// 请求的表单类型
type ReqType = InterReqType<releaseTenderNewsUpdate>;
// 传参类型
interface propType {
title: string;
open: boolean;
closed: any;
data?: TableType[0];
}
const AddEditModal: React.FC<propType> = (props) => {
AddEditModal.defaultProps = {
data: undefined,
};
// 参数
const { title, open, closed, data } = props;
// 表单钩子
const [form] = Form.useForm<ReqType>();
// 关闭弹窗
const handleCancel = () => {
form.resetFields();
closed();
};
// 确认事件
const handleOk = () => {
form
.validateFields()
.then(async (values) => {
await handleSubmit(values as ReqType & { file: any[] });
})
.catch((err) => {
message
.warning({
content: err.errorFields[0].errors[0],
})
.then();
});
};
// 提交事件
const handleSubmit = async (values: ReqType & { file: any[] }) => {
const formData = new FormData();
formData.append('file', values?.file?.at(-1));
const blob = new Blob([JSON.stringify({ ...values, id: data?.id ? data?.id : null })], {
type: 'application/json',
});
formData.append('tenderNewsVO', blob);
const res = await ResourceManageAPI[
data?.id ? 'releaseTenderNewsUpdate' : 'releaseTenderNewsAdd'
](formData);
if (res && res.code === '200') {
message.success('操作成功');
handleCancel();
}
};
// componentDidMount
useEffect(() => {
if (!open) return;
if (!data) return;
form.setFieldsValue(data);
// console.log('data --->', data);
}, [open]);
return (
<Modal open={open} title={title} onCancel={handleCancel} onOk={handleOk} destroyOnClose>
<Form
name='Form'
form={form}
labelAlign='right'
labelCol={{ span: 5 }}
wrapperCol={{ span: 10 }}
>
<Form.Item
label='招标快讯名称'
name='tenderName'
rules={[{ required: true, message: '请输入名称' }]}
>
<Input placeholder={'请输入名称'} maxLength={20} allowClear />
</Form.Item>
<Form.Item
label='状态'
name='using'
rules={[{ required: true, message: '请选择状态' }]}
initialValue={1}
>
<Select
placeholder={'请选择状态'}
options={[
{ label: '上架', value: 1 },
{ label: '下架', value: 0 },
]}
allowClear
/>
</Form.Item>
<Form.Item
label='上传内容'
name='file'
rules={[{ required: !data?.id, message: '请上传内容' }]}
>
<Uploader
listType={'text'}
fileUpload={false}
fileType={[
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
'application/vnd.ms-excel',
]}
onChange={(e) => {
form.setFieldValue('file', e);
}}
>
<Button icon={<UploadOutlined />} type={'primary'}>
上传
</Button>
</Uploader>
</Form.Item>
</Form>
</Modal>
);
};
export default AddEditModal;
import { useEffect, useState } from 'react';
import { useLocation, useNavigate } from 'react-router-dom';
import SearchBox from '~/components/search-box';
import { Button, Table, Tooltip } from 'antd';
import { ArrowLeftOutlined } from '@ant-design/icons';
import qs from 'query-string';
import { InterListType } from '~/api/interface';
import { releaseTenderNewsInfo } from '~/api/interface/resourceManageType';
import { ResourceManageAPI } from '~/api';
import { ColumnsType } from 'antd/es/table';
import AddEditDetailModal from '~/pages/resourceManage/tenderManage/comp/addEditDetailModal';
// 列表类型
type TableType = InterListType<releaseTenderNewsInfo>;
const TenderManageDetail = () => {
// 路由钩子
const location = useLocation();
// 导航钩子
const navigate = useNavigate();
// 返回上一页
const handleBack = () => {
navigate(-1);
};
// 新增修改弹窗是否开启
const [addModalVisible, setAddModalVisible] = useState(false);
// 需要编辑的数据
const [editData, setEditData] = useState<TableType[0]>();
// 表格数据
const [tableData, setTableData] = useState<TableType>([]);
// 表格分页配置
const [pagination, setPagination] = useState({
total: 0,
pageSize: 10,
current: 1,
totalPage: 0,
});
// 加载列表
const getTableList = async (value = {}) => {
// 只需要修改这个地方的接口即可
const res = await ResourceManageAPI.releaseTenderNewsInfo({
pageNo: pagination.current,
pageSize: pagination.pageSize,
...value,
tenderNewsId: Number(qs.parse(location.search)?.id),
});
if (res && res.code === '200') {
const { list, pageNo, totalCount, pageSize, totalPage } = res.result; // 解构
setPagination({
total: totalCount,
current: pageNo,
pageSize,
totalPage,
});
setTableData(list || []);
}
};
// 翻页
const paginationChange = (pageNo: number, pageSize: number) => {
getTableList({ pageNo, pageSize }).then();
};
// componentDidMount
useEffect(() => {
getTableList().then();
}, []);
// 表格结构
const columns: ColumnsType<TableType[0]> = [
{
title: '序号',
dataIndex: 'accountNo',
align: 'center',
width: '50px',
render: (_text, _record, index) => (pagination.current - 1) * pagination.pageSize + index + 1,
},
{
title: '标题',
dataIndex: 'tenderTitle',
align: 'center',
width: '200px',
ellipsis: true,
},
{
title: '详情',
dataIndex: 'tenderContent',
align: 'center',
width: '300px',
ellipsis: true,
render: (text) =>
text && (
<Tooltip
placement='top'
title={
<div
dangerouslySetInnerHTML={{ __html: text.replace(/<img(?:(?!\/>).|\n)*?\/>/gm, '') }}
/>
}
>
<div
style={{
height: '20px',
overflow: 'hidden',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
wordBreak: 'break-all',
}}
dangerouslySetInnerHTML={{ __html: text }}
/>
</Tooltip>
),
},
{
title: '价格(万元)',
dataIndex: 'tenderPrice',
align: 'center',
width: '100px',
ellipsis: true,
render: (text) => text?.toLocaleString(),
},
{
title: '操作',
dataIndex: 'action',
align: 'center',
width: '100px',
fixed: 'right',
render: (_text, record) => (
<Button
type={'link'}
onClick={() => {
setEditData(JSON.parse(JSON.stringify(record)));
setAddModalVisible(true);
}}
>
编辑
</Button>
),
},
];
return (
<>
<SearchBox
child={
<>
<Button type={'primary'} icon={<ArrowLeftOutlined />} onClick={handleBack}>
返回
</Button>
</>
}
/>
<Table
size='small'
dataSource={tableData}
columns={columns}
rowKey='id'
// scroll={{ x: 1500 }}
bordered
pagination={{
total: pagination.total,
pageSize: pagination.pageSize,
current: pagination.current,
showSizeChanger: true,
showQuickJumper: true,
onChange: (page: number, pageSize: number) => paginationChange(page, pageSize),
showTotal: (total, range) => `当前 ${range[0]}-${range[1]} 条记录 / 共 ${total} 条数据`,
}}
/>
<AddEditDetailModal
open={addModalVisible}
title={editData?.id ? '编辑' : '新增'}
data={editData}
closed={() => {
setAddModalVisible(false);
setEditData(undefined);
paginationChange(pagination.current, pagination.pageSize);
}}
/>
</>
);
};
export default TenderManageDetail;
import { useEffect, useState } from 'react';
import SearchBox from '~/components/search-box';
import { ResourceManageAPI } from '~/api';
import qs from 'query-string';
import { useLocation, useNavigate } from 'react-router-dom';
import { Button, Table } from 'antd';
import { ArrowLeftOutlined } from '@ant-design/icons';
import {
releaseTenderNewsApplyList,
releaseTenderNewsInfo,
} from '~/api/interface/resourceManageType';
import { InterListType, InterReqListType } from '~/api/interface';
import { ColumnsType } from 'antd/es/table';
// 列表类型
type ListType = InterListType<releaseTenderNewsInfo>;
// 表格类型
type TableType = InterListType<releaseTenderNewsApplyList>;
// 请求的参数
type ReqType = InterReqListType<releaseTenderNewsApplyList>;
// 搜索表单的数据
let query: ReqType = {};
const TenderManageFeedback = () => {
// 路由钩子
const location = useLocation();
// 导航钩子
const navigate = useNavigate();
// 返回上一页
const handleBack = () => {
navigate(-1);
};
// 表格数据
const [tableData, setTableData] = useState<TableType>([]);
// 表格分页配置
const [pagination, setPagination] = useState({
total: 0,
pageSize: 10,
current: 1,
totalPage: 0,
});
// 快讯详情列表
const [tenderInfoList, setTenderInfoId] = useState<
{ value: number; label: string; data: ListType[0] }[]
>([]);
// 获取快讯详情列表
const getNewsInfoList = async () => {
const res = await ResourceManageAPI.releaseTenderNewsInfo({
pageNo: 1,
pageSize: 9999,
tenderNewsId: Number(qs.parse(location.search)?.id),
});
if (res && res.code === '200') {
const list = res.result?.list || [];
setTenderInfoId(
list?.map((i, j) => ({
value: i.id,
label: `${j + 1}${i.tenderTitle}`,
data: i,
})),
);
}
};
// 加载列表
const getTableList = async (value = {}) => {
// 只需要修改这个地方的接口即可
const res = await ResourceManageAPI.releaseTenderNewsApplyList({
pageNo: pagination.current,
pageSize: pagination.pageSize,
...value,
...query,
tenderNewsId: Number(qs.parse(location.search)?.id),
});
if (res && res.code === '200') {
const { list, pageNo, totalCount, pageSize, totalPage } = res.result; // 解构
setPagination({
total: totalCount,
current: pageNo,
pageSize,
totalPage,
});
setTableData(list);
}
};
// 翻页
const paginationChange = (pageNo: number, pageSize: number) => {
getTableList({ pageNo, pageSize }).then();
};
// 表单提交
const onFinish = (data: ReqType) => {
pagination.current = 1;
query = data;
getTableList(data).then();
};
// componentDidMount
useEffect(() => {
query = {};
getNewsInfoList().then();
getTableList().then();
}, []);
// 表格结构
const columns: ColumnsType<TableType[0]> = [
{
title: '编号',
dataIndex: 'tenderInfoNo',
align: 'center',
},
{
title: '标题',
dataIndex: 'tenderTitle',
align: 'center',
ellipsis: true,
},
{
title: '用户昵称',
dataIndex: 'nickName',
align: 'center',
},
{
title: '用户姓名',
dataIndex: 'userName',
align: 'center',
},
{
title: '电话号码',
dataIndex: 'phoneNum',
align: 'center',
},
];
return (
<>
<SearchBox
search={[
{
label: '项目编号',
name: 'tenderInfoId',
type: 'Select',
placeholder: '请选择编号',
options: tenderInfoList,
},
{ label: '用户姓名', name: 'userName', type: 'input', placeholder: '请输入用户姓名' },
]}
searchData={onFinish}
child={
<>
<Button type={'primary'} icon={<ArrowLeftOutlined />} onClick={handleBack}>
返回
</Button>
</>
}
/>
<Table
size='small'
dataSource={tableData}
columns={columns}
rowKey='id'
// scroll={{ x: 1500 }}
bordered
pagination={{
total: pagination.total,
pageSize: pagination.pageSize,
current: pagination.current,
showSizeChanger: true,
showQuickJumper: true,
onChange: (page: number, pageSize: number) => paginationChange(page, pageSize),
showTotal: (total, range) => `当前 ${range[0]}-${range[1]} 条记录 / 共 ${total} 条数据`,
}}
/>
</>
);
};
export default TenderManageFeedback;
import { useEffect, useState } from 'react';
import SearchBox from '~/components/search-box';
import { Button, message, Modal, Table } from 'antd';
import { PlusOutlined, DownloadOutlined } from '@ant-design/icons';
import { ColumnsType } from 'antd/es/table';
import { ResourceManageAPI } from '~/api';
import { InterListType, InterReqListType } from '~/api/interface';
import { releaseTenderNews } from '~/api/interface/resourceManageType';
import AddEditModal from './comp/addEditModal';
import qs from 'query-string';
import { useNavigate } from 'react-router-dom';
import saveAs from 'file-saver';
// 列表类型
type TableType = InterListType<releaseTenderNews>;
// 请求的参数
type ReqType = InterReqListType<releaseTenderNews>;
// 搜索表单的数据
let query: ReqType = {};
const TenderManageView = () => {
const { confirm } = Modal;
// 路由钩子
const navigate = useNavigate();
// 新增弹窗
const [addModalVisible, setAddModalVisible] = useState<boolean>(false);
// 需要编辑的数据
const [editData, setEditData] = useState<TableType[0]>();
// 表格数据
const [tableData, setTableData] = useState<TableType>([]);
// 表格分页配置
const [pagination, setPagination] = useState({
total: 0,
pageSize: 10,
current: 1,
totalPage: 0,
});
// 加载列表
const getTableList = async (value = {}) => {
// 只需要修改这个地方的接口即可
const res = await ResourceManageAPI.releaseTenderNews({
pageNo: pagination.current,
pageSize: pagination.pageSize,
...value,
...query,
});
if (res && res.code === '200') {
const { list, pageNo, totalCount, pageSize, totalPage } = res.result; // 解构
setPagination({
total: totalCount,
current: pageNo,
pageSize,
totalPage,
});
setTableData(list);
}
};
// 翻页
const paginationChange = (pageNo: number, pageSize: number) => {
getTableList({ pageNo, pageSize }).then();
};
// 表单提交
const onFinish = (data: ReqType & { rangeTime: string[] }) => {
pagination.current = 1;
query = {
startTime: data.rangeTime ? data.rangeTime[0] : undefined,
endTime: data.rangeTime ? data.rangeTime[1] : undefined,
tenderName: data.tenderName,
using: data.using,
};
getTableList(query).then();
};
// 删除数据
const handleDelete = (record: TableType[0]) => {
confirm({
title: '提示',
content: '是否删除该记录?',
onOk: async () => {
const res = await ResourceManageAPI.releaseTenderNewsDelete({ id: record.id });
if (res && res.code === '200') {
message.success('删除成功');
paginationChange(
tableData.length === 1 ? pagination.current - 1 : pagination.current,
pagination.pageSize,
);
}
},
});
};
// 跳转详情
const handleDetail = (record: TableType[0]) => {
const search = {
id: record.id,
};
navigate(`/resourceManage/tenderManage/detail?${qs.stringify(search)}`);
};
// 跳转反馈
const handleFeedback = (record: TableType[0]) => {
const search = {
id: record.id,
};
navigate(`/resourceManage/tenderManage/feedback?${qs.stringify(search)}`);
};
// componentDidMount
useEffect(() => {
query = {};
getTableList().then();
}, []);
// 表格结构
const columns: ColumnsType<TableType[0]> = [
{
title: '招标快讯名称',
dataIndex: 'tenderName',
align: 'center',
ellipsis: true,
},
{
title: '发布时间',
dataIndex: 'createTime',
align: 'center',
},
{
title: '状态',
dataIndex: 'using',
align: 'center',
render: (text) => (text === 1 ? '上架' : '下架'),
},
{
title: '操作',
dataIndex: 'action',
align: 'center',
width: '200px',
fixed: 'right',
render: (_text, record) => (
<>
<Button type={'link'} onClick={() => handleDetail(record)}>
详情
</Button>
<Button
type={'link'}
onClick={() => {
setEditData(JSON.parse(JSON.stringify(record)));
setAddModalVisible(true);
}}
>
编辑
</Button>
<Button type={'link'} onClick={() => handleFeedback(record)}>
用户反馈
</Button>
<Button type={'link'} danger onClick={() => handleDelete(record)}>
删除
</Button>
</>
),
},
];
return (
<>
<SearchBox
search={[
{ name: 'tenderName', label: '名称', type: 'input', placeholder: '请输入招标快讯名称' },
{
name: 'rangeTime',
label: '发布时间',
type: 'rangePicker',
placeholder: '请选择开始时间和结束时间',
},
]}
searchData={onFinish}
child={
<>
<Button
type={'primary'}
icon={<PlusOutlined />}
onClick={() => {
setAddModalVisible(true);
}}
>
新增
</Button>
</>
}
otherChild={
<>
<Button
type={'primary'}
icon={<DownloadOutlined />}
onClick={() => {
saveAs(
'https://pad-video-x.oss-cn-shenzhen.aliyuncs.com/doc/tender-news-template.xlsx',
`招标快讯模板_${new Date().getTime()}.xlsx`,
);
}}
>
下载模板
</Button>
</>
}
/>
<Table
size='small'
dataSource={tableData}
columns={columns}
rowKey='id'
// scroll={{ x: 1500 }}
bordered
pagination={{
total: pagination.total,
pageSize: pagination.pageSize,
current: pagination.current,
showSizeChanger: true,
showQuickJumper: true,
onChange: (page: number, pageSize: number) => paginationChange(page, pageSize),
showTotal: (total, range) => `当前 ${range[0]}-${range[1]} 条记录 / 共 ${total} 条数据`,
}}
/>
<AddEditModal
open={addModalVisible}
title={editData?.id ? '编辑' : '新增'}
data={editData}
closed={() => {
setAddModalVisible(false);
setEditData(undefined);
paginationChange(pagination.current, pagination.pageSize);
}}
/>
</>
);
};
export default TenderManageView;
...@@ -3,10 +3,7 @@ import { Navigate, RouteObject } from 'react-router-dom'; ...@@ -3,10 +3,7 @@ import { Navigate, RouteObject } from 'react-router-dom';
import ErrorPage from '~/pages/common/error'; import ErrorPage from '~/pages/common/error';
import LayoutView from '~/components/layout'; import LayoutView from '~/components/layout';
import { import {
// AccountBookOutlined,
MacCommandOutlined, MacCommandOutlined,
// GiftOutlined,
// PayCircleOutlined,
BarsOutlined, BarsOutlined,
ShoppingOutlined, ShoppingOutlined,
ShopOutlined, ShopOutlined,
...@@ -27,6 +24,14 @@ import { ...@@ -27,6 +24,14 @@ import {
BookOutlined, BookOutlined,
SketchOutlined, SketchOutlined,
DribbbleOutlined, DribbbleOutlined,
MessageOutlined,
AliwangwangOutlined,
AuditOutlined,
MonitorOutlined,
PictureOutlined,
PaperClipOutlined,
ReadOutlined,
ThunderboltOutlined,
} from '@ant-design/icons'; } from '@ant-design/icons';
// eslint-disable-next-line @typescript-eslint/ban-ts-comment // eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore // @ts-ignore
...@@ -34,6 +39,7 @@ import { AgnosticIndexRouteObject } from '@remix-run/router'; ...@@ -34,6 +39,7 @@ import { AgnosticIndexRouteObject } from '@remix-run/router';
import { Spin } from 'antd'; import { Spin } from 'antd';
// 登录 // 登录
import LoginView from '~/pages/common/login'; import LoginView from '~/pages/common/login';
// 积分 // 积分
// import { PointList } from '~/pages/pointManage/pointList'; // import { PointList } from '~/pages/pointManage/pointList';
// import { PointDetail } from '~/pages/pointManage/pointList/detail'; // import { PointDetail } from '~/pages/pointManage/pointList/detail';
...@@ -42,18 +48,32 @@ import LoginView from '~/pages/common/login'; ...@@ -42,18 +48,32 @@ import LoginView from '~/pages/common/login';
// 分成 // 分成
// import DivideOrder from '~/pages/pointManage/divideOrder'; // import DivideOrder from '~/pages/pointManage/divideOrder';
// import DivideRules from '~/pages/pointManage/divideRules'; // import DivideRules from '~/pages/pointManage/divideRules';
// 客户列表 // 活动
// const ActivityList = React.lazy(() => import('src/pages/activityManage/activityList')); //活动管理
// 客户管理
import CustomListView from '~/pages/customManage/customList'; import CustomListView from '~/pages/customManage/customList';
import CustomMoneyView from '~/pages/customManage/customMoney'; import CustomMoneyView from '~/pages/customManage/customMoney';
import CustomMoneyDetail from '~/pages/customManage/customMoney/detail'; import CustomMoneyDetail from '~/pages/customManage/customMoney/detail';
import AccountManageView from '~/pages/systemManage/accountManage'; //资源管理
import CourseManageView from '~/pages/mallManage/courseManage';
import MaterielManageView from '~/pages/resourceManage/materielManage'; import MaterielManageView from '~/pages/resourceManage/materielManage';
import MaterielManageDetail from '~/pages/resourceManage/materielManage/detail'; import MaterielManageDetail from '~/pages/resourceManage/materielManage/detail';
// 活动 const RequirementsGatheringView = React.lazy(
// const ActivityList = React.lazy(() => import('src/pages/activityManage/activityList')); //活动管理 () => import('~/pages/resourceManage/requirementsGathering'),
); //需求收集
const TagManageView = React.lazy(() => import('~/pages/resourceManage/tagManage')); //标签管理
const IndustryNewsView = React.lazy(() => import('~/pages/resourceManage/industryNews'));
//论坛管理
const DynamicListView = React.lazy(() => import('~/pages/forumManage/dynamicList'));
// 订单
const ProductOrderView = React.lazy(() => import('src/pages/orderManage/productOrder')); //销售订单
const EquipmentOrderView = React.lazy(() => import('src/pages/orderManage/equipmentOrder')); //设备订单
const ServiceOrderView = React.lazy(() => import('src/pages/orderManage/serviceOrder')); //服务订单
const ProductOrderDetail = React.lazy(() => import('~/pages/orderManage/productOrder/detail'));
const ServiceOrderDetail = React.lazy(() => import('~/pages/orderManage/serviceOrder/detail'));
const EquipmentOrderDetail = React.lazy(() => import('~/pages/orderManage/equipmentOrder/detail'));
//商品管理 //商品管理
import CourseManageView from '~/pages/mallManage/courseManage'; //课程管理
const ServiceListView = React.lazy(() => import('~/pages/mallManage/serviceManage/serviceList')); //服务列表 const ServiceListView = React.lazy(() => import('~/pages/mallManage/serviceManage/serviceList')); //服务列表
const ServiceDetailView = React.lazy( const ServiceDetailView = React.lazy(
() => import('~/pages/mallManage/serviceManage/serviceDetail'), () => import('~/pages/mallManage/serviceManage/serviceDetail'),
...@@ -74,19 +94,25 @@ const ProduceDetailView = React.lazy( ...@@ -74,19 +94,25 @@ const ProduceDetailView = React.lazy(
() => import('~/pages/mallManage/produceManage/produceDetail'), () => import('~/pages/mallManage/produceManage/produceDetail'),
); //产品详情 ); //产品详情
const MakeListView = React.lazy(() => import('~/pages/mallManage/makeManage/makeList')); const MakeListView = React.lazy(() => import('~/pages/mallManage/makeManage/makeList'));
// 分类管理
const CategoryManage = React.lazy(() => import('~/pages/categoryManage/category'));
const CategoryDetail = React.lazy(() => import('~/pages/categoryManage/category/detail'));
// 目录管理
const DirectoryManage = React.lazy(() => import('~/pages/categoryManage/directoryManage'));
// 系统管理
import AccountManageView from '~/pages/systemManage/accountManage';
import TenderManageView from '~/pages/resourceManage/tenderManage';
import TenderManageDetail from '~/pages/resourceManage/tenderManage/detail';
import TenderManageFeedback from '~/pages/resourceManage/tenderManage/feedback';
import BusinessCaseManage from '~/pages/resourceManage/businessCaseManage';
import CustomIdentityView from '~/pages/customManage/customIdentity';
// const IndustryListView = React.lazy(() => import('~/pages/mallManage/industryManage/industryList')); //行业列表 // const IndustryListView = React.lazy(() => import('~/pages/mallManage/industryManage/industryList')); //行业列表
// const IndustryDetailView = React.lazy( // const IndustryDetailView = React.lazy(
// () => import('~/pages/mallManage/industryManage/industryDetail'), // () => import('~/pages/mallManage/industryManage/industryDetail'),
// ); //行业详情 // ); //行业详情
// 订单
const ProductOrderView = React.lazy(() => import('src/pages/orderManage/productOrder')); //销售订单
const EquipmentOrderView = React.lazy(() => import('src/pages/orderManage/equipmentOrder')); //设备订单
const ServiceOrderView = React.lazy(() => import('src/pages/orderManage/serviceOrder')); //服务订单
const ProductOrderDetail = React.lazy(() => import('~/pages/orderManage/productOrder/detail'));
const ServiceOrderDetail = React.lazy(() => import('~/pages/orderManage/serviceOrder/detail'));
const EquipmentOrderDetail = React.lazy(() => import('~/pages/orderManage/equipmentOrder/detail'));
// 优惠券 // 优惠券
// const CouponList = React.lazy(() => import('src/pages/couponManage/couponList')); //优惠券管理 // const CouponList = React.lazy(() => import('src/pages/couponManage/couponList')); //优惠券管理
// const CouponDetail = React.lazy(() => import('src/pages/couponManage/couponList/detail')); //优惠券明细 // const CouponDetail = React.lazy(() => import('src/pages/couponManage/couponList/detail')); //优惠券明细
...@@ -96,11 +122,6 @@ const EquipmentOrderDetail = React.lazy(() => import('~/pages/orderManage/equipm ...@@ -96,11 +122,6 @@ const EquipmentOrderDetail = React.lazy(() => import('~/pages/orderManage/equipm
// ); // 裂变优惠券操作 // ); // 裂变优惠券操作
// const CouponDetailed = React.lazy(() => import('src/pages/couponManage/couponDetailed')); //优惠券明细 // const CouponDetailed = React.lazy(() => import('src/pages/couponManage/couponDetailed')); //优惠券明细
// 分类管理
const CategoryManage = React.lazy(() => import('~/pages/categoryManage/category'));
const CategoryDetail = React.lazy(() => import('~/pages/categoryManage/category/detail'));
// 目录管理
const DirectoryManage = React.lazy(() => import('~/pages/categoryManage/directoryManage'));
export interface RouteObjectType { export interface RouteObjectType {
path: AgnosticIndexRouteObject['path']; path: AgnosticIndexRouteObject['path'];
element: any; element: any;
...@@ -153,6 +174,173 @@ export const whiteRouterList: Array<RouteObject & RouteObjectType> = [ ...@@ -153,6 +174,173 @@ export const whiteRouterList: Array<RouteObject & RouteObjectType> = [
// 路由数组 // 路由数组
export const routerList: Array<RouteObjectType> = [ export const routerList: Array<RouteObjectType> = [
{ {
path: '/customManage',
element: <LayoutView />,
errorElement: <ErrorPage />,
meta: {
id: 22000,
icon: <TeamOutlined />,
title: '客户管理',
},
children: [
{
path: '/customManage/customList',
element: withLoadingComponent(<CustomListView />),
meta: {
id: 26100,
title: '客户列表',
icon: <SolutionOutlined />,
},
},
{
path: '/customManage/customMoney',
element: withLoadingComponent(<CustomMoneyView />),
meta: {
id: 26200,
title: '现金管理',
icon: <RedEnvelopeOutlined />,
hidden: true,
},
},
{
path: '/customManage/customMoney/detail',
element: withLoadingComponent(<CustomMoneyDetail />),
meta: {
id: 26200,
title: '现金变更',
icon: <RedEnvelopeOutlined />,
hidden: true,
},
},
{
path: '/customManage/customIdentity',
element: withLoadingComponent(<CustomIdentityView />),
meta: {
id: 26300,
title: '加盟入驻',
icon: <AuditOutlined />,
},
},
],
},
{
path: '/resourceManage',
element: <LayoutView />,
errorElement: <ErrorPage />,
meta: {
id: 30000,
icon: <DribbbleOutlined />,
title: '资源管理',
},
children: [
{
path: '/resourceManage/requirementsGathering',
element: withLoadingComponent(<RequirementsGatheringView />),
meta: {
id: 30200,
title: '需求收集',
icon: <MonitorOutlined />,
},
},
{
path: '/resourceManage/materielManage',
element: withLoadingComponent(<MaterielManageView />),
meta: {
id: 30100,
title: '宣传管理',
icon: <PictureOutlined />,
},
},
{
path: '/resourceManage/materielManage/detail',
element: withLoadingComponent(<MaterielManageDetail />),
meta: {
id: 30100,
title: '宣传管理详情',
icon: <SketchOutlined />,
hidden: true,
},
},
{
path: '/resourceManage/tagManage',
element: withLoadingComponent(<TagManageView />),
meta: {
id: 30300,
title: '标签管理',
icon: <PaperClipOutlined />,
},
},
{
path: '/resourceManage/industryNews',
element: withLoadingComponent(<IndustryNewsView />),
meta: {
id: 30400,
title: '行业新闻',
icon: <ReadOutlined />,
},
},
{
path: '/resourceManage/tenderManage',
element: withLoadingComponent(<TenderManageView />),
meta: {
id: 30500,
title: '招标快讯',
icon: <CoffeeOutlined />,
},
},
{
path: '/resourceManage/tenderManage/detail',
element: withLoadingComponent(<TenderManageDetail />),
meta: {
id: 30500,
title: '招标快讯详情',
icon: <CoffeeOutlined />,
hidden: true,
},
},
{
path: '/resourceManage/tenderManage/feedback',
element: withLoadingComponent(<TenderManageFeedback />),
meta: {
id: 30500,
title: '用户反馈',
icon: <CoffeeOutlined />,
hidden: true,
},
},
{
path: '/resourceManage/businessCaseManage',
element: withLoadingComponent(<BusinessCaseManage />),
meta: {
id: 30600,
title: '业务案例',
icon: <AliwangwangOutlined />,
},
},
],
},
{
path: '/forumManage',
element: <LayoutView />,
errorElement: <ErrorPage />,
meta: {
id: 40000,
icon: <MessageOutlined />,
title: '论坛管理',
},
children: [
{
path: '/forumManage/dynamicList',
element: withLoadingComponent(<DynamicListView />),
meta: {
id: 40100,
title: '动态列表',
icon: <ThunderboltOutlined />,
},
},
],
},
{
path: '/orderManage', path: '/orderManage',
element: <LayoutView />, element: <LayoutView />,
errorElement: <ErrorPage />, errorElement: <ErrorPage />,
...@@ -472,47 +660,6 @@ export const routerList: Array<RouteObjectType> = [ ...@@ -472,47 +660,6 @@ export const routerList: Array<RouteObjectType> = [
}, },
], ],
}, },
{
path: '/customManage',
element: <LayoutView />,
errorElement: <ErrorPage />,
meta: {
id: 22000,
icon: <TeamOutlined />,
title: '客户管理',
},
children: [
{
path: '/customManage/customList',
element: withLoadingComponent(<CustomListView />),
meta: {
id: 26100,
title: '客户列表',
icon: <SolutionOutlined />,
},
},
{
path: '/customManage/customMoney',
element: withLoadingComponent(<CustomMoneyView />),
meta: {
id: 26200,
title: '现金管理',
icon: <RedEnvelopeOutlined />,
hidden: true,
},
},
{
path: '/customManage/customMoney/detail',
element: withLoadingComponent(<CustomMoneyDetail />),
meta: {
id: 26200,
title: '现金变更',
icon: <RedEnvelopeOutlined />,
hidden: true,
},
},
],
},
// { // {
// path: '/pointManage', // path: '/pointManage',
// element: <LayoutView />, // element: <LayoutView />,
...@@ -681,37 +828,6 @@ export const routerList: Array<RouteObjectType> = [ ...@@ -681,37 +828,6 @@ export const routerList: Array<RouteObjectType> = [
// ], // ],
// }, // },
{ {
path: '/resourceManage',
element: <LayoutView />,
errorElement: <ErrorPage />,
meta: {
id: 30000,
icon: <DribbbleOutlined />,
title: '资源管理',
},
children: [
{
path: '/resourceManage/materielManage',
element: withLoadingComponent(<MaterielManageView />),
meta: {
id: 30100,
title: '宣传管理',
icon: <SketchOutlined />,
},
},
{
path: '/resourceManage/materielManage/detail',
element: withLoadingComponent(<MaterielManageDetail />),
meta: {
id: 30100,
title: '宣传管理详情',
icon: <SketchOutlined />,
hidden: true,
},
},
],
},
{
path: '/systemManage', path: '/systemManage',
element: <LayoutView />, element: <LayoutView />,
errorElement: <ErrorPage />, errorElement: <ErrorPage />,
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论