reportdetail.js 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792
  1. import Taro, { Component } from '@tarojs/taro'
  2. import { View, Input, Picker, Label, Button, } from '@tarojs/components'
  3. import { Loading } from '@components'
  4. import { connect } from '@tarojs/redux'
  5. import * as actions from '@actions/report'
  6. import { getWindowHeight } from '@utils/style'
  7. import ImagePicker from '../../components/imagePicker'
  8. import RuiEditor from '../../components/editor'
  9. import './reportdetail.scss'
  10. @connect(state => state.home, { ...actions, })
  11. class ReportDetail extends Component {
  12. config = {
  13. navigationBarTitleText: '报告撰写'
  14. }
  15. state = {
  16. selector: [
  17. { name: "文本项", type: "text" },
  18. { name: "日期项", type: "date" },
  19. { name: "起止时间", type: "dateRange" },
  20. ],
  21. visible: "",
  22. data: {},
  23. metadata: [],
  24. chapterType: [
  25. { title: "立项背景与意义", key: "BACKGROUND", keywords: ['必要性'] },
  26. { title: "国内外研究现状与发展趋势", key: "RESEARCH_STATUS", keywords: ['研究现状', '发展趋势'] },
  27. { title: "项目主要研究内容", key: "RESEARCH", keywords: ['技术特点', '技术研究', '实际应用'] },
  28. { title: "关键技术与创新点", key: "INNOVATION", keywords: ['关键技术', '创新点'] },
  29. { title: "拟解决的关键问题", key: "SOLVE_PROBLEM", keywords: ['解决的问题', '解决的关键问题'] },
  30. { title: "实施方案及进度安排", key: "SOLUTION", keywords: ['实施方案'] },
  31. { title: "经费预算", key: "BUDGET", keywords: [] },
  32. { title: "经济及社会效益分析", key: "BENEFIT_ANALYSIS", keywords: ['经济效益', '社会效益', '经济效益分析', '社会效益分析'] },
  33. { title: "项目风险分析和对策", key: "RISK", keywords: ['风险分析', '风险对策'] },
  34. { title: "自定义章节", key: "USER_DEFINED", keywords: [] },
  35. ],
  36. chapters: [],
  37. aeList: [],
  38. name: "",
  39. newvb: false,
  40. popup: false,
  41. template: false,
  42. name: '',
  43. tags: [],
  44. }
  45. componentDidMount() {
  46. this.getData()
  47. this.getQuery()
  48. }
  49. componentWillUnmount() {
  50. }
  51. // 详情接口
  52. getData() {
  53. this.setState({ loading: true })
  54. let payload = {
  55. id: this.$router.params.id,
  56. }
  57. this.props.reportDetail(payload).then((data) => {
  58. this.setState({
  59. loading: false,
  60. data: data,
  61. metadata: data.metadata,
  62. chapters: data.chapters,
  63. })
  64. }).catch(() => {
  65. this.setState({ loading: false })
  66. })
  67. }
  68. // 获取企业列表
  69. getQuery() {
  70. let payload = {
  71. name: "",
  72. size: 99,
  73. }
  74. this.props.query(payload).then((data) => {
  75. this.setState({
  76. aeList: data,
  77. })
  78. }).catch(() => {
  79. })
  80. }
  81. // Al生成
  82. getGenerate(title, i) {
  83. const { data } = this.state
  84. let payload = {
  85. chapterTitle: title,
  86. keywords: data.keywords,
  87. projectName: data.reportName,
  88. }
  89. Taro.showLoading({
  90. title: 'AI正在撰写章节内容,请稍等…',
  91. mask: true,
  92. })
  93. this.props.generate(payload).then((res) => {
  94. Taro.hideLoading()
  95. const chaplist = this.state.data.chapters
  96. chaplist.forEach(function (item, index) {
  97. if (index == i) {
  98. item.content = res
  99. }
  100. })
  101. this.setState({
  102. chapters: chaplist
  103. })
  104. }).catch(() => {
  105. Taro.hideLoading()
  106. })
  107. }
  108. // 添加新项
  109. onChange = e => {
  110. this.setState({
  111. type: this.state.selector[e.detail.value].type,
  112. inputName: e.detail.value == 2 ? "起止时间" : undefined,
  113. visible: "add"
  114. })
  115. }
  116. // 阿拉伯数字转中文
  117. numberToChinese(num) {
  118. var arr1 = new Array('零', '一', '二', '三', '四', '五', '六', '七', '八', '九');
  119. var arr2 = new Array('', '十', '百', '千', '万', '十', '百', '千', '亿', '十', '百', '千', '万', '十', '百', '千', '亿');//可继续追加更高位转换值
  120. if (!num || isNaN(num)) {
  121. return "零";
  122. }
  123. var english = num.toString().split("");
  124. var result = "";
  125. for (var i = 0; i < english.length; i++) {
  126. var des_i = english.length - 1 - i;//倒序排列设值
  127. result = arr2[i] + result;
  128. var arr1_index = english[des_i];
  129. result = arr1[arr1_index] + result;
  130. }
  131. //将【零千、零百】换成【零】 【十零】换成【十】
  132. result = result.replace(/零(千|百|十)/g, '零').replace(/十零/g, '十');
  133. //合并中间多个零为一个零
  134. result = result.replace(/零+/g, '零');
  135. //将【零亿】换成【亿】【零万】换成【万】
  136. result = result.replace(/零亿/g, '亿').replace(/零万/g, '万');
  137. //将【亿万】换成【亿】
  138. result = result.replace(/亿万/g, '亿');
  139. //移除末尾的零
  140. result = result.replace(/零+$/, '');
  141. //将【零一十】换成【零十】
  142. //result = result.replace(/零一十/g, '零十');//貌似正规读法是零一十
  143. //将【一十】换成【十】
  144. result = result.replace(/^一十/g, '十');
  145. return result;
  146. }
  147. // 字符串拼接
  148. getTitleWithChineseNum(index, title) {
  149. return this.numberToChinese(index + 1) + '、' + title
  150. }
  151. // 章节添加
  152. onChapterChange = e => {
  153. let list = this.state.chapters
  154. let obj = this.state.chapterType[e.detail.value]
  155. let data = {
  156. chapterType: obj.key,
  157. content: "",
  158. fullTitle: this.getTitleWithChineseNum(list.length, obj.title),
  159. keywords: obj.keywords,
  160. title: obj.title,
  161. }
  162. list.push(data)
  163. this.setState({
  164. chapters: list
  165. })
  166. }
  167. // 选中关联企业
  168. onAeChange = e => {
  169. const { aeList } = this.state
  170. let obj = aeList[e.detail.value]
  171. let list = this.state.data
  172. list.companyName = obj.name
  173. list.companyId = obj.id
  174. this.setState({
  175. data: list,
  176. })
  177. }
  178. // 企业添加
  179. onAeCancel = () => {
  180. this.setState({
  181. name: "",
  182. newvb: false,
  183. })
  184. }
  185. // 企业添加
  186. onAeOk = () => {
  187. if (!this.state.name) {
  188. Taro.showToast({
  189. title: "请输入新企业名称",
  190. icon: 'none'
  191. })
  192. return
  193. }
  194. const payload = {
  195. name: this.state.name,
  196. }
  197. this.props.company(payload).then((data) => {
  198. let obj = this.state.data
  199. obj.companyName = data.name
  200. obj.companyId = data.id
  201. this.setState({
  202. data: obj,
  203. newvb: false,
  204. })
  205. }).catch(() => {
  206. })
  207. }
  208. // 添加新项弹窗
  209. onCancel = () => {
  210. this.setState({
  211. inputName: undefined,
  212. inputText: undefined,
  213. dateSel: undefined,
  214. dataStart: undefined,
  215. dataEnd: undefined,
  216. indx: undefined,
  217. type: "",
  218. visible: "",
  219. })
  220. }
  221. // 添加新项弹窗
  222. onOk = () => {
  223. const { visible, metadata, inputName, inputText, type, indx, dateSel, dataStart, dataEnd } = this.state
  224. // if (visible == "add") {
  225. let list = []
  226. if (!inputName) {
  227. Taro.showToast({
  228. title: "请输入字段名称",
  229. icon: 'none'
  230. })
  231. return
  232. }
  233. if (type == "text") {
  234. if (!inputText) {
  235. Taro.showToast({
  236. title: "请输入字段值",
  237. icon: 'none'
  238. })
  239. return
  240. }
  241. list.push({ name: inputName, value: inputText, type: type })
  242. } else if (type == "date") {
  243. if (!dateSel) {
  244. Taro.showToast({
  245. title: "请选择日期",
  246. icon: 'none'
  247. })
  248. return
  249. }
  250. list.push({ name: inputName, value: dateSel, type: type })
  251. } else if (type == "dateRange") {
  252. if (!dataStart) {
  253. Taro.showToast({
  254. title: "请选择开始日期",
  255. icon: 'none'
  256. })
  257. return
  258. }
  259. if (!dataEnd) {
  260. Taro.showToast({
  261. title: "请选择结束日期",
  262. icon: 'none'
  263. })
  264. return
  265. }
  266. list.push({ name: inputName, value: dataStart + " " + dataEnd, type: type })
  267. }
  268. if (visible == "edit") {
  269. let nlist = metadata
  270. nlist[indx] = list[0]
  271. this.setState({
  272. metadata: nlist,
  273. visible: "",
  274. })
  275. } else {
  276. this.setState({
  277. metadata: [...metadata, ...list],
  278. visible: "",
  279. })
  280. }
  281. }
  282. // 修改章节名
  283. onChapTitle = (i, e) => {
  284. const data = this.state.chapters
  285. data.forEach(function (item, index) {
  286. if (index == i) {
  287. item.title = e.detail.value
  288. }
  289. })
  290. this.setState({
  291. chapters: data
  292. })
  293. }
  294. // 修改章节关键词
  295. onChapKeywords = (i, e) => {
  296. const data = this.state.chapters
  297. data.forEach(function (item, index) {
  298. if (index == i) {
  299. let val = e.detail.value.replace(/[\uff0c]/g, ",")
  300. item.keywords = !val ? [] : val.split(",")
  301. }
  302. })
  303. this.setState({
  304. chapters: data
  305. })
  306. }
  307. // 修改章节内容
  308. onChaoContent = (i, e) => {
  309. const data = this.state.chapters
  310. data.forEach(function (item, index) {
  311. if (index == i) {
  312. item.content = e.detail.html
  313. }
  314. })
  315. this.setState({
  316. chapters: data
  317. })
  318. }
  319. // 二级确认
  320. toggleVisible = () => {
  321. this.setState({
  322. popup: !this.state.popup,
  323. })
  324. }
  325. // 删除章节
  326. delChap = () => {
  327. const list = this.state.chapters
  328. list.splice(this.state.delIndex, 1)
  329. for (var i = 0; i < list.length; i++) {
  330. list[i].fullTitle = this.getTitleWithChineseNum(i, list[i].title)
  331. }
  332. this.setState({
  333. chapters: list
  334. })
  335. this.toggleVisible()
  336. }
  337. // 保存
  338. onSubmit = () => {
  339. const { data, metadata, chapters } = this.state
  340. if (!data.companyId) {
  341. Taro.showToast({
  342. title: "请填写关联企业!",
  343. icon: 'none'
  344. })
  345. return
  346. }
  347. if (!data.name) {
  348. Taro.showToast({
  349. title: "请填写报告类型!",
  350. icon: 'none'
  351. })
  352. return
  353. }
  354. if (!data.reportName) {
  355. Taro.showToast({
  356. title: "请填写项目名称!",
  357. icon: 'none'
  358. })
  359. return
  360. }
  361. if (!data.supervisor) {
  362. Taro.showToast({
  363. title: "请填写负责人!",
  364. icon: 'none'
  365. })
  366. return
  367. }
  368. if (!data.keywords) {
  369. Taro.showToast({
  370. title: "请填写关键词!",
  371. icon: 'none'
  372. })
  373. return
  374. }
  375. data.metadata = metadata
  376. data.chapters = chapters
  377. let payload = data
  378. this.props.report(payload).then((data) => {
  379. Taro.showToast({
  380. title: "保存成功",
  381. icon: 'none'
  382. })
  383. }).catch(() => {
  384. })
  385. }
  386. // 另存为模板
  387. onReportTemplate = () => {
  388. const { data, metadata, chapters, name, tags } = this.state
  389. if (!this.state.name) {
  390. Taro.showToast({
  391. title: "请填写模板名称!",
  392. icon: 'none'
  393. })
  394. return
  395. }
  396. let payload = {
  397. chapters,
  398. companyId: data.companyId || 0,
  399. id: 0,
  400. logoPath: data.logoPath || '',
  401. metadata,
  402. name,
  403. reportName: data.reportName || '',
  404. tags,
  405. }
  406. this.props.onReportTemplate(payload).then((data) => {
  407. this.onTemCancel()
  408. Taro.showToast({
  409. title: "模板保存成功",
  410. icon: 'none'
  411. })
  412. }).catch(() => {
  413. })
  414. }
  415. // 取消
  416. onTemCancel = () => {
  417. this.setState({
  418. name: '',
  419. tags: [],
  420. template: false,
  421. })
  422. }
  423. render() {
  424. // if (!this.state.loaded) {
  425. // return <Loading />
  426. // }
  427. const { data, visible, metadata, type, chapterType, chapters, aeList } = this.state
  428. return (
  429. <View className='home main'>
  430. <View className='home-item'>
  431. <View className='home-item-tit'>关联企业</View>
  432. <View className='home-item-vals'>
  433. <Picker mode='selector' range={aeList} rangeKey="name"
  434. onChange={this.onAeChange}
  435. >
  436. <View className='home-item-vals-txt'>{data.companyName || "请选择关联企业"}</View>
  437. </Picker>
  438. <View className='home-item-vals-bt'>
  439. <Button size='mini' type='primary' onClick={() => { this.setState({ newvb: true }) }}>+新增企业</Button>
  440. </View>
  441. </View>
  442. </View>
  443. <View className='home-item'>
  444. <View className='home-item-tit'>报告类型</View>
  445. <Input
  446. value={data.name}
  447. className='home-item-val'
  448. placeholder='请输入报告类型'
  449. onChange={e => {
  450. let obj = data
  451. obj.name = e.detail.value
  452. this.setState({
  453. data: obj,
  454. })
  455. }}
  456. />
  457. </View>
  458. <View className='home-item'>
  459. <View className='home-item-tit'>项目名称</View>
  460. <Input
  461. value={data.reportName}
  462. className='home-item-val'
  463. placeholder='请输入项目名称'
  464. onChange={e => {
  465. let obj = data
  466. obj.reportName = e.detail.value
  467. this.setState({
  468. data: obj,
  469. })
  470. }}
  471. />
  472. </View>
  473. <View className='home-item'>
  474. <View className='home-item-tit'>项目负责人</View>
  475. <Input
  476. value={data.supervisor}
  477. className='home-item-val'
  478. placeholder='请输入项目负责人'
  479. onChange={e => {
  480. let obj = data
  481. obj.supervisor = e.detail.value
  482. this.setState({
  483. data: obj,
  484. })
  485. }}
  486. />
  487. </View>
  488. <View className='home-item'>
  489. <View className='home-item-tit'>企业LOGO</View>
  490. <ImagePicker
  491. id={data.id}
  492. keyId="reportId"
  493. api='/gw/user/logo'
  494. urls={data.logoPath}
  495. onChange={(path) => {
  496. let obj = data
  497. obj.logoPath = path
  498. this.setState({
  499. data: obj,
  500. })
  501. }}
  502. />
  503. </View>
  504. <View className='home-item'>
  505. <View className='home-item-tit'>关键词</View>
  506. <Input
  507. value={data.keywords}
  508. className='home-item-val'
  509. placeholder='请输入关键词'
  510. onChange={e => {
  511. let obj = data
  512. obj.keywords = e.detail.value
  513. this.setState({
  514. data: obj,
  515. })
  516. }}
  517. />
  518. </View>
  519. {
  520. metadata.map((item, index) =>
  521. <View className='home-item' key={index}
  522. onClick={() => {
  523. this.setState({
  524. indx: index,
  525. type: item.type,
  526. inputName: item.name,
  527. visible: "edit",
  528. inputText: item.type == "text" ? item.value : undefined,
  529. dateSel: item.type == "date" ? item.value : undefined,
  530. dataStart: item.type == "dateRange" ? item.value.split(" ")[0] : undefined,
  531. dataEnd: item.type == "dateRange" ? item.value.split(" ")[1] : undefined,
  532. })
  533. }}
  534. >
  535. <View className='home-item-tits'>
  536. <View className='home-item-tits-txt'>{item.name}</View>
  537. <View className='home-item-tits-bt'>
  538. <Button size='mini' type='warn'
  539. onClick={e => {
  540. e.stopPropagation()
  541. let list = this.state.metadata
  542. list.splice(index, 1)
  543. this.setState({
  544. metadata: list
  545. })
  546. }}
  547. >删除</Button>
  548. </View>
  549. </View>
  550. {item.type == "text" && <View className='home-item-val'>{item.value}</View>}
  551. {item.type == "date" && <View className='home-item-val'>{item.value}</View>}
  552. {item.type == "dateRange" && <View className='home-item-val'>{item.value.replace(" ", " → ")}</View>}
  553. </View>
  554. )
  555. }
  556. <View className='home-item'>
  557. <Picker mode='selector' range={this.state.selector} rangeKey="name"
  558. onChange={this.onChange}
  559. >
  560. <Button style={{ background: "#0079c2", color: "#fff" }}>+添加新项</Button>
  561. </Picker>
  562. </View>
  563. <View className='home-line' />
  564. {
  565. chapters.map((item, index) =>
  566. <View className='home-item' key={index} style={{ marginBottom: 10, }}>
  567. <View className='home-item-tits'>
  568. <Input
  569. value={item.title}
  570. className='home-item-tits-txt'
  571. style={{ borderBottom: "1px solid #d9d9d9" }}
  572. onChange={(e) => {
  573. this.onChapTitle(index, e)
  574. }}
  575. />
  576. <View className='home-item-tits-bt'>
  577. <Button size='mini' type='warn'
  578. onClick={e => {
  579. e.stopPropagation()
  580. this.setState({
  581. delIndex: index
  582. })
  583. this.toggleVisible()
  584. }}
  585. >删除</Button>
  586. </View>
  587. </View>
  588. <View className='home-item-text'>
  589. <View>章节关键词:</View>
  590. <Input
  591. value={item.keywords.toString().replace(/,/g, ",")}
  592. className='home-item-text-val'
  593. placeholder='输入逗号分割'
  594. onChange={(e) => {
  595. this.onChapKeywords(index, e)
  596. }}
  597. />
  598. </View>
  599. <View className='home-item-editor'>
  600. <RuiEditor
  601. keys={index}
  602. placeholder={item.content || '文字内容...'}
  603. onInput={e => {
  604. this.onChaoContent(index, e)
  605. }}
  606. />
  607. </View>
  608. {/* <View className='home-item-editor' contenteditable="true">{item.content || "请填写内容..."}</View> */}
  609. <View className='home-item-bottom'>
  610. <View></View>
  611. <Button
  612. style={{ margin: 0 }}
  613. size='mini'
  614. type='primary'
  615. onClick={() => {
  616. this.getGenerate(item.title, index)
  617. }}
  618. >Al生成</Button>
  619. </View>
  620. </View>
  621. )
  622. }
  623. <View className='home-item'>
  624. <Picker mode='selector' range={chapterType} rangeKey="title"
  625. onChange={this.onChapterChange}
  626. >
  627. <Button style={{ background: "#0079c2", color: "#fff" }}>+添加章节</Button>
  628. </Picker>
  629. </View>
  630. <View className='home-item' style={{ marginTop: 30, paddingBottom: 30 }}>
  631. <Button type='primary' onClick={this.onSubmit}>保存</Button>
  632. <Button style={{ background: "#0079c2", color: "#fff" }}
  633. onClick={() => {
  634. this.setState({
  635. template: true
  636. })
  637. }}
  638. >另存为模板</Button>
  639. </View>
  640. {/* 新增项 */}
  641. {visible != "" &&
  642. <View className='mask'>
  643. <View className='count'>
  644. <View className='count_top'>
  645. <Input
  646. value={this.state.inputName}
  647. className='count_top_input'
  648. placeholder='字段名称'
  649. onChange={e => { this.setState({ inputName: e.detail.value }) }}
  650. />
  651. {type == "text" &&
  652. <Input
  653. value={this.state.inputText}
  654. style={{ marginTop: 15 }}
  655. className='count_top_input'
  656. placeholder='请输入字段值'
  657. onChange={e => { this.setState({ inputText: e.detail.value }) }}
  658. />}
  659. {type == "date" &&
  660. <Picker mode='date' value={this.state.dateSel}
  661. onChange={e => {
  662. this.setState({
  663. dateSel: e.detail.value,
  664. })
  665. }}>
  666. <View className={!this.state.dateSel ? 'count_top_dates' : 'count_top_date'}>
  667. {!this.state.dateSel ? "请选择日期" : this.state.dateSel}
  668. </View>
  669. </Picker>
  670. }
  671. {type == "dateRange" &&
  672. <Picker mode='date' value={this.state.dataStart}
  673. onChange={e => {
  674. this.setState({
  675. dataStart: e.detail.value,
  676. })
  677. }}>
  678. <View className={!this.state.dataStart ? 'count_top_dates' : 'count_top_date'}>
  679. {!this.state.dataStart ? "开始日期" : this.state.dataStart}
  680. </View>
  681. </Picker>
  682. }
  683. {type == "dateRange" &&
  684. <Picker mode='date' value={this.state.dataEnd}
  685. onChange={e => {
  686. this.setState({
  687. dataEnd: e.detail.value,
  688. })
  689. }}>
  690. <View className={!this.state.dataEnd ? 'count_top_dates' : 'count_top_date'}>
  691. {!this.state.dataEnd ? "结束日期" : this.state.dataEnd}
  692. </View>
  693. </Picker>
  694. }
  695. </View>
  696. <View className='count_foot'>
  697. <Button onClick={this.onCancel}>取消</Button>
  698. <Button style={{ marginTop: 0 }}
  699. onClick={this.onOk}
  700. >确认</Button>
  701. </View>
  702. </View>
  703. </View>}
  704. {/* 新增企业 */}
  705. {this.state.newvb &&
  706. <View className='mask'>
  707. <View className='count'>
  708. <View className='title'>新增企业名称</View>
  709. <View className='count_top'>
  710. <Input
  711. value={this.state.name}
  712. className='count_top_input'
  713. placeholder='请输入新企业名称'
  714. onChange={e => { this.setState({ name: e.detail.value }) }}
  715. />
  716. </View>
  717. <View className='count_foot'>
  718. <Button onClick={this.onAeCancel}>取消</Button>
  719. <Button style={{ marginTop: 0 }}
  720. onClick={this.onAeOk}
  721. >确认</Button>
  722. </View>
  723. </View>
  724. </View>}
  725. {/* 二级确认 */}
  726. {this.state.popup &&
  727. <View className='mask'>
  728. <View className='count'>
  729. <View className='title' style={{ margin: "60px 0" }}>确认删除吗?</View>
  730. <View className='count_foot'>
  731. <Button onClick={this.toggleVisible}>取消</Button>
  732. <Button style={{ marginTop: 0 }}
  733. onClick={this.delChap}
  734. >确认</Button>
  735. </View>
  736. </View>
  737. </View>}
  738. {/* 另存为模板 */}
  739. {this.state.template &&
  740. <View className='mask'>
  741. <View className='count'>
  742. <View className='title'>另存为模板</View>
  743. <View className='count_top' style={{ margin: "20px 0" }}>
  744. <Input
  745. value={this.state.name}
  746. className='count_top_input'
  747. placeholder='模板名称'
  748. onChange={e => { this.setState({ name: e.detail.value }) }}
  749. />
  750. <Input
  751. value={this.state.tags.toString().replace(/,/g, ",")}
  752. style={{ marginTop: 15 }}
  753. className='count_top_input'
  754. placeholder='模板标签,输入逗号分割'
  755. onChange={e => {
  756. let val = e.detail.value.replace(/[\uff0c]/g, ",")
  757. this.setState({
  758. tags: !val ? [] : val.split(",")
  759. })
  760. }}
  761. />
  762. </View>
  763. <View className='count_foot'>
  764. <Button onClick={this.onTemCancel}>取消</Button>
  765. <Button style={{ marginTop: 0 }}
  766. onClick={this.onReportTemplate}
  767. >确认</Button>
  768. </View>
  769. </View>
  770. </View>
  771. }
  772. </View >
  773. )
  774. }
  775. }
  776. export default ReportDetail