中泽后台管理前端
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

carModels.tsx 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  1. import React,{Ref,useEffect,useState,useRef } from 'react';
  2. import {Button,Tree,Tabs,Table,Modal,Space,Form, Input,TreeSelect,Select,Upload, message,Popconfirm,Tooltip } from 'antd'
  3. import { PlusOutlined,LoadingOutlined,InfoCircleOutlined } from '@ant-design/icons';
  4. import { upload } from '@/services/news/news';
  5. import { FormattedMessage,useIntl } from 'umi';
  6. import { getCarList,editProductTree,getDeleteTree,pushProducts, } from '@/services/product';
  7. import '../index.less';
  8. import { trim } from 'lodash';
  9. const { Option } = Select;
  10. const { TextArea } = Input;
  11. const CarModelsTable: React.FC<{id:any,upTree:any,treeDataAll:any}> = (prop:any) => {
  12. let intl = useIntl()
  13. const [listData, setListData] = useState([]); //列表数据
  14. const [isModalOpen, setIsModalOpen] = useState(false); //弹框
  15. const [modalTitle, setModalTitle] = useState(true); //弹框标题
  16. const [form] = Form.useForm();
  17. // const [nodes, setNodes] = useState<string>();
  18. const [loading, setLoading] = useState(false);
  19. const [imgPc, setImgPc] = useState({id:undefined,url:''}); //pc图片
  20. const [imgM, setImgM] = useState({id:undefined,url:''}); //移动端图片
  21. const [htmlPath, setHtmlPath] = useState(1); //页面路径,为1成功,为2失败不能保存
  22. // 页面路径是否显示
  23. const [pagePathShow, setPagePathShow] = useState(true);
  24. //弹框确定
  25. const handleOk = () => {
  26. let dataNow=form.getFieldsValue();
  27. if(dataNow.htmlUrl==undefined||trim(dataNow.htmlUrl).length==0){
  28. setHtmlPath(3)
  29. }
  30. form.submit();
  31. };
  32. //弹框取消
  33. const handleCancel = () => {
  34. setIsModalOpen(false);
  35. };
  36. //删除数据
  37. const deleteCar = async (e:any) => {
  38. console.log('删除:',e);
  39. let res:any=await getDeleteTree(e.uuid);
  40. if(res.code==200){
  41. getListData();
  42. prop.upTree();
  43. message.success(res.msg);
  44. }else{
  45. message.error(res.msg)
  46. }
  47. };
  48. //修改数据
  49. const revise = (e:any) => {
  50. console.log('修改',e);
  51. form.setFieldsValue(e);
  52. setHtmlPath(1);
  53. // setNodes(e?.nodes);
  54. setImgPc({id:e?.pcImg,url:e?.pcImgUrl});
  55. // setImgM({id:e?.mImg,url:e?.mImgUrl});
  56. setIsModalOpen(true);
  57. setModalTitle(false);
  58. };
  59. //新增
  60. const addDom = ()=>{
  61. form.resetFields();
  62. form.setFieldsValue({
  63. carType: undefined,
  64. pText: undefined,
  65. title:undefined,
  66. sort:undefined,
  67. uuid:undefined,
  68. key:undefined,
  69. htmlUrl:undefined,
  70. });
  71. setHtmlPath(1);
  72. // setNodes(undefined);
  73. setImgPc({id:undefined,url:''});
  74. // setImgM({id:undefined,url:''});
  75. setIsModalOpen(true);
  76. setModalTitle(true);
  77. }
  78. //表单数据保存
  79. const formSend = ()=>{
  80. form.validateFields();
  81. let dataNow=form.getFieldsValue();
  82. if(pagePathShow)dataNow.htmlUrl=trim(dataNow.htmlUrl);
  83. dataNow={
  84. ...dataNow,
  85. // nodes,
  86. pcImg:imgPc.id?imgPc.id:'',
  87. // mImg:imgM.id?imgM.id:'',
  88. fatherId:prop.id,
  89. carType:'model'
  90. }
  91. if(pagePathShow&&htmlPath!=1){
  92. return
  93. }
  94. editProductTree(dataNow).then((res:any)=>{
  95. if(res.code == 200){
  96. getListData();
  97. prop.upTree();
  98. setIsModalOpen(false);
  99. message.success(res.msg);
  100. }else{
  101. message.error(res.msg);
  102. }
  103. });
  104. }
  105. //树形选择
  106. const onChangeTreeSelect = (newValue: string) => {
  107. console.log(newValue,'newValue');
  108. // setNodes(newValue);
  109. };
  110. //类型选择
  111. const onCarTypeChange = (value: string) => {
  112. form.setFieldsValue({ carType: value });
  113. };
  114. //图片上传
  115. const handleBeforeUpload = async (file: any,type:any) => {
  116. const formData = new FormData();
  117. formData.append('file', file, file.name);
  118. const res = await upload(formData);
  119. if (res?.data?.uuid) {
  120. if(type == 'pc'){
  121. setImgPc({id:res.data.uuid,url:res.data.url})
  122. }else{
  123. setImgM({id:res.data.uuid,url:res.data.url})
  124. }
  125. }
  126. return false;
  127. };
  128. //图片删除
  129. const imgDele = (value: string) => {
  130. if(value == 'pc'){
  131. setImgPc({id:undefined,url:''})
  132. }else{
  133. setImgM({id:undefined,url:''})
  134. }
  135. };
  136. //表格列设置
  137. const columns: any = [
  138. {
  139. title: intl.formatMessage({id:'public.title'}),
  140. dataIndex: 'title',
  141. key: 'title',
  142. width:200,
  143. },
  144. {
  145. title: intl.formatMessage({id:'public.sort'}),
  146. dataIndex: 'sort',
  147. key: 'sort',
  148. align: 'center',
  149. width:100,
  150. },
  151. {
  152. title: intl.formatMessage({id:'public.desctiption'}),
  153. dataIndex: 'pText',
  154. key: 'pText',
  155. align: 'center',
  156. width:400,
  157. },
  158. {
  159. title: intl.formatMessage({id:'public.img'}),
  160. dataIndex: 'carImg',
  161. key: 'carImg',
  162. align: 'center',
  163. width:150,
  164. render: (text,record:any) => <img src={record?.pcImgUrl} style={{ height:'110px'}}/>,
  165. },
  166. {
  167. title: intl.formatMessage({id:'public.action'}),
  168. dataIndex: '',
  169. align: 'center',
  170. width:160,
  171. render: (text,record) => {
  172. return <Space size="middle"><Button type='text' onClick={()=>revise(record)}>{intl.formatMessage({id:'public.update'})}</Button><Button type='text' onClick={()=>deleteCar(record)}>{intl.formatMessage({id:'public.delete'})}</Button></Space>
  173. },
  174. },
  175. ];
  176. const getListData:any =()=>{
  177. if(prop.id=='')return;
  178. let showPage=true;
  179. prop.treeDataAll.map((e:any)=>{
  180. if(e.uuid =="9a99b2abf66e45269306c3c34bd64d8c"){
  181. if(e.children.filter((item:any)=>item.uuid==prop.id).length>0){
  182. showPage=false;
  183. }
  184. }
  185. });
  186. setPagePathShow(showPage);
  187. getCarList(prop.id).then((res)=>{
  188. if(res.code==200){
  189. if(res.rows.length>0){
  190. setListData(res.rows);
  191. }else{
  192. setListData([]);
  193. }
  194. }else{
  195. message.error(res.msg);
  196. }
  197. })
  198. }
  199. //发布静态化
  200. const pushStatusPage:any =()=>{
  201. if(prop.id==''){
  202. message.error('没有id');
  203. return;
  204. }
  205. pushProducts(prop.id).then((res:any)=>{
  206. if(res.code==200){
  207. message.success(res.msg)
  208. }else{
  209. message.error(res.msg);
  210. }
  211. })
  212. }
  213. useEffect(() => {
  214. getListData();
  215. }, [prop.id]);
  216. //路径校验
  217. const onPagePathChange=(val:any)=>{
  218. let str=trim(val.target.value);
  219. if(str.length==0||str==undefined||str==null){
  220. setHtmlPath(3)
  221. }else if(str.indexOf('?')!==-1||str.indexOf('*')!==-1||str.indexOf(':')!==-1||str.indexOf('"')!==-1||str.indexOf('<')!==-1||str.indexOf('>')!==-1||str.indexOf('|')!==-1||str.indexOf('\\')!==-1){
  222. setHtmlPath(2)
  223. }
  224. else{
  225. setHtmlPath(1)
  226. }
  227. }
  228. return (
  229. <div className='carRight'>
  230. <div className='carTitle'>
  231. {intl.formatMessage({id:'public.carTypeList'})}
  232. <Popconfirm title={intl.formatMessage({id:'public.ifConfirmPublish'})+'?'} onConfirm={pushStatusPage}>
  233. <Button className='btn' type="primary">{intl.formatMessage({id:'public.publishAll'})}</Button>
  234. </Popconfirm>
  235. <Button className='btn' type="primary" onClick={addDom}>{intl.formatMessage({id:'public.add'})}</Button>
  236. </div>
  237. <Table
  238. columns={columns}
  239. dataSource={listData}
  240. rowKey={(record:any)=>record?.uuid}
  241. />
  242. <Modal title={modalTitle?intl.formatMessage({id:'public.newCarTypeInfo'}):intl.formatMessage({id:'public.updateCarTypeInfo'})} className='carModal' open={isModalOpen} onOk={handleOk} onCancel={handleCancel} width={880}>
  243. <Form
  244. form={form}
  245. labelCol={{ flex: '160px' }}
  246. labelAlign="left"
  247. labelWrap
  248. wrapperCol={{ flex: 1 }}
  249. colon={false}
  250. style={{ maxWidth: 880 }}
  251. onFinish={formSend}
  252. >
  253. <Form.Item label="uuid" name="uuid" hidden>
  254. <Input />
  255. </Form.Item>
  256. <Form.Item label={intl.formatMessage({id:'public.carTypeName'})} name="title" rules={[{ required: true }]}>
  257. <Input />
  258. </Form.Item>
  259. {/* <Form.Item name="carType" label="类型" rules={[{ required: true }]}>
  260. <Select
  261. placeholder="请选择类型"
  262. onChange={onCarTypeChange}
  263. allowClear
  264. >
  265. <Option value="series">车系</Option>
  266. <Option value="overview">概览</Option>
  267. </Select>
  268. </Form.Item> */}
  269. <Form.Item label={intl.formatMessage({id:'public.sort'})} name="sort">
  270. <Input />
  271. </Form.Item>
  272. {/* <Form.Item label="关联节点" rules={[{ required: true }]}>
  273. <TreeSelect
  274. showSearch
  275. style={{ width: '100%' }}
  276. value={nodes}
  277. dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
  278. placeholder="请选择"
  279. allowClear
  280. treeDefaultExpandAll
  281. onChange={onChangeTreeSelect}
  282. treeData={prop.treeDataMy}
  283. fieldNames={{label:'title',value:'uuid'}}
  284. />
  285. </Form.Item> */}
  286. <Form.Item label={intl.formatMessage({id:'public.description'})} name="pText">
  287. <TextArea rows={4} />
  288. </Form.Item>
  289. <Form.Item label={intl.formatMessage({id:'public.keyword'})} name="key">
  290. <Input />
  291. </Form.Item>
  292. {pagePathShow&&
  293. <Form.Item label={intl.formatMessage({id:'public.pagePath'})} name="htmlUrl" rules={[{ required: true }]}
  294. validateStatus={(htmlPath==2||htmlPath==3)?"error":""} help={htmlPath==2?intl.formatMessage({id:'public.pagePathInfo'}):htmlPath==3?intl.formatMessage({id:'public.inputPlaceholder'})+intl.formatMessage({id:'public.pagePath'}):""}
  295. >
  296. <Input suffix={<Tooltip title={intl.formatMessage({id:'public.pagePathMess'})}>
  297. <InfoCircleOutlined style={{ color: 'rgba(0,0,0,.45)' }} />
  298. </Tooltip>} onChange={onPagePathChange} placeholder={intl.formatMessage({id:'public.inputPlaceholder'})+intl.formatMessage({id:'public.pagePath'})}/>
  299. </Form.Item>}
  300. <Form.Item label={intl.formatMessage({id:'public.img'})+'(PC)'} extra={intl.formatMessage({id:'public.pictureSize'})+':1280*720'}>
  301. {imgPc.id && <div className='showImg'><img src={imgPc.url} /></div>}
  302. <div className='uploadBtn'>
  303. <Upload
  304. beforeUpload={(e)=>handleBeforeUpload(e,'pc')}
  305. maxCount={1}
  306. showUploadList={false}
  307. accept={'.png, .jpg, .gif'}
  308. >
  309. <Button>{intl.formatMessage({id:'public.upload'})}</Button>
  310. </Upload>
  311. </div>
  312. <div className='uploadBtn'><Button onClick={()=>{imgDele('pc')}} >{intl.formatMessage({id:'public.delete'})}</Button></div>
  313. </Form.Item>
  314. {/* <Form.Item label="图片(移动)">
  315. {imgM.id && <div className='showImg'><img src={imgM.url} /></div>}
  316. <div className='uploadBtn'>
  317. <Upload
  318. beforeUpload={(e)=>handleBeforeUpload(e,'m')}
  319. maxCount={1}
  320. showUploadList={false}
  321. accept={'.png, .jpg, .gif'}
  322. >
  323. <Button>上传</Button>
  324. </Upload>
  325. </div>
  326. <div className='uploadBtn'><Button onClick={()=>{imgDele('m')}}>删除</Button></div>
  327. </Form.Item> */}
  328. </Form>
  329. </Modal>
  330. </div>
  331. );
  332. };
  333. export default CarModelsTable;