publicContent.jsx 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412
  1. import React,{Component} from 'react';
  2. import Taro,{getCurrentInstance } from '@tarojs/taro';
  3. import {Text, View} from '@tarojs/components'
  4. import dayjs from 'dayjs';
  5. import './index.less';
  6. import DateTimePicker from '../../components/common/DateTimePicker';
  7. import ImagePicker from '../../components/common/imagePicker'
  8. import {AtButton, AtTextarea, AtIcon, AtCalendar, message} from 'taro-ui'
  9. import {addPublicRelease} from '../../utils/servers/servers';
  10. import 'taro-ui/dist/style/components/form.scss';
  11. import 'taro-ui/dist/style/components/button.scss';
  12. import 'taro-ui/dist/style/components/loading.scss';
  13. import 'taro-ui/dist/style/components/icon.scss';
  14. import 'taro-ui/dist/style/components/icon.scss';
  15. import 'taro-ui/dist/style/components/textarea.scss';
  16. import 'taro-ui/dist/style/components/calendar.scss';
  17. import './publicContent.less';
  18. import InquiryModal from "../../components/common/inquiryModal";
  19. class PublicContent extends Component{
  20. constructor(props) {
  21. super(props);
  22. this.state={
  23. rangeStartVal:'',
  24. rangeEndVal:'',
  25. rangeEndMinuteVal:'',
  26. rangeStartMinuteVal:'',
  27. reason:'',
  28. imgs:[],
  29. validDates:[],
  30. totalDuration:0,
  31. loading:false,
  32. }
  33. this.onSubmit = this.onSubmit.bind(this);
  34. this.selectArrder = this.selectArrder.bind(this);
  35. this.onChange = this.onChange.bind(this);
  36. }
  37. componentDidMount() {
  38. Taro.eventCenter.on('result', () => {
  39. this.rangeEndRef && this.rangeEndRef.clear();
  40. this.rangeStartRef && this.rangeStartRef.clear();
  41. this.imagePickerRef && this.imagePickerRef.clear();
  42. this.setState({
  43. rangeStartVal:'',
  44. rangeEndVal:'',
  45. rangeEndMinuteVal:'',
  46. rangeStartMinuteVal:'',
  47. reason:'',
  48. imgs:[],
  49. validDates:[],
  50. totalDuration:0,
  51. loading:false,
  52. })
  53. })
  54. }
  55. getHours(startTime,endTime){
  56. let a1 = dayjs(startTime);
  57. let b1 = dayjs(endTime);
  58. let c1 = b1.diff(a1,'minutes');
  59. let hourse = parseInt(c1/60);
  60. let minutes = c1%60
  61. let minutes1 = parseInt(minutes / 30)*0.5
  62. if(
  63. a1.isBefore(dayjs(a1.format('YYYY-MM-DD')+' 13:30'))
  64. &&
  65. a1.isAfter(dayjs(a1.format('YYYY-MM-DD')+' 12:00'))
  66. ){
  67. this.getHours(dayjs(a1.format('YYYY-MM-DD')+' 13:30'),endTime);
  68. }else if(
  69. a1.isBefore(dayjs(a1.format('YYYY-MM-DD')+' 12:00'))
  70. &&
  71. b1.isAfter(dayjs(a1.format('YYYY-MM-DD')+' 13:30'))
  72. ){
  73. return hourse+minutes1-1.5
  74. }else{
  75. return hourse+minutes1
  76. }
  77. }
  78. getNumHourse(startTime,endTime){
  79. if(dayjs(dayjs(startTime).format('YYYY-MM-DD')).isSame(dayjs(dayjs(endTime).format('YYYY-MM-DD')))){
  80. this.setState({
  81. totalDuration:this.getHours(startTime,endTime)
  82. })
  83. }else{
  84. let a = this.getHours(startTime,dayjs(startTime.format('YYYY-MM-DD')+' 17:30'));
  85. let b = this.getHours(dayjs(endTime.format('YYYY-MM-DD')+' 8:30'),endTime);
  86. let c = (this.state.validDates.length-2)*7.5;
  87. this.setState({
  88. totalDuration:a+b+c
  89. })
  90. }
  91. }
  92. onSubmit(){
  93. if(!this.state.rangeStartMinuteVal){
  94. Taro.showToast({title:'请选择公出开始时间',icon:'none'})
  95. return ;
  96. }
  97. if(!this.state.rangeEndMinuteVal){
  98. Taro.showToast({title:'请选择公出结束时间',icon:'none'})
  99. return ;
  100. }
  101. if(!(this.props.selectArrderLocation.longitude && this.props.selectArrderLocation.latitude)){
  102. Taro.showToast({title:'请选择公出地点',icon:'none'})
  103. return ;
  104. }
  105. if(!this.state.reason){
  106. Taro.showToast({title:'请输入公出事由',icon:'none'})
  107. return ;
  108. }
  109. if(this.state.totalDuration === 0){
  110. Taro.showToast({title:'公出时间不足0小时',icon:'none'})
  111. return ;
  112. }
  113. this.setState({
  114. loading:true
  115. })
  116. addPublicRelease({
  117. uid:this.props.enterpriseInfor.id,
  118. releaseStarts:this.state.rangeStartMinuteVal,
  119. releaseEnds:this.state.rangeEndMinuteVal,
  120. remarks:this.state.reason,
  121. userName: this.props.selectArrderLocation.name,
  122. longitude: this.props.selectArrderLocation.longitude,
  123. latitude: this.props.selectArrderLocation.latitude,
  124. annexUrl: this.state.imgs.length === 0 ? '' : this.state.imgs.join(','),
  125. duration: this.state.totalDuration,
  126. validDate: JSON.stringify(this.state.validDates)
  127. }).then(v=>{
  128. this.setState({
  129. loading:false
  130. })
  131. if(v.error.length === 0){
  132. Taro.eventCenter.trigger('publicContent',v.data)
  133. }else{
  134. Taro.showToast({
  135. title:v.error[0].message,
  136. icon:'none'
  137. })
  138. }
  139. }).catch(()=>{
  140. this.setState({
  141. loading:false
  142. })
  143. });
  144. }
  145. selectArrder(){
  146. const key = 'AWBBZ-GRAC2-JFYUO-CLA7I-JAHXK-YFFGT'; //使用在腾讯位置服务申请的key
  147. const referer = '科德打卡定位'; //调用插件的app的名称
  148. const category = '公司企业,房产小区';
  149. Taro.navigateTo({
  150. url: 'plugin://chooseLocation/index?key=' + key + '&referer=' + referer + '&category=' + category
  151. });
  152. }
  153. onChange(value,type){
  154. let arr = this.state.imgs.concat([]);
  155. if(type === 'add'){
  156. arr.push(value)
  157. }else if(type === 'remove'){
  158. arr.splice(value,1)
  159. }
  160. this.setState({
  161. imgs: arr,
  162. })
  163. }
  164. render() {
  165. return (
  166. <View className='publicContent'>
  167. <View className='formItem'>
  168. <View className='formName'>公出企业:</View>
  169. <View className='formValue'>{this.props.enterpriseInfor.name}</View>
  170. </View>
  171. <View className='formItem'>
  172. <View className='formName'>公出开始时间:</View>
  173. <View className='formValue'>
  174. <DateTimePicker ref={ref=>this.rangeStartRef = ref} onOk={(current)=>{
  175. let arr = [];
  176. if(this.state.rangeEndVal){
  177. if(dayjs(current.current).isAfter(dayjs(this.state.rangeEndMinuteVal))){
  178. Taro.showToast({title:'开始时间不能在结束时间之后',icon:'none'})
  179. this.rangeStartRef.clear();
  180. this.setState({
  181. rangeStartVal:'',
  182. rangeStartMinuteVal: '',
  183. validDates:[],
  184. totalDuration:0
  185. })
  186. return;
  187. }
  188. }
  189. if(this.state.rangeEndVal){
  190. let str = dayjs(current.current).format('YYYY-MM-DD');
  191. arr.push({value:str});
  192. let a = dayjs(this.state.rangeEndVal.split('-'));
  193. let b = dayjs(str.split('-'));
  194. let num = a.diff(b, 'days');
  195. let strAdd = str;
  196. for(let i = 0;i<num;i++){
  197. let time = dayjs(strAdd).add(1, 'days').format('YYYY-MM-DD');
  198. strAdd = time
  199. arr.push({value:time});
  200. }
  201. }
  202. this.setState({
  203. rangeStartVal:dayjs(current.current).format('YYYY-MM-DD'),
  204. rangeStartMinuteVal: dayjs(current.current).format('YYYY-MM-DD HH:mm:ss'),
  205. validDates:arr
  206. },()=>{
  207. if(this.state.rangeEndVal){
  208. let a1 = dayjs(dayjs(current.current).format('YYYY-MM-DD HH:mm:ss'));
  209. let b1 = dayjs(dayjs(this.state.rangeEndMinuteVal).format('YYYY-MM-DD HH:mm:ss'));
  210. this.getNumHourse(a1,b1)
  211. }
  212. })
  213. }} onClear={()=>{
  214. this.setState({
  215. rangeStartVal:'',
  216. rangeStartMinuteVal: '',
  217. validDates:[],
  218. totalDuration:0
  219. })
  220. }} initValue={dayjs().format('YYYY-MM-DD HH:mm:ss')} wrap-class="my-class" select-item-class="mySelector" />
  221. </View>
  222. </View>
  223. <View className='formItem'>
  224. <View className='formName'>公出结束时间:</View>
  225. <View className='formValue'>
  226. <DateTimePicker ref={ref=>this.rangeEndRef = ref} onOk={(current)=>{
  227. let arr = [];
  228. if(this.state.rangeStartVal){
  229. if(dayjs(current.current).isBefore(dayjs(this.state.rangeStartMinuteVal))){
  230. Taro.showToast({title:'结束时间不能在开始时间之前',icon:'none'})
  231. this.rangeEndRef.clear();
  232. this.setState({
  233. rangeEndVal:'',
  234. rangeEndMinuteVal: '',
  235. validDates:[],
  236. totalDuration:0
  237. })
  238. return;
  239. }
  240. }
  241. if(this.state.rangeStartVal){
  242. let str = dayjs(current.current).format('YYYY-MM-DD');
  243. arr.push({value:this.state.rangeStartVal});
  244. let a = dayjs(this.state.rangeStartVal.split('-'));
  245. let b = dayjs(str.split('-'));
  246. let num = b.diff(a, 'days');
  247. let strAdd = this.state.rangeStartVal;
  248. for(let i = 0;i<num;i++){
  249. let time = dayjs(strAdd).add(1, 'days').format('YYYY-MM-DD');
  250. strAdd = time
  251. arr.push({value:time});
  252. }
  253. }
  254. this.setState({
  255. rangeEndVal:dayjs(current.current).format('YYYY-MM-DD'),
  256. rangeEndMinuteVal: dayjs(current.current).format('YYYY-MM-DD HH:mm:ss'),
  257. validDates:arr,
  258. },()=>{
  259. if(this.state.rangeStartVal){
  260. let a1 = dayjs(dayjs(current.current).format('YYYY-MM-DD HH:mm:ss'));
  261. let b1 = dayjs(dayjs(this.state.rangeStartMinuteVal).format('YYYY-MM-DD HH:mm:ss'));
  262. this.getNumHourse(b1,a1)
  263. }
  264. })
  265. }} onClear={()=>{
  266. this.setState({
  267. rangeEndVal:'',
  268. rangeEndMinuteVal: '',
  269. validDates:[],
  270. totalDuration:0
  271. })
  272. }} initValue={dayjs().format('YYYY-MM-DD HH:mm:ss')} wrap-class="my-class" select-item-class="mySelector" />
  273. </View>
  274. </View>
  275. <View className='formItem'>
  276. <View className='formName'>总时长:</View>
  277. <View className='formValue'>
  278. {this.state.totalDuration}小时
  279. </View>
  280. </View>
  281. {this.state.validDates.length !== 0? <View className='formItem' style={{display:'block',paddingTop:'15px'}}>
  282. <View className='formName'>去除放假时间:</View>
  283. <AtCalendar
  284. currentDate={this.state.rangeStartVal}
  285. minDate={this.state.rangeStartVal}
  286. maxDate={this.state.rangeEndVal}
  287. isSwiper={false}
  288. validDates={this.state.validDates}
  289. onDayLongClick={(item)=>{
  290. if(!(dayjs(item.value.split('-')).isSame(this.state.rangeStartVal.split('-')) || dayjs(item.value.split('-')).isSame(this.state.rangeEndVal.split('-')))){
  291. if(!(dayjs(item.value.split('-')).isAfter(this.state.rangeStartVal.split('-')) && dayjs(item.value.split('-')).isBefore(this.state.rangeEndVal.split('-')))){
  292. return;
  293. }
  294. }else{
  295. Taro.showToast({title:'开始结束时间不能取消',icon:'none'})
  296. return
  297. }
  298. let index = this.state.validDates.findIndex(v=>{
  299. let lv = dayjs(v.value.split('-')).isSame(item.value.split('-'));
  300. return lv
  301. })
  302. if(index<0){
  303. let arr = item.value.split('-');
  304. this.state.validDates.push({value:arr.join('-')})
  305. this.setState({
  306. validDates:this.state.validDates,
  307. totalDuration: this.state.totalDuration + 7.5
  308. })
  309. }else{
  310. this.state.validDates.splice(index,1)
  311. this.setState({
  312. validDates:this.state.validDates,
  313. totalDuration: this.state.totalDuration - 7.5
  314. })
  315. }
  316. }}
  317. />
  318. </View> : null}
  319. <View className='formItem' style={{paddingBottom:0}}>
  320. <View className='formName'>公出地点:</View>
  321. <View className='formValue' onClick={this.selectArrder}>
  322. <Text className='formValueText'>{this.props.selectArrderLocation.name}</Text>
  323. <AtIcon value='chevron-right' size='30' color='#bbbbbb'/>
  324. </View>
  325. </View>
  326. <View className='tips'>打卡范围是以地图中红标为中心100米范围为可打卡范围,拖动地图可移动红标</View>
  327. <View className='formItem' style={{display:'block',paddingTop:'15px'}}>
  328. <View className='formName'>公出事由:</View>
  329. <View className='formValue' style={{paddingTop:'10px',textAlign:'left'}}>
  330. <AtTextarea
  331. value={this.state.reason}
  332. onChange={(v)=>{
  333. this.setState({
  334. reason:v
  335. })
  336. }}
  337. maxLength={200}
  338. placeholder='请输入公出事由'
  339. />
  340. </View>
  341. </View>
  342. <View className='formItem' style={{display:'block'}}>
  343. <View className='formName'>附件:</View>
  344. <View className='formValue' style={{paddingTop:'10px',textAlign:'left'}}>
  345. <ImagePicker
  346. showAddBtn={true}
  347. ref={ref => this.imagePickerRef = ref}
  348. url='/api/admin/release/upload'
  349. onChange={this.onChange}
  350. />
  351. </View>
  352. </View>
  353. <View className='operation'>
  354. <AtButton disabled={this.state.loading} type='secondary' circle onClick={()=>{
  355. Taro.eventCenter.trigger('enterpriseBack')
  356. }}>
  357. 上一步
  358. </AtButton>
  359. <AtButton type='primary' loading={this.state.loading} circle onClick={()=>{
  360. this.setState({
  361. isInquiryOpened:true,
  362. inquiryTitle:'提醒',
  363. inquiryContent:'您确定要提交此申请吗?',
  364. inquiryFn:()=>{
  365. this.onSubmit();
  366. }
  367. })
  368. }}>
  369. 提交申请
  370. </AtButton>
  371. </View>
  372. <InquiryModal
  373. isOpened={this.state.isInquiryOpened}
  374. title={this.state.inquiryTitle}
  375. content={this.state.inquiryContent}
  376. onClose={()=>{
  377. this.setState({
  378. isInquiryOpened:false,
  379. inquiryTitle:'',
  380. inquiryContent:'',
  381. })
  382. }}
  383. onDetermine={()=>{
  384. this.state.inquiryFn();
  385. this.setState({
  386. isInquiryOpened:false,
  387. inquiryTitle:'',
  388. inquiryContent:'',
  389. inquiryFn:()=>{}
  390. })
  391. }}
  392. />
  393. </View>
  394. )
  395. }
  396. }
  397. export default PublicContent;