Sfoglia il codice sorgente

feat: 自动编号功能。ok

lanjianrong 4 anni fa
parent
commit
a0579097f9

+ 37 - 0
src/assets/css/common.scss

@@ -427,3 +427,40 @@
 .my-3 {
   margin-top: 1rem;
 }
+
+.pi-table {
+  width: 100%;
+  margin-bottom: 1rem;
+  color: #212529;
+  & > thead th {
+    vertical-align: bottom;
+    border-bottom: 2px solid #dee2e6;
+  }
+  & > tbody td,
+  & > thead td,
+  & > tbody th,
+  & > thead th {
+    padding: 0.3rem;
+    vertical-align: top;
+  }
+
+  & > tbody th,
+  & > thead th {
+    background: #e9ecef;
+    font-weight: normal;
+    color: #000;
+  }
+}
+
+.pi-bordered {
+  border: 1px solid #dee2e6;
+  & > tbody td,
+  & > thead td,
+  & > tbody th,
+  & > thead th {
+    border: 1px solid #dee2e6;
+  }
+  & > thead th {
+    border-bottom-width: 2px;
+  }
+}

+ 55 - 0
src/components/Button/index.module.scss

@@ -50,3 +50,58 @@
     border-color: #6c757d;
   }
 }
+
+.submitButton {
+  :global(.ant-btn) {
+    color: #ffffff;
+    background-color: #1e7e34;
+    border-color: #1c7430;
+  }
+  :global(.ant-btn:hover) {
+    background-color: #218838;
+    border-color: #1e7e34;
+  }
+  :global(.ant-btn:focus) {
+    background-color: #218838;
+    border-color: #1e7e34;
+  }
+  :global(.ant-btn:active) {
+    background-color: #218838;
+    border-color: #1e7e34;
+  }
+
+  :global(.ant-btn:not(:hover)) {
+    color: #ffffff;
+    background-color: #1e7e34;
+    border-color: #1c7430;
+  }
+}
+
+.uploadButton {
+  :global(.ant-btn) {
+    color: #007bff;
+    background-color: #f8f9fa;
+    border-color: #f8f9fa;
+  }
+  :global(.ant-btn:hover) {
+    color: #0056b3;
+    background-color: #dae0e5;
+    border-color: #d3d9df;
+  }
+  :global(.ant-btn:focus) {
+    color: #0056b3;
+    background-color: #dae0e5;
+    border-color: #d3d9df;
+  }
+  :global(.ant-btn:active) {
+    color: #0056b3;
+    background-color: #dae0e5;
+    border-color: #d3d9df;
+  }
+
+  :global(.ant-btn:not(:hover)) {
+    color: #007bff;
+    background-color: #f8f9fa;
+    border-color: #f8f9fa;
+  }
+}

+ 10 - 1
src/components/Button/index.tsx

@@ -10,8 +10,17 @@ const ZhCloseButton:React.FC<ButtonProps> = props => {
   return <div className={styles.closeButton}><Button {...props}></Button></div>
 }
 
+const ZhSubmitButton:React.FC<ButtonProps> = props => {
+  return <div className={styles.submitButton}><Button {...props}></Button></div>
+}
+
+const ZhUploadButton:React.FC<ButtonProps> = props => {
+  return <div className={styles.uploadButton}><Button {...props} type="text"></Button></div>
+}
 export {
   ZhButton,
-  ZhCloseButton
+  ZhCloseButton,
+  ZhSubmitButton,
+  ZhUploadButton
 }
 

+ 1 - 0
src/components/LeftSide/index.tsx

@@ -11,6 +11,7 @@ const leftSide:React.FC<iNavSide> = ({ childRoutes, location }) => {
     tenderStore.saveBidsectionId(location.state?.id)
   }
   const pathname = location.pathname
