This commit is contained in:
parent
e446e46655
commit
ad3d83ec8c
|
|
@ -0,0 +1,242 @@
|
|||
import React, { useState, useCallback } from 'react';
|
||||
import './FeedbackModal.scss';
|
||||
import { createMemo } from '../../forums/api';
|
||||
import { message, Upload } from 'antd';
|
||||
import { httpUrl } from '../../forums/fetch';
|
||||
|
||||
// 导入图片资源
|
||||
import modalBg from '../../images/factory/feedback/modal-bg.webp';
|
||||
import iconClose from '../../images/factory/feedback/icon-close-new.webp';
|
||||
import iconRequired from '../../images/factory/feedback/icon-required-new.webp';
|
||||
|
||||
/**
|
||||
* 反馈中心-新增弹窗组件
|
||||
* @param {boolean} visible - 弹窗显示状态
|
||||
* @param {function} onClose - 关闭弹窗回调
|
||||
* @param {function} onSuccess - 提交成功回调
|
||||
*/
|
||||
function FeedbackModal({ visible, onClose, onSuccess }) {
|
||||
const [formData, setFormData] = useState({
|
||||
title: '',
|
||||
description: '',
|
||||
});
|
||||
const [fileList, setFileList] = useState([]);
|
||||
const [errors, setErrors] = useState({});
|
||||
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||
|
||||
// 处理输入变化
|
||||
const handleInputChange = useCallback((field, value) => {
|
||||
setFormData(prev => ({
|
||||
...prev,
|
||||
[field]: value,
|
||||
}));
|
||||
// 清除对应字段的错误
|
||||
if (errors[field]) {
|
||||
setErrors(prev => ({
|
||||
...prev,
|
||||
[field]: null,
|
||||
}));
|
||||
}
|
||||
}, [errors]);
|
||||
|
||||
// 文件上传前校验
|
||||
const beforeUpload = useCallback((file) => {
|
||||
const isLt100M = file.size / 1024 / 1024 < 100;
|
||||
if (!isLt100M) {
|
||||
message.error('文件大小必须小于100MB!');
|
||||
}
|
||||
return isLt100M;
|
||||
}, []);
|
||||
|
||||
// 文件列表变化处理
|
||||
const handleFileChange = useCallback((info) => {
|
||||
if (info.file.status === 'uploading' || info.file.status === 'done' || info.file.status === 'removed') {
|
||||
const newFileList = info.fileList || [];
|
||||
setFileList(newFileList);
|
||||
}
|
||||
}, []);
|
||||
|
||||
// 验证表单
|
||||
const validateForm = useCallback(() => {
|
||||
const newErrors = {};
|
||||
if (!formData.title.trim()) {
|
||||
newErrors.title = '请输入标题';
|
||||
}
|
||||
if (!formData.description.trim()) {
|
||||
newErrors.description = '请输入问题描述';
|
||||
}
|
||||
setErrors(newErrors);
|
||||
return Object.keys(newErrors).length === 0;
|
||||
}, [formData]);
|
||||
|
||||
// 处理提交
|
||||
const handleSubmit = useCallback(async () => {
|
||||
if (!validateForm()) return;
|
||||
|
||||
setIsSubmitting(true);
|
||||
try {
|
||||
// 获取附件ID数组
|
||||
const attachmentIdArray = fileList.map(item => {
|
||||
// 优先使用 response.id(新上传的文件),其次是 item.id(已存在的文件)
|
||||
return item.response && item.response.id ? item.response.id : item.id;
|
||||
}).filter(id => id); // 过滤掉undefined/null
|
||||
|
||||
// 构建接口参数,主题板块默认填11
|
||||
const params = {
|
||||
forum_id: 11,
|
||||
children_forum_id: '0',
|
||||
attachments: attachmentIdArray.length > 0 ? attachmentIdArray : undefined,
|
||||
memo: {
|
||||
subject: formData.title,
|
||||
content: formData.description,
|
||||
is_original: 1,
|
||||
},
|
||||
};
|
||||
|
||||
const ret = await createMemo(params);
|
||||
|
||||
if (ret.status === 1) {
|
||||
message.success(ret.message || '提交成功');
|
||||
// 提交成功后重置表单并关闭
|
||||
setFormData({ title: '', description: '' });
|
||||
setFileList([]);
|
||||
onClose?.();
|
||||
onSuccess?.(ret);
|
||||
} else {
|
||||
message.error(ret.message || '提交失败');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('提交反馈失败:', error);
|
||||
message.error('提交失败,请稍后重试');
|
||||
} finally {
|
||||
setIsSubmitting(false);
|
||||
}
|
||||
}, [formData, fileList, validateForm, onClose, onSuccess]);
|
||||
|
||||
// 处理取消
|
||||
const handleCancel = useCallback(() => {
|
||||
setFormData({ title: '', description: '' });
|
||||
setFileList([]);
|
||||
setErrors({});
|
||||
onClose?.();
|
||||
}, [onClose]);
|
||||
|
||||
// 点击蒙层关闭
|
||||
const handleMaskClick = useCallback((e) => {
|
||||
if (e.target === e.currentTarget) {
|
||||
handleCancel();
|
||||
}
|
||||
}, [handleCancel]);
|
||||
|
||||
if (!visible) return null;
|
||||
|
||||
return (
|
||||
<div className="feedback-modal-mask" onClick={handleMaskClick}>
|
||||
<div className="feedback-modal">
|
||||
{/* 弹窗背景 */}
|
||||
<div className="feedback-modal-bg">
|
||||
<img src={modalBg} alt="" />
|
||||
</div>
|
||||
|
||||
{/* 弹窗头部 */}
|
||||
<div className="feedback-modal-header">
|
||||
<h2 className="feedback-modal-title">意见反馈</h2>
|
||||
<button
|
||||
className="feedback-modal-close"
|
||||
onClick={handleCancel}
|
||||
aria-label="关闭"
|
||||
>
|
||||
<img src={iconClose} alt="关闭" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* 弹窗内容 */}
|
||||
<div className="feedback-modal-content">
|
||||
{/* 标题输入 */}
|
||||
<div className="feedback-form-item">
|
||||
<div className="feedback-form-label">
|
||||
<img src={iconRequired} alt="必填" className="required-icon" />
|
||||
<span>标题</span>
|
||||
</div>
|
||||
<div className={`feedback-form-input-wrapper ${errors.title ? 'error' : ''}`}>
|
||||
<input
|
||||
type="text"
|
||||
className="feedback-form-input"
|
||||
placeholder="提升模型API调用接口的兼容性-参数错误"
|
||||
value={formData.title}
|
||||
onChange={(e) => handleInputChange('title', e.target.value)}
|
||||
maxLength={500}
|
||||
/>
|
||||
</div>
|
||||
{errors.title && <span className="feedback-form-error">{errors.title}</span>}
|
||||
</div>
|
||||
|
||||
{/* 问题描述输入 */}
|
||||
<div className="feedback-form-item">
|
||||
<div className="feedback-form-label">
|
||||
<img src={iconRequired} alt="必填" className="required-icon" />
|
||||
<span>问题描述</span>
|
||||
</div>
|
||||
<div className={`feedback-form-textarea-wrapper ${errors.description ? 'error' : ''}`}>
|
||||
<textarea
|
||||
className="feedback-form-textarea"
|
||||
placeholder="请输入问题详情"
|
||||
value={formData.description}
|
||||
onChange={(e) => handleInputChange('description', e.target.value)}
|
||||
rows={4}
|
||||
maxLength={500}
|
||||
/>
|
||||
</div>
|
||||
{errors.description && <span className="feedback-form-error">{errors.description}</span>}
|
||||
</div>
|
||||
|
||||
{/* 附件上传 */}
|
||||
<div className="feedback-form-item">
|
||||
<div className="feedback-form-label">
|
||||
<span>附件</span>
|
||||
</div>
|
||||
<div className="feedback-form-upload">
|
||||
<Upload.Dragger
|
||||
className="feedback-upload-dragger"
|
||||
action={`${httpUrl}/api/attachments.json`}
|
||||
beforeUpload={beforeUpload}
|
||||
onChange={handleFileChange}
|
||||
fileList={fileList}
|
||||
multiple={true}
|
||||
>
|
||||
<p className="ant-upload-drag-icon">
|
||||
<svg width="48" height="48" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M12 2L12 14M12 2L8 6M12 2L16 6" stroke="#4953e6" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
|
||||
<path d="M2 17L2 19C2 20.1046 2.89543 21 4 21L20 21C21.1046 21 22 20.1046 22 19L22 17" stroke="#4953e6" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
|
||||
</svg>
|
||||
</p>
|
||||
<p className="feedback-upload-text">点击或拖拽文件到此区域上传</p>
|
||||
<p className="feedback-upload-hint">文件大小不超过 100MB</p>
|
||||
</Upload.Dragger>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 弹窗底部 */}
|
||||
<div className="feedback-modal-footer">
|
||||
<button
|
||||
className="feedback-btn feedback-btn-cancel"
|
||||
onClick={handleCancel}
|
||||
disabled={isSubmitting}
|
||||
>
|
||||
取消
|
||||
</button>
|
||||
<button
|
||||
className="feedback-btn feedback-btn-submit"
|
||||
onClick={handleSubmit}
|
||||
disabled={isSubmitting}
|
||||
>
|
||||
{isSubmitting ? '提交中...' : '提交'}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default FeedbackModal;
|
||||
|
|
@ -0,0 +1,472 @@
|
|||
// 反馈中心-新增弹窗样式
|
||||
// 遵循 factory 目录下的 SCSS 规范
|
||||
|
||||
// 颜色变量
|
||||
$primary-color: #4953e6;
|
||||
$primary-hover: #3a42d1;
|
||||
$text-primary: #091221;
|
||||
$text-secondary: #223452;
|
||||
$text-muted: #9494b4;
|
||||
$border-color: #cfd5e8;
|
||||
$border-focus: #4953e6;
|
||||
$bg-white: #ffffff;
|
||||
$bg-mask: rgba(0, 0, 0, 0.4);
|
||||
$error-color: #ff4d4f;
|
||||
|
||||
// 尺寸变量
|
||||
$modal-width: 900px;
|
||||
$modal-height: 551px;
|
||||
$content-width: 860px;
|
||||
$content-height: 446px;
|
||||
$border-radius-modal: 30px;
|
||||
$border-radius-content: 30px;
|
||||
$border-radius-input: 8px;
|
||||
$border-radius-btn: 9px;
|
||||
|
||||
// 动画变量
|
||||
$transition-duration: 0.3s;
|
||||
|
||||
// 蒙层
|
||||
.feedback-modal-mask {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: $bg-mask;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 1000;
|
||||
animation: fadeIn $transition-duration ease;
|
||||
}
|
||||
|
||||
// 弹窗容器
|
||||
.feedback-modal {
|
||||
position: relative;
|
||||
width: $modal-width;
|
||||
height: $modal-height;
|
||||
border-radius: $border-radius-modal;
|
||||
overflow: hidden;
|
||||
animation: slideUp $transition-duration ease;
|
||||
}
|
||||
|
||||
// 弹窗背景
|
||||
.feedback-modal-bg {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 0;
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
// 添加渐变叠加层以增强文字可读性
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: linear-gradient(
|
||||
180deg,
|
||||
rgba(73, 83, 230, 0.1) 0%,
|
||||
rgba(73, 83, 230, 0.05) 100%
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// 弹窗头部
|
||||
.feedback-modal-header {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 24px 30px;
|
||||
height: 81px;
|
||||
}
|
||||
|
||||
// 弹窗标题
|
||||
.feedback-modal-title {
|
||||
font-family: 'Alibaba PuHuiTi', 'PingFang SC', sans-serif;
|
||||
font-size: 20px;
|
||||
font-weight: 500;
|
||||
color: $bg-white;
|
||||
text-align: center;
|
||||
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
// 关闭按钮
|
||||
.feedback-modal-close {
|
||||
position: absolute;
|
||||
right: 30px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
background: transparent;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: transform $transition-duration ease;
|
||||
|
||||
img {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
filter: brightness(0) invert(1);
|
||||
}
|
||||
|
||||
&:hover {
|
||||
transform: translateY(-50%) rotate(90deg);
|
||||
}
|
||||
}
|
||||
|
||||
// 弹窗内容区域
|
||||
.feedback-modal-content {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
width: $content-width;
|
||||
height: $content-height;
|
||||
margin: 0 auto;
|
||||
background-color: $bg-white;
|
||||
border-radius: $border-radius-content;
|
||||
padding: 40px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 24px;
|
||||
}
|
||||
|
||||
// 表单项
|
||||
.feedback-form-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
// 表单标签
|
||||
.feedback-form-label {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
font-family: 'Alibaba PuHuiTi', 'PingFang SC', sans-serif;
|
||||
font-size: 14px;
|
||||
color: $text-primary;
|
||||
line-height: 1.5;
|
||||
|
||||
.required-icon {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
// 输入框容器
|
||||
.feedback-form-input-wrapper,
|
||||
.feedback-form-textarea-wrapper {
|
||||
width: 100%;
|
||||
border: 1px solid $border-color;
|
||||
border-radius: $border-radius-input;
|
||||
transition: border-color $transition-duration ease, box-shadow $transition-duration ease;
|
||||
|
||||
&:hover {
|
||||
border-color: darken($border-color, 10%);
|
||||
}
|
||||
|
||||
&:focus-within {
|
||||
border-color: $border-focus;
|
||||
box-shadow: 0 0 0 2px rgba($border-focus, 0.1);
|
||||
}
|
||||
|
||||
&.error {
|
||||
border-color: $error-color;
|
||||
box-shadow: 0 0 0 2px rgba($error-color, 0.1);
|
||||
}
|
||||
}
|
||||
|
||||
// 输入框
|
||||
.feedback-form-input {
|
||||
width: 100%;
|
||||
height: 36px;
|
||||
padding: 8px 16px;
|
||||
border: none;
|
||||
background: transparent;
|
||||
font-family: 'Alibaba PuHuiTi', 'PingFang SC', sans-serif;
|
||||
font-size: 14px;
|
||||
color: $text-primary;
|
||||
line-height: 1.5;
|
||||
outline: none;
|
||||
|
||||
&::placeholder {
|
||||
color: $text-muted;
|
||||
}
|
||||
}
|
||||
|
||||
// 文本域
|
||||
.feedback-form-textarea {
|
||||
width: 100%;
|
||||
min-height: 80px;
|
||||
padding: 12px 16px;
|
||||
border: none;
|
||||
background: transparent;
|
||||
font-family: 'Alibaba PuHuiTi', 'PingFang SC', sans-serif;
|
||||
font-size: 14px;
|
||||
color: $text-primary;
|
||||
line-height: 1.6;
|
||||
outline: none;
|
||||
resize: vertical;
|
||||
|
||||
&::placeholder {
|
||||
color: $text-muted;
|
||||
}
|
||||
}
|
||||
|
||||
// 错误提示
|
||||
.feedback-form-error {
|
||||
font-family: 'Alibaba PuHuiTi', 'PingFang SC', sans-serif;
|
||||
font-size: 12px;
|
||||
color: $error-color;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
// 上传区域
|
||||
.feedback-form-upload {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
// Ant Design Upload.Dragger 样式覆盖
|
||||
.feedback-upload-dragger {
|
||||
.ant-upload {
|
||||
padding: 20px !important;
|
||||
background: #fafafa !important;
|
||||
border: 1px dashed $border-color !important;
|
||||
border-radius: 8px !important;
|
||||
transition: all $transition-duration ease;
|
||||
|
||||
&:hover {
|
||||
border-color: $primary-color !important;
|
||||
background: rgba($primary-color, 0.02) !important;
|
||||
}
|
||||
|
||||
&.ant-upload-drag-hover {
|
||||
border-color: $primary-color !important;
|
||||
background: rgba($primary-color, 0.05) !important;
|
||||
}
|
||||
}
|
||||
|
||||
.ant-upload-drag-icon {
|
||||
margin-bottom: 12px;
|
||||
|
||||
svg {
|
||||
display: block;
|
||||
margin: 0 auto;
|
||||
}
|
||||
}
|
||||
|
||||
.feedback-upload-text {
|
||||
font-family: 'Alibaba PuHuiTi', 'PingFang SC', sans-serif;
|
||||
font-size: 14px;
|
||||
color: $text-primary;
|
||||
line-height: 1.5;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.feedback-upload-hint {
|
||||
font-family: 'Alibaba PuHuiTi', 'PingFang SC', sans-serif;
|
||||
font-size: 12px;
|
||||
color: $text-muted;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
// 文件列表样式
|
||||
.ant-upload-list {
|
||||
margin-top: 12px;
|
||||
|
||||
.ant-upload-list-item {
|
||||
font-family: 'Alibaba PuHuiTi', 'PingFang SC', sans-serif;
|
||||
font-size: 13px;
|
||||
|
||||
&:hover {
|
||||
background-color: rgba($primary-color, 0.02);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 隐藏文件输入
|
||||
.feedback-form-file-input {
|
||||
display: none;
|
||||
}
|
||||
|
||||
// 上传按钮(旧版,保留兼容性)
|
||||
.feedback-form-upload-btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
padding: 6px 16px;
|
||||
border: 1px solid $primary-color;
|
||||
border-radius: 4px;
|
||||
background-color: transparent;
|
||||
cursor: pointer;
|
||||
transition: all $transition-duration ease;
|
||||
|
||||
.upload-icon {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
color: $primary-color;
|
||||
}
|
||||
|
||||
span {
|
||||
font-family: 'Alibaba PuHuiTi', 'PingFang SC', sans-serif;
|
||||
font-size: 14px;
|
||||
color: $primary-color;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: rgba($primary-color, 0.05);
|
||||
}
|
||||
}
|
||||
|
||||
// 文件名(旧版,保留兼容性)
|
||||
.feedback-form-file-name {
|
||||
font-family: 'Alibaba PuHuiTi', 'PingFang SC', sans-serif;
|
||||
font-size: 13px;
|
||||
color: $text-secondary;
|
||||
max-width: 200px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
// 弹窗底部
|
||||
.feedback-modal-footer {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 16px;
|
||||
padding: 20px 0;
|
||||
}
|
||||
|
||||
// 按钮基础样式
|
||||
.feedback-btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-width: 101px;
|
||||
height: 36px;
|
||||
padding: 0 24px;
|
||||
border-radius: $border-radius-btn;
|
||||
font-family: 'Alibaba PuHuiTi', 'PingFang SC', sans-serif;
|
||||
font-size: 14px;
|
||||
line-height: 1.4;
|
||||
cursor: pointer;
|
||||
transition: all $transition-duration ease;
|
||||
border: none;
|
||||
|
||||
&:disabled {
|
||||
opacity: 0.6;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
|
||||
// 取消按钮
|
||||
.feedback-btn-cancel {
|
||||
background-color: transparent;
|
||||
border: 1px solid $text-primary;
|
||||
color: $text-primary;
|
||||
|
||||
&:hover:not(:disabled) {
|
||||
background-color: rgba($text-primary, 0.05);
|
||||
}
|
||||
}
|
||||
|
||||
// 提交按钮
|
||||
.feedback-btn-submit {
|
||||
background-color: $text-primary;
|
||||
color: $bg-white;
|
||||
|
||||
&:hover:not(:disabled) {
|
||||
background-color: lighten($text-primary, 10%);
|
||||
}
|
||||
}
|
||||
|
||||
// 动画定义
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes slideUp {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(30px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
// 响应式适配
|
||||
@media screen and (max-width: 992px) {
|
||||
.feedback-modal {
|
||||
width: 90vw;
|
||||
max-width: 600px;
|
||||
height: auto;
|
||||
max-height: 90vh;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.feedback-modal-content {
|
||||
width: auto;
|
||||
height: auto;
|
||||
margin: 0 20px;
|
||||
padding: 24px;
|
||||
}
|
||||
|
||||
.feedback-modal-header {
|
||||
padding: 20px 24px;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.feedback-modal-close {
|
||||
right: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 576px) {
|
||||
.feedback-modal-content {
|
||||
padding: 20px;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.feedback-modal-footer {
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
padding: 16px 20px;
|
||||
|
||||
.feedback-btn {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.feedback-form-upload {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,7 @@ import React, { useEffect, useState, useRef } from 'react';
|
|||
import './index.scss';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { TPMIndexHOC } from "../../modules/tpm/TPMIndexHOC";
|
||||
import FeedbackModal from './FeedbackModal';
|
||||
|
||||
// 导入图片资源
|
||||
import headerBg from '../../images/factory/feedback/header-bg.webp';
|
||||
|
|
@ -134,6 +135,7 @@ const mockAllFeedback = [
|
|||
function FeedbackCenter(props) {
|
||||
const [hotFeedback, setHotFeedback] = useState(mockHotFeedback);
|
||||
const [allFeedback, setAllFeedback] = useState(mockAllFeedback);
|
||||
const [modalVisible, setModalVisible] = useState(false);
|
||||
const contentRef = useRef(null);
|
||||
const [isVisible, setIsVisible] = useState(false);
|
||||
|
||||
|
|
@ -160,15 +162,28 @@ function FeedbackCenter(props) {
|
|||
};
|
||||
}, []);
|
||||
|
||||
// 打开弹窗
|
||||
const handleFeedbackClick = () => {
|
||||
const { user, history } = props;
|
||||
const { user } = props;
|
||||
if (user && user.login) {
|
||||
history.push('/sf/feedback/new');
|
||||
setModalVisible(true);
|
||||
} else {
|
||||
history.push(`/login?go_page=/sf/feedback/new`);
|
||||
const { history } = props;
|
||||
history.push(`/login?go_page=/sf/feedback`);
|
||||
}
|
||||
};
|
||||
|
||||
// 关闭弹窗
|
||||
const handleModalClose = () => {
|
||||
setModalVisible(false);
|
||||
};
|
||||
|
||||
// 提交成功回调
|
||||
const handleModalSuccess = (ret) => {
|
||||
// 提交成功后可以刷新列表或做其他操作
|
||||
console.log('反馈提交成功:', ret);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="feedback-center" ref={contentRef}>
|
||||
{/* 顶部横幅区域 */}
|
||||
|
|
@ -301,6 +316,13 @@ function FeedbackCenter(props) {
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 反馈弹窗 */}
|
||||
<FeedbackModal
|
||||
visible={modalVisible}
|
||||
onClose={handleModalClose}
|
||||
onSuccess={handleModalSuccess}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 1.7 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.7 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 598 B |
Binary file not shown.
|
After Width: | Height: | Size: 598 B |
Binary file not shown.
|
After Width: | Height: | Size: 25 KiB |
Loading…
Reference in New Issue