add.jsx 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476
  1. import React,{Component} from 'react';
  2. import SpinContainer from "../../../SpinContainer";
  3. import {Button, Form, Icon, Input, message, Modal, Select, Upload} from "antd";
  4. import {beforeUploadFile,splitUrl} from "@/tools.js";
  5. import Editors from "@/richTextEditors";
  6. import $ from "jquery/src/ajax";
  7. const FormItem = Form.Item;
  8. //上传图片组件
  9. const PicturesWall = React.createClass({
  10. getInitialState() {
  11. return {
  12. previewVisible: false,
  13. previewImage: "",
  14. fileList: this.props.pictureUrl,
  15. type:''
  16. };
  17. },
  18. getDefaultProps() {
  19. return {
  20. changeClick: this.modifyChange
  21. };
  22. },
  23. handleCancel() {
  24. this.setState({ previewVisible: false });
  25. },
  26. handlePreview(file) {
  27. let type = '';
  28. if(file.type){
  29. let str = file.type;
  30. let index = str.indexOf("/");
  31. type =str.substring(0,index) === 'video' ? 1 : str.substring(0,index) === 'audio' ? 2 : 0;
  32. }else{
  33. // let str = file.url || file.thumbUrl;
  34. // let index = str.lastIndexOf(".");
  35. // type = str.substring(index+1);
  36. type = this.props.type;
  37. }
  38. this.setState({
  39. type,
  40. previewImage: file.url || file.thumbUrl,
  41. previewVisible: true
  42. });
  43. },
  44. handleChange(info) {
  45. let fileList = info.fileList;
  46. this.setState({ fileList });
  47. this.props.fileList(fileList);
  48. },
  49. componentWillReceiveProps(nextProps) {
  50. this.state.fileList = nextProps.pictureUrl;
  51. },
  52. render() {
  53. const { previewVisible, previewImage, fileList } = this.state;
  54. const uploadButton = (
  55. <div>
  56. <Icon type="plus" />
  57. <div className="ant-upload-text">点击上传</div>
  58. </div>
  59. );
  60. return (
  61. <div style={{ display: "inline-block" }}>
  62. <Upload
  63. accept={
  64. this.props.type === 0 ? "image/*" :
  65. this.props.type === 1 ?
  66. 'video/mp4,video/rmvb,video/mkv,video/avi' :
  67. this.props.type === 2 ?
  68. "audio/mp3" : '*'}
  69. beforeUpload={beforeUploadFile}
  70. action={globalConfig.context + "/api/admin/project/uploadFile"}
  71. data={{ sign: "purchase_picture" }}
  72. listType="picture-card"
  73. fileList={fileList}
  74. onPreview={this.handlePreview}
  75. onChange={this.handleChange}
  76. >
  77. {fileList && fileList.length >= 1 ? null : uploadButton}
  78. </Upload>
  79. <Modal
  80. maskClosable={false}
  81. visible={previewVisible}
  82. footer={null}
  83. onCancel={this.handleCancel}
  84. >
  85. {
  86. this.state.type=== 0 ?
  87. <img alt="" style={{ width: "100%" }} src={previewImage} /> :
  88. this.state.type=== 1 ?
  89. <video style={{width:'100%'}} controls="controls" autoPlay="" name="media">
  90. <source src={previewImage} type="video/mp4"/>
  91. </video>:
  92. this.state.type=== 2 ?
  93. <audio src={previewImage} controls="controls">Your browser does not support the audio element.</audio>: ''
  94. }
  95. </Modal>
  96. </div>
  97. );
  98. }
  99. });
  100. class Add extends Component{
  101. constructor(props) {
  102. super(props);
  103. this.state={
  104. loading: false,
  105. projectType: '',
  106. sort:'',
  107. summary:'',
  108. name:'',
  109. pictureVideoUrl: '',
  110. pictureImgUrl: '',
  111. content: '',
  112. commodityContent: '',
  113. amount: '',
  114. projectList: [],
  115. host: 0,
  116. commodityType: '',
  117. }
  118. this.getOrgCodeUrl = this.getOrgCodeUrl.bind(this);
  119. this.getVideoOrgCodeUrl = this.getVideoOrgCodeUrl.bind(this);
  120. this.onOk = this.onOk.bind(this);
  121. this.getProjectList = this.getProjectList.bind(this);
  122. }
  123. componentDidMount() {
  124. this.getProjectList();
  125. }
  126. getOrgCodeUrl(e) {
  127. this.setState({ pictureImgUrl: e });
  128. }
  129. getVideoOrgCodeUrl(e) {
  130. if(e.length === 0){
  131. this.setState({
  132. pictureVideoUrl: '',
  133. commodityType: '',
  134. });
  135. }else{
  136. let str = e[0].type;
  137. let index = str.indexOf("/");
  138. let type =str.substring(0,index);
  139. this.setState({
  140. pictureVideoUrl: e,
  141. commodityType: type === 'video' ? 1 : type === 'audio' ? 2 : 0,
  142. });
  143. }
  144. }
  145. onOk(releaseStatus = 0){
  146. if(!this.state.name){
  147. message.warning('请输入产品名称');
  148. return false;
  149. }
  150. if(isNaN(parseInt(this.state.projectType))){
  151. message.warning('请输入产品分类');
  152. return false;
  153. }
  154. if(isNaN(parseInt(this.state.amount))){
  155. message.warning('请输入正确的金额');
  156. return false;
  157. }
  158. // if(this.state.pictureVideoUrl.length === 0){
  159. // message.warning('请上传视频/音频');
  160. // return false;
  161. // }
  162. if(this.state.pictureImgUrl.length === 0){
  163. message.warning('请上传略缩图');
  164. return false;
  165. }
  166. if(!this.state.commodityContent){
  167. message.warning('请输入未购买简介');
  168. return false;
  169. }
  170. if(!this.state.content){
  171. message.warning('请输入已购买简介');
  172. return false;
  173. }
  174. this.setState({
  175. loading: true
  176. });
  177. let url = this.props.id ? "/api/admin/project/update" : "/api/admin/project/add"
  178. $.ajax({
  179. method: "post",
  180. dataType: "json",
  181. crossDomain: false,
  182. url: globalConfig.context + url,
  183. data: {
  184. name: this.state.name || undefined,
  185. sort:this.state.sort || undefined,
  186. summary:this.state.summary || undefined,
  187. content: this.state.content || undefined,
  188. commodityContent: this.state.commodityContent || undefined,
  189. id: this.props.id || undefined,
  190. type: this.state.projectType,
  191. amount: !isNaN(parseInt(this.state.amount)) ? this.state.amount : undefined,
  192. commodityUrl: this.state.pictureVideoUrl ? this.state.pictureVideoUrl[0].response.data : '',
  193. commodityType: this.state.commodityType,
  194. thumbnailUrl: this.state.pictureImgUrl[0].response.data || undefined,
  195. host: this.state.host,
  196. releaseStatus,
  197. },
  198. success: function(data) {
  199. if (data.error && data.error.length) {
  200. message.warning(data.error[0].message);
  201. } else {
  202. message.success(this.state.id ? '修改成功' : '添加成功');
  203. this.props.onOk();
  204. }
  205. }.bind(this)
  206. }).always(
  207. function() {
  208. this.setState({
  209. loading: false
  210. });
  211. }.bind(this)
  212. );
  213. }
  214. getProjectList() {
  215. this.setState({
  216. loading: true
  217. });
  218. $.ajax({
  219. method: "get",
  220. dataType: "json",
  221. crossDomain: false,
  222. url: globalConfig.context + "/open/projectTypeList",
  223. data: {}
  224. }).done((data1) => {
  225. if (data1.error.length !== 0) {
  226. message.warning(data1.error[0].message);
  227. } else {
  228. this.setState({
  229. projectList: data1.data,
  230. },()=>{
  231. if(this.props.infor){
  232. this.setState({
  233. name: this.props.infor.name,
  234. sort:this.props.infor.sort,
  235. summary:this.props.infor.summary,
  236. content: this.props.infor.content,
  237. commodityContent: this.props.infor.commodityContent,
  238. projectType: this.props.infor.type,
  239. amount: this.props.infor.amount,
  240. pictureVideoUrl: this.props.infor.commodityUrl ? splitUrl(this.props.infor.commodityUrl, ',', globalConfig.avatarHost + '/upload') : '',
  241. pictureImgUrl: this.props.infor.thumbnailUrl ? splitUrl(this.props.infor.thumbnailUrl, ',', globalConfig.avatarHost + '/upload') : [],
  242. host: this.props.infor.host,
  243. commodityType:this.props.infor.commodityType
  244. })
  245. }
  246. });
  247. }
  248. }).always(function () {
  249. this.setState({
  250. loading: false
  251. });
  252. }.bind(this))
  253. }
  254. render() {
  255. return (
  256. <Modal
  257. className="customeDetails"
  258. title={this.props.id ? "修改产品" : "添加产品"}
  259. okText={"保存"}
  260. width="1050"
  261. visible={this.props.visible}
  262. onCancel={this.props.onCancel}
  263. footer={false}
  264. >
  265. <Form
  266. layout="horizontal"
  267. id="demand-form"
  268. >
  269. <SpinContainer spinning={this.state.loading}>
  270. <div className="clearfix">
  271. <FormItem
  272. className="half-item"
  273. labelCol={{ span: 8 }}
  274. wrapperCol={{ span: 12 }}
  275. label="产品名称"
  276. >
  277. <Input
  278. placeholder="请输入产品名称"
  279. value={this.state.name}
  280. onChange={(e) => {
  281. this.setState({ name: e.target.value });
  282. }}
  283. />
  284. </FormItem>
  285. <FormItem
  286. className="half-item"
  287. labelCol={{ span: 8 }}
  288. wrapperCol={{ span: 12 }}
  289. label="产品分类"
  290. >
  291. <Select
  292. value={this.state.projectType}
  293. placeholder="请选择产品分类"
  294. onChange={e => {
  295. this.setState({
  296. projectType: e
  297. });
  298. }}
  299. >
  300. {
  301. this.state.projectList.map((v,k)=>(
  302. <Option key={k} value={v.id}>{v.name}</Option>
  303. ))
  304. }
  305. </Select>
  306. </FormItem>
  307. <FormItem
  308. className="half-item"
  309. labelCol={{ span: 8 }}
  310. wrapperCol={{ span: 12 }}
  311. label="产品金额"
  312. >
  313. <Input
  314. type={'number'}
  315. placeholder="请输入产品金额"
  316. value={this.state.amount}
  317. onChange={(e) => {
  318. this.setState({ amount: e.target.value });
  319. }}
  320. />
  321. </FormItem>
  322. <FormItem
  323. className="half-item"
  324. labelCol={{ span: 8 }}
  325. wrapperCol={{ span: 12 }}
  326. label="是否发布到首页"
  327. >
  328. <Select
  329. value={this.state.host}
  330. placeholder="是否发布到首页"
  331. onChange={e => {
  332. this.setState({
  333. host: e
  334. });
  335. }}
  336. >
  337. <Option value={0}>否</Option>
  338. <Option value={1}>是</Option>
  339. </Select>
  340. </FormItem>
  341. <FormItem
  342. className="half-item"
  343. labelCol={{ span: 8 }}
  344. wrapperCol={{ span: 12 }}
  345. label="排序"
  346. >
  347. <Input
  348. placeholder="请输入排序"
  349. value={this.state.sort}
  350. onChange={e => {
  351. this.setState({
  352. sort: e.target.value
  353. });
  354. }}
  355. />
  356. <p>数字越大,排序越前</p>
  357. </FormItem>
  358. <FormItem
  359. className="half-item"
  360. labelCol={{ span: 8 }}
  361. wrapperCol={{ span: 12 }}
  362. label="摘要"
  363. >
  364. <Input
  365. placeholder="请输入摘要"
  366. value={this.state.summary}
  367. onChange={e => {
  368. this.setState({
  369. summary: e.target.value
  370. });
  371. }}
  372. />
  373. </FormItem>
  374. <div className="clearfix">
  375. <FormItem
  376. className="half-item"
  377. labelCol={{ span: 8 }}
  378. wrapperCol={{ span: 12 }}
  379. label="缩略图"
  380. >
  381. <PicturesWall
  382. type={0}
  383. fileList={this.getOrgCodeUrl}
  384. pictureUrl={this.state.pictureImgUrl}
  385. />
  386. </FormItem>
  387. </div>
  388. <div className="clearfix">
  389. <FormItem
  390. className="half-item"
  391. labelCol={{ span: 8 }}
  392. wrapperCol={{ span: 12 }}
  393. label="视频/音频"
  394. >
  395. <PicturesWall
  396. type={this.state.commodityType}
  397. fileList={this.getVideoOrgCodeUrl}
  398. pictureUrl={this.state.pictureVideoUrl}
  399. />
  400. <p>支持<span style={{color:'#F00'}}>MP3/MP4/RMVB/MKV/AVI</span></p>
  401. </FormItem>
  402. </div>
  403. <div className="clearfix">
  404. <FormItem
  405. labelCol={{ span: 4 }}
  406. wrapperCol={{ span: 18 }}
  407. label="未购买简介"
  408. >
  409. <Editors
  410. id={0}
  411. textContent={this.state.content}
  412. uploadUrl={"/api/admin/news/uploadFile"}
  413. globalConfig={globalConfig.uploadPath}
  414. placeholder="内容(编辑器,支持图文音频等)"
  415. handleRichText={value => {
  416. this.setState({ content: value });
  417. }}
  418. />
  419. </FormItem>
  420. </div>
  421. <div className="clearfix">
  422. <FormItem
  423. labelCol={{ span: 4 }}
  424. wrapperCol={{ span: 18 }}
  425. label="已购买简介"
  426. >
  427. <Editors
  428. id={1}
  429. textContent={this.state.commodityContent}
  430. uploadUrl={"/api/admin/news/uploadFile"}
  431. globalConfig={globalConfig.uploadPath}
  432. placeholder="内容(编辑器,支持图文音频等)"
  433. handleRichText={value => {
  434. this.setState({ commodityContent: value });
  435. }}
  436. />
  437. </FormItem>
  438. </div>
  439. </div>
  440. <div style={{display:'flex',justifyContent: 'center'}}>
  441. <Button
  442. type="primary"
  443. onClick={()=>{
  444. this.onOk();
  445. }}>
  446. 保存
  447. </Button>
  448. <Button
  449. type="primary"
  450. style={{marginLeft:'30px'}}
  451. onClick={()=>{
  452. this.onOk(1);
  453. }}>
  454. 保存并发布
  455. </Button>
  456. </div>
  457. </SpinContainer>
  458. </Form>
  459. </Modal>
  460. )
  461. }
  462. }
  463. export default Add;