+
   return (
     <div className={userStore.showLeftSide ? "panel-sidebar" : "scale-out-hor-left"}>
       <div>

+ 6 - 5
src/components/RuleModal/index.tsx

@@ -7,7 +7,6 @@ import { dayjsFomrat } from '@/utils/util'
 import { Form, Input, InputNumber, Modal, Select, Tabs, Tag } from 'antd'
 import { TweenOneGroup } from 'rc-tween-one'
 import React, { useEffect, useState } from 'react'
-import { useActivate } from 'react-activation'
 import styles from './index.module.scss'
 const { TabPane } = Tabs
 const { Option } = Select
@@ -77,7 +76,7 @@ const SafeCreateForm: React.FC<iSafeCreateFormProps> = ({
   const [ ruleArr, setRuleArr ] = useState<ruleOption[]>([])
   useEffect(() => {
     form.setFieldsValue({ bidsectionId: tenderStore.bidsectionId })
-  }, [ tenderStore.bidsectionId ])
+  }, [ visible, type ])
   const ruleHandler = () => {
     switch (ruleType) {
       case '0':
@@ -129,9 +128,11 @@ const SafeCreateForm: React.FC<iSafeCreateFormProps> = ({
   }
 
   useEffect(() => {
-    ruleModalIniter()
-  }, [])
-  useActivate(() => ruleModalIniter())
+    if (visible) {
+      ruleModalIniter()
+    }
+  }, [ visible, type ])
+  // useActivate(() => ruleModalIniter())
   return (
     <Modal
       getContainer={false}

+ 1 - 32
src/components/SvgIcon/index.tsx

@@ -1,36 +1,5 @@
 import { createFromIconfontCN } from '@ant-design/icons'
-// import './index.scss'
-// type svgProps = {
-//   iconClass: string,
-//   fontSize: string,
-//   fill: string
-//   transform?: string
-// } & typeof defaultProps
-
-// const defaultProps = {
-//   fill: 'currentColor',
-//   fontSize: '14'
-// }
-// const SvgIcon = (props: svgProps) => {
-//   const { iconClass, fontSize, fill } = props
-//   const svg = require(`@/assets/icons/svg/${iconClass}.svg`)
-//   const styleObj = {
-//     fontSize: fontSize + 'px',
-//     minWidth: fontSize + 'px'
-//   }
-//   return (
-//     <span aria-hidden="true" className="svg-icon">
-//       <svg className='svg-class' style={styleObj} fill={fill} >
-//         <use xlinkHref={"#icon-" + iconClass}  transform={ props.transform ? props.transform : ''}/>
-//       </svg>
-//     </span>
-//   )
-// }
-// SvgIcon.defaultProps = defaultProps
-// export default SvgIcon
-
-
 const IconFont = createFromIconfontCN({
-  scriptUrl: '//at.alicdn.com/t/font_2224180_dpzddostful.js'
+  scriptUrl: '//at.alicdn.com/t/font_2224180_82mpoja7619.js'
 })
 export default IconFont

+ 48 - 0
src/pages/Safe/Content/Detail/index.module.scss

@@ -0,0 +1,48 @@
+.detailContainer {
+  width: 100%;
+  margin: 0 auto;
+  .content {
+    flex: 0 0 66.666667%;
+    max-width: 66.666667%;
+    margin: 0 auto;
+    .header {
+      margin: 1rem 0;
+      font-size: 1.5rem;
+      font-weight: 500;
+      line-height: 1.2;
+      text-align: center;
+    }
+    .table {
+      width: 100%;
+      margin-bottom: 1rem;
+      color: #212529;
+      border-collapse: collapse;
+      border: 1px solid #dee2e6;
+      & > tbody td,
+      & > thead td {
+        padding: 0.3rem;
+        vertical-align: top;
+        border: 1px solid #dee2e6;
+      }
+      & > tbody th,
+      & > thead th {
+        padding: 0.3rem;
+        font-weight: normal;
+        color: #000000;
+        vertical-align: top;
+        background: #e9ecef;
+        border: 1px solid #dee2e6;
+      }
+
+      & > thead th {
+        vertical-align: bottom;
+        border-bottom: 2px solid #dee2e6;
+        border-bottom-width: 2px;
+      }
+
+      & > tbody th {
+        width: 150px;
+      }
+    }
+  }
+}

+ 63 - 4
src/pages/Safe/Content/Detail/index.tsx

@@ -1,9 +1,68 @@
+import { ZhSubmitButton, ZhUploadButton } from '@/components/Button'
+import DatePicker from '@/components/DatePicker'
+import Header from '@/components/Header'
+import Slot from '@/components/Header/slot'
+import SvgIcon from '@/components/SvgIcon'
+import { dayjsFomrat } from '@/utils/util'
+import { Button, Input, Tooltip } from 'antd'
+import locale from 'antd/es/date-picker/locale/zh_CN'
 import React from 'react'
-
-export default function index() {
+import styles from './index.module.scss'
+const Detail:React.FC<{}> = () => {
   return (
-    <div>
-      巡检审批详情页
+    <div className="wrap-contaniner">
+      <Header title="安全巡检">
+        <Slot position="right">
+          <div>
+            <ZhSubmitButton size="small">提交审批</ZhSubmitButton>
+          </div>
+        </Slot>
+      </Header>
+      <div className={styles.detailContainer}>
+        <div className={styles.content}>
+          <h4 className={styles.header}>WC-202008-0001</h4>
+          <table className="pi-table pi-bordered">
+            <thead>
+              <tr>
+                <th colSpan={2} className="pi-text-center">安全巡检单</th>
+              </tr>
+            </thead>
+            <tbody>
+              <tr><th style={{ width: "150px" }}>检查项目</th><td><Input.TextArea></Input.TextArea></td></tr>
+              <tr><th style={{ width: "150px" }}>现场检查情况</th><td><Input.TextArea></Input.TextArea></td></tr>
+              <tr><th style={{ width: "150px" }}>处理要求及措施</th><td><Input.TextArea></Input.TextArea></td></tr>
+              <tr><th style={{ width: "150px" }}>检查日期</th><td><DatePicker size="small" locale={locale} allowClear></DatePicker></td></tr>
+              <tr><th style={{ width: "150px" }}>质检员</th><td>布尔</td></tr>
+            </tbody>
+          </table>
+          <table className="pi-table pi-bordered mt-3">
+            <thead>
+              <tr>
+                <th></th>
+                <th className="pi-text-center">附件</th>
+                <th className="pi-text-center">上传者</th>
+                <th className="pi-text-center" style={{ width: 200 }}>上传时间</th>
+                <th className="pi-text-center">操作</th>
+              </tr>
+            </thead>
+            <tbody>
+              <tr><td colSpan={5}><ZhUploadButton size="small" icon={<SvgIcon type="xxh-cloud-upload"/>}>上传附件</ZhUploadButton></td></tr>
+              <tr>
+                <td style={{ width: 70 }}>1</td>
+                <td><span className="pi-link-blue">安全检查附件.pdf</span></td>
+                <td className="pi-text-center">布尔</td><td className="pi-text-center">{dayjsFomrat("2020-08-01 13:21:33")}</td>
+                <td style={{ width: 90 }} className="pi-text-center">
+                  <Tooltip title="移除">
+                    <Button size="small" type="text" icon={<SvgIcon type="xxh-times-circle1"/>} style={{ color: "#df3f45" }}></Button>
+                  </Tooltip>
+                </td>
+              </tr>
+            </tbody>
+          </table>
+        </div>
+      </div>
     </div>
   )
 }
+
+export default Detail

+ 10 - 0
src/pages/Safe/Content/List/index.module.scss

@@ -1,5 +1,9 @@
 .SafeModalForm {
+  position: relative;
+  top: 0;
+  left: 0;
   :global(.ant-input-group-addon) {
+    padding: 0;
     &:hover {
       color: #ffffff;
       background-color: #6c757d;
@@ -18,6 +22,12 @@
     }
   }
 
+  .position {
+    position: absolute;
+    top: 0;
+    right: 0;
+    z-index: 100;
+  }
   .warningFooter {
     padding: 0.5rem;
     color: #856404;

+ 6 - 1
src/pages/Safe/Content/List/index.tsx

@@ -148,7 +148,12 @@ const SafeList:React.FC<{}> =() => {
     <div className="wrap-contaniner">
       <Header title="巡检概况">
         <Slot position="right">
-          <Button type="ghost" size="small" icon={<SettingOutlined />} className="pi-mg-right-3" style={{ color: '#007bff' }} onClick={() => setRuleModal({ ...ruleModal, visible: true })}>设置</Button>
+          {
+            !list.length ?
+            <Button type="ghost" size="small" icon={<SettingOutlined />} className="pi-mg-right-3" style={{ color: '#007bff' }} onClick={() => setRuleModal({ ...ruleModal, visible: true })}>设置</Button>
+            : ""
+          }
+
           <Button type="primary" size="small" onClick={() => setAddModal({ ...addModal, visible: true })}>新建巡检</Button>
         </Slot>
       </Header>

+ 9 - 8
src/pages/Safe/Content/List/modal.tsx

@@ -39,8 +39,11 @@ const SafeCreateForm: React.FC<iSafeCreateFormProps> = ({
     }
   }
   useEffect(() => {
-    form.setFieldsValue({ bidsectionId: tenderStore.bidsectionId })
-  }, [])
+    if (visible) {
+      form.setFieldsValue({ bidsectionId: tenderStore.bidsectionId })
+    }
+
+  }, [ visible ])
   return (
     <Modal
       getContainer={false}
@@ -68,15 +71,13 @@ const SafeCreateForm: React.FC<iSafeCreateFormProps> = ({
         <Form.Item name="bidsectionId" hidden>
           <Input />
         </Form.Item>
-        <Form.Item
-          name="position"
-          label="部位"
-          rules={[ { required: true, message: '请选择' } ]}
-        >
+        <span className={[ styles.position, "pi-link-blue" ].join(" ")}>部位设置</span>
+        <Form.Item name="position" label="部位" rules={[ { required: true, message: '请选择' } ]}>
+          {/* <span className={[ styles.position, "pi-link-blue" ].join(" ")}>部位设置</span> */}
           <Input />
         </Form.Item>
         <Form.Item name="code" label="安全编号" rules={[ { required: true, message: '请输入/生成安全编号' } ]}>
-          <Input addonAfter={<span onClick={() => autoCodeHandler()}>自动编号</span>}/>
+          <Input addonAfter={<span className="pi-pd-lr-11"onClick={() => autoCodeHandler()}>自动编号</span>}/>
         </Form.Item>
         <Form.Item name="inspection" label="检查项" rules={[ { required: true, message: '请填写检查项' } ]}>
           <Input placeholder="请填写巡检项"/>

+ 1 - 0
src/pages/Safe/Content/index.tsx

@@ -5,6 +5,7 @@ import React from 'react'
 import { Switch } from 'react-router-dom'
 const Content:React.FC<NavigationGuardsProps> = props => {
   const { routeConfig, match, location } = props
+
   return (
     <>
       <LeftSide childRoutes={routeConfig} location={location}></LeftSide>

+ 17 - 3
src/utils/util.ts

@@ -71,7 +71,7 @@ const debounce = (fn: Function, delay: number) => {
  * 将子组件路径还原成带前缀的路径
  * @param parentPath - 父组件路径
  * @param pathOfTargetConfig - 用户希望访问的组件的在路由配置信息中填写的路径
- * @returns {string} 拼接后的path
+ * @returns 拼接后的path
  */
 const combinationPath = (parentPath: string|undefined, pathOfTargetConfig: string): string => {
   let combinedPath = !pathOfTargetConfig.startsWith('/') ? `/${pathOfTargetConfig}` : pathOfTargetConfig
@@ -81,12 +81,25 @@ const combinationPath = (parentPath: string|undefined, pathOfTargetConfig: strin
 
 /**
  * 日期格式化
- * @param {String} format - 格式
+ * @param format - 格式
  */
 const dayjsFomrat = (date: dayjs.ConfigType, format: string = 'YYYY-MM-DD HH:mm:ss') => {
   return dayjs(date).format(format)
 }
 
+/**
+ * 生成随机密码
+ * @param len - 长度
+ */
+const generatePsw = (len: number): string => {
+  const pasArr = [ 'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','0','1','2','3','4','5','6','7','8','9','_','-','$','%','&','@','+','!' ]
+  let password = ""
+  for (let i=0; i<len; i++){
+    const x = Math.floor(Math.random()*pasArr.length)
+    password += pasArr[x]
+  }
+  return password
+}
 
 export {
   getCookie,
@@ -94,6 +107,7 @@ export {
   throttle,
   debounce,
   combinationPath,
-  dayjsFomrat
+  dayjsFomrat,
+  generatePsw
 }