modal.jsx 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  1. import React, { Component } from "react";
  2. import Taro from "@tarojs/taro";
  3. import { View, Image, Button, Picker, Text } from '@tarojs/components'
  4. import { AtInput, AtModal, AtModalHeader, AtModalContent, AtModalAction } from "taro-ui";
  5. import { typeList, vehiclelist } from '../../utils/tools/config';
  6. import { getNumHourse, removeNull } from "../../utils/tools";
  7. import { detailsAdd } from "../../utils/servers/servers";
  8. import Right from '../../image/right.png';
  9. import Icons from '../../image/returns.png';
  10. import dayjs from "dayjs";
  11. import './index.less';
  12. import "taro-ui/dist/style/components/icon.scss";
  13. class Modal extends Component {
  14. constructor(props) {
  15. super(props);
  16. this.state = {
  17. data: {
  18. type: {},
  19. vehicle: {},
  20. rangeStartMinuteVal: '',
  21. rangeEndMinuteVal: '',
  22. }
  23. };
  24. }
  25. getNumHourse(startTime, endTime) {
  26. this.setState({
  27. totalDuration: getNumHourse(
  28. startTime,
  29. endTime,
  30. this.state.validDates.length
  31. ),
  32. });
  33. }
  34. onPickerHide() {
  35. this.setState({
  36. isPickerRender: false,
  37. });
  38. }
  39. onSetPickerTime(val) {
  40. let data = val.detail;
  41. this.setState({
  42. rangeStartMinuteVal: data.selectStartTime,
  43. rangeEndMinuteVal: data.selectEndTime,
  44. });
  45. let arr = [];
  46. if (data.startTime && data.endTime) {
  47. let a = dayjs(data.startTime);
  48. let b = dayjs(data.endTime);
  49. let num;
  50. if (a.hour() <= b.hour()) {
  51. num = b.diff(a, "day") + 1;
  52. } else {
  53. num = b.diff(a, "day") + 2;
  54. }
  55. let strAdd = data.startTime;
  56. for (let i = 0; i < num; i++) {
  57. let time = dayjs(strAdd).add(i, "days").format("YYYY-MM-DD");
  58. arr.push({ value: time });
  59. }
  60. }
  61. this.setState({
  62. rangeEndVal: dayjs(data.endTime).format("YYYY-MM-DD"),
  63. rangeStartVal: dayjs(data.startTime).format("YYYY-MM-DD"),
  64. validDates: arr,
  65. }, () => {
  66. let a1 = dayjs(dayjs(data.endTime).format("YYYY-MM-DD HH:mm:ss"));
  67. let b1 = dayjs(dayjs(data.startTime).format("YYYY-MM-DD HH:mm:ss"));
  68. this.getNumHourse(b1, a1);
  69. });
  70. }
  71. // 差旅费报销
  72. onSubmit() {
  73. const { data } = this.state
  74. const { eaid } = this.props
  75. let type = data.type.value
  76. if (!type && type != 0) {
  77. Taro.showToast({ title: "请选择费用类型", icon: "none", });
  78. return
  79. }
  80. if (type == 1) {
  81. if (!data.vehicle.value && data.vehicle.value != 0) {
  82. Taro.showToast({ title: "请选择交通工具", icon: "none", });
  83. return
  84. }
  85. if (data.vehicle.value == 0 && !data.vehicleOther) {
  86. Taro.showToast({ title: "请填写其他工具说明", icon: "none", });
  87. return
  88. }
  89. if (!this.state.rangeStartMinuteVal || !this.state.rangeEndMinuteVal) {
  90. Taro.showToast({ title: "请选择时间", icon: "none", });
  91. return
  92. }
  93. if (!data.startDistrict) {
  94. Taro.showToast({ title: "请填写始发地", icon: "none", });
  95. return
  96. }
  97. if (!data.endDistrict) {
  98. Taro.showToast({ title: "请填写目的地", icon: "none", });
  99. return
  100. }
  101. }
  102. if (!data.amount) {
  103. Taro.showToast({ title: "请填写报销金额", icon: "none", });
  104. return
  105. }
  106. var isMoney = /^(([1-9][0-9]*)|(([0]\.\d{1,2}|[1-9][0-9]*\.\d{1,2})))$/;
  107. if (!isMoney.test(data.amount)) {
  108. Taro.showToast({ title: "请填写正确的报销金额", icon: "none", });
  109. return
  110. }
  111. if (type == 1) {
  112. data.startTime = this.state.rangeStartMinuteVal
  113. data.endTime = this.state.rangeEndMinuteVal
  114. }
  115. if (data.vehicle.value != 0) {
  116. data.vehicleOther = undefined
  117. }
  118. let obj = {
  119. ...data,
  120. ...{ eaid, type: data.type.value, vehicle: data.vehicle.value, }
  121. }
  122. this.setState({
  123. loading: true,
  124. });
  125. detailsAdd(removeNull(obj))
  126. .then((v) => {
  127. this.setState({
  128. loading: false,
  129. });
  130. if (v.error.length === 0) {
  131. this.props.onClose()
  132. if (type == 1) {
  133. Taro.setStorageSync('location', { start: data.startDistrict, end: data.endDistrict })
  134. }
  135. } else {
  136. Taro.showToast({
  137. title: v.error[0].message,
  138. icon: "none",
  139. });
  140. }
  141. })
  142. .catch(() => {
  143. this.setState({
  144. loading: false,
  145. });
  146. });
  147. }
  148. swap() {
  149. const temp = this.state.data.startDistrict;
  150. this.setState({
  151. data: {
  152. ...this.state.data,
  153. ...{
  154. startDistrict: this.state.data.endDistrict,
  155. endDistrict: temp
  156. }
  157. }
  158. });
  159. }
  160. render() {
  161. const { data } = this.state
  162. const { visible = "", onClose } = this.props
  163. return (
  164. <AtModal
  165. isOpened={visible != ""}
  166. closeOnClickOverlay={false}
  167. >
  168. <AtModalHeader>{visible == "add" ? "新增费用" : visible == "edit" && "编辑费用"}</AtModalHeader>
  169. <AtModalContent>
  170. <View className="modal" style={{ minHeight: data.type.value == 1 && "200px" }}>
  171. <View className="picker">
  172. <View className="ptit"><View style={{ color: "red" }}>*&nbsp;</View>类型:</View>
  173. <Picker
  174. value={data.type.value == 0 ? typeList.length - 1 : data.type.value - 1}
  175. range={typeList} rangeKey='label' mode='selector'
  176. onChange={(e) => {
  177. let obj = {
  178. type: typeList[e.detail.value]
  179. }
  180. console.log(this.props.visible, "======", e.detail.value)
  181. if (this.props.visible == "add" && e.detail.value == 0) {
  182. console.log("--")
  183. let location = Taro.getStorageSync('location')
  184. if (location) {
  185. obj.startDistrict = location.start
  186. obj.endDistrict = location.end
  187. }
  188. }
  189. this.setState({
  190. data: { ...data, ...obj }
  191. })
  192. }}>
  193. <View className='selModal'>
  194. <View className='selTitle'>{!data.type.label ? "点击选择" : data.type.label}</View>
  195. </View>
  196. </Picker>
  197. </View>
  198. {/* 其他 */}
  199. {/* {data.type.value == 0 &&
  200. <View>
  201. <AtInput
  202. required
  203. name='vehicleOther'
  204. title='类型说明:'
  205. type='text'
  206. placeholder='其他说明'
  207. value={data.vehicleOther}
  208. onChange={e => {
  209. this.setState({
  210. data: { ...data, vehicleOther: e }
  211. })
  212. }}
  213. />
  214. </View>} */}
  215. {/* 交通费 */}
  216. {data.type?.value == 1 &&
  217. <View className="picker">
  218. <View className="ptit"><View style={{ color: "red" }}>*&nbsp;</View>交通工具:</View>
  219. <Picker
  220. value={data.vehicle.value == 0 ? vehiclelist.length - 1 : data.vehicle.value - 1}
  221. range={vehiclelist} rangeKey='label' mode='selector'
  222. onChange={(e) => {
  223. this.setState({
  224. data: { ...data, vehicle: vehiclelist[e.detail.value] }
  225. })
  226. }}>
  227. <View className='selModal'>
  228. <View className='selTitle'>{!data.vehicle.label ? "点击选择" : data.vehicle.label}</View>
  229. </View>
  230. </Picker>
  231. </View>}
  232. {/* 其他 */}
  233. {data.vehicle?.value == 0 &&
  234. <View>
  235. <AtInput
  236. required
  237. name='vehicleOther'
  238. title='工具说明:'
  239. type='text'
  240. placeholder='其他交通工具说明'
  241. value={data.vehicleOther}
  242. onChange={e => {
  243. this.setState({
  244. data: { ...data, vehicleOther: e }
  245. })
  246. }}
  247. />
  248. </View>}
  249. {data.type?.value == 1 &&
  250. <View className="pub">
  251. <View className="ptit"><View style={{ color: "red" }}>*&nbsp;</View>时间:</View>
  252. <View className="ptxt"
  253. onClick={() => {
  254. this.setState({
  255. isPickerRender: true,
  256. });
  257. }}
  258. >
  259. {
  260. this.state.rangeStartMinuteVal &&
  261. this.state.rangeEndMinuteVal
  262. ? <View className="pick">
  263. <View className="ptime">{this.state.rangeStartMinuteVal.slice(0, 16)}</View>
  264. &nbsp;&nbsp;至&nbsp;&nbsp;
  265. <View className="ptime">{this.state.rangeEndMinuteVal.slice(0, 16)}</View>
  266. </View>
  267. : <View>选择时间</View>
  268. }
  269. </View>
  270. </View>}
  271. {data.type?.value == 1 &&
  272. <View className="pub">
  273. <View className="ptit"><View style={{ color: "red" }}>*&nbsp;</View>地点:</View>
  274. <View className="ptxt">
  275. <AtInput name="startDistrict" className="pin" type='text' placeholder='始发地' value={data.startDistrict}
  276. onChange={e => {
  277. this.setState({
  278. data: { ...data, startDistrict: e }
  279. })
  280. }}
  281. />
  282. <Image src={Icons} className='icons' mode='aspectFit' onClick={this.swap.bind(this)} />
  283. <AtInput name="endDistrict" className="pin" type='text' placeholder='目的地' value={data.endDistrict}
  284. onChange={e => {
  285. this.setState({
  286. data: { ...data, endDistrict: e }
  287. })
  288. }}
  289. />
  290. </View>
  291. </View>}
  292. <View>
  293. <AtInput
  294. required
  295. name='amount'
  296. title='金额:'
  297. type='digit'
  298. placeholder='请填写金额(元)'
  299. value={data.amount}
  300. onChange={e => {
  301. this.setState({
  302. data: { ...data, amount: e }
  303. })
  304. }}
  305. />
  306. </View>
  307. </View>
  308. </AtModalContent>
  309. <AtModalAction>
  310. <Button onClick={onClose}>取消</Button>
  311. <Button onClick={this.onSubmit.bind(this)}>确定</Button>
  312. </AtModalAction>
  313. <timePicker
  314. config={{
  315. endDate: true,
  316. column: "minute",
  317. dateLimit: false,
  318. limitStartTime: dayjs()
  319. .subtract(3, "year")
  320. .format("YYYY-MM-DD HH:mm:ss"),
  321. limitEndTime: dayjs()
  322. .add(3, "year")
  323. .format("YYYY-MM-DD HH:mm:ss"),
  324. }}
  325. isPartition
  326. pickerShow={this.state.isPickerRender}
  327. onconditionaljudgment={(v) => {
  328. let a = dayjs(
  329. dayjs(v.detail.endTime)
  330. .second(0)
  331. .format("YYYY-MM-DD HH:mm:ss")
  332. );
  333. }}
  334. onhidepicker={() => {
  335. this.onPickerHide();
  336. }}
  337. onsetpickertime={(v) => {
  338. this.onSetPickerTime(v);
  339. }}
  340. />
  341. </AtModal>
  342. )
  343. }
  344. }
  345. export default Modal;