ソースを参照

Merge branch 'master' of http://192.168.0.115:3000/shaogen1995/YW_Goods into master

shaogen1995 1 ヶ月 前
コミット
5054771a17

+ 2 - 2
public/index.html

@@ -12,8 +12,8 @@
 
     <script>
       // 域名地址
-      // const baseUrlTempOne = 'https://sit-yiwubwg.4dage.com'
-      const baseUrlTempOne = 'http://192.168.20.61:8096'
+      const baseUrlTempOne = 'https://sit-yiwubwg.4dage.com'
+      // const baseUrlTempOne = 'http://192.168.20.61:8096'
 
       // 钉钉模式
       const isDingTemp = false

BIN
public/templates/10.docx


BIN
public/templates/11.docx


BIN
public/templates/16.docx


BIN
public/templates/4.docx


+ 24 - 2
src/components/MyTable/index.tsx

@@ -13,6 +13,7 @@ import ImageLazy from '../ImageLazy'
 import classNames from 'classnames'
 import { resJiLianFu } from '@/utils/history'
 import { baseURL } from '@/utils/http'
+import dayjs from 'dayjs'
 
 interface MyTableProps extends Omit<TableProps, 'onChange'> {
   yHeight?: number //设置表格的高度
@@ -62,6 +63,19 @@ export const myTableTransferSize = (item: any) => {
   else return arr.join(' - ')
 }
 
+export const getDesensitizeTxt = (txt: string, frontLen = 3, endLen = 4) => {
+  if (!txt) return txt
+  const totalVisible = frontLen + endLen
+  if (txt.length <= totalVisible) {
+    return txt
+  }
+  const frontStr = txt.substring(0, frontLen)
+  const endStr = endLen > 0 ? txt.substring(txt.length - endLen) : ''
+  const maskStr = '*'.repeat(txt.length - frontLen - endLen)
+
+  return frontStr + maskStr + endStr
+}
+
 const MyTable = forwardRef<MyTableMethods, MyTableProps>(
   (
     {
@@ -164,8 +178,8 @@ const MyTable = forwardRef<MyTableMethods, MyTableProps>(
           ),
           // 日期去掉00:00:00
           dateRes: (item: any) => {
-            let res: string = item[v[2]] || isNull
-            return res.replace('00:00:00', '')
+            let res = item[v[2]] ? dayjs(item[v[2]]).format('YYYY-MM-DD') : isNull
+            return res
           },
           // 多个字段拼接
           ping: (item: any) => (item[v[2]] || '') + (resJiLianFu(item[v[3]]) || '') || isNull,
@@ -241,6 +255,14 @@ const MyTable = forwardRef<MyTableMethods, MyTableProps>(
                 {v[3].render(readOnly)}
               </Form.Item>
             )
+          },
+          desensitize: (item: any) => {
+            const txt = item[v[2]]
+            if (!txt) return isNull
+            const frontLen = v[3]?.frontLen || 3
+            const endLen = v[3]?.endLen || 4
+
+            return getDesensitizeTxt(txt, frontLen, endLen)
           }
         }
 

+ 18 - 9
src/pages/D_storeManage/D3staff/D3edit/index.tsx

@@ -27,6 +27,7 @@ import { D3STAFF_OUTSIDER_TABLE_COLUMNS } from '../constants'
 import { D2_APIgetList } from '@/store/action/D2storSet'
 import dayjs from 'dayjs'
 import { EXPORT_WORD_ENUM } from '@/utils/exportTemplates'
+import encodeStr, { decodeStr } from '@/utils/pass'
 
 export const pageTitTxtObj = {
   1: '新增',
@@ -63,7 +64,7 @@ function C21edit() {
     if (res.code === 0) {
       setTopInfo({
         ...res.data,
-        date: dayjs().format('YYYY-MM-DD')
+        date: dayjs().format('YYYY-MM-DD HH:mm:ss')
       })
     }
   }, [])
@@ -71,12 +72,16 @@ function C21edit() {
   // 获取详情
   const getInfoFu = useCallback(
     async (id2?: number) => {
-      const res = await D3_APIgetInfo(id2 || id)
-      if (res.code === 0) {
-        const { memberIds, sonTypeName } = res.data
-        setTopInfo(res.data)
-        setOversiderList(JSON.parse(memberIds || '') || [])
-        setCurTab(sonTypeName)
+      try {
+        const res = await D3_APIgetInfo(id2 || id)
+        if (res.code === 0) {
+          const { memberIds, sonTypeName } = res.data
+          setTopInfo(res.data)
+          setCurTab(sonTypeName)
+          setOversiderList(JSON.parse(decodeURIComponent(decodeStr(memberIds || ''))) || [])
+        }
+      } catch (err) {
+        console.log(err)
       }
     },
     [id]
@@ -150,7 +155,7 @@ function C21edit() {
         const obj = {
           ...topInfo,
           rtf: JSON.stringify(rtf1.val || ''),
-          memberIds: JSON.stringify(oversiderList),
+          memberIds: encodeStr(encodeURIComponent(JSON.stringify(oversiderList))),
           sonTypeName: curTab
         }
         // console.log(123, obj)
@@ -326,11 +331,12 @@ function C21edit() {
             </div>
             <div className='D4rowrr'>
               <DatePicker
+                showTime
                 disabled={pageDisabled}
                 defaultValue={dayjs(topInfo.date)}
                 style={{ width: '300px' }}
                 onChange={e => {
-                  setTopInfo({ ...topInfo, date: e.format('YYYY-MM-DD') })
+                  setTopInfo({ ...topInfo, date: e.format('YYYY-MM-DD HH:mm:ss') })
                 }}
               />
             </div>
@@ -535,6 +541,9 @@ function C21edit() {
         visible={outsiderVisible}
         setVisible={setOutsiderVisible}
         onOk={item => setOversiderList([...oversiderList, item])}
+        onCancel={() => {
+          setCheckedOversider(null)
+        }}
       />
     </div>
   )

+ 48 - 4
src/pages/D_storeManage/D3staff/components/OutsiderModal/index.tsx

@@ -7,14 +7,22 @@ export interface OutsiderModalProps {
   item: D3StaffOversiderType | null
   setVisible: (v: boolean) => void
   onOk: (item: D3StaffOversiderType) => void
+  onCancel?: () => void
 }
 
-export const OutsiderModal: FC<OutsiderModalProps> = ({ visible, item, setVisible, onOk }) => {
+export const OutsiderModal: FC<OutsiderModalProps> = ({
+  visible,
+  item,
+  setVisible,
+  onOk,
+  onCancel
+}) => {
   const [form] = Form.useForm()
 
   const handleCancel = () => {
     setVisible(false)
     form.resetFields()
+    onCancel?.()
   }
 
   const handleSubmit = async () => {
@@ -24,6 +32,42 @@ export const OutsiderModal: FC<OutsiderModalProps> = ({ visible, item, setVisibl
     handleCancel()
   }
 
+  // const validateIdCard = (_: any, value: string) => {
+  //   if (!value) return Promise.resolve()
+
+  //   // 身份证简单正则
+  //   const reg = /(^\d{15}$)|(^\d{17}(\d|X|x)$)/
+  //   if (!reg.test(value)) {
+  //     return Promise.reject('请输入正确的身份证号')
+  //   }
+
+  //   // 校验位验证(18位身份证)
+  //   if (value.length === 18) {
+  //     const weight = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2] // 加权因子
+  //     const validate = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'] // 校验码
+
+  //     let sum = 0
+  //     for (let i = 0; i < 17; i++) {
+  //       sum += parseInt(value.charAt(i)) * weight[i]
+  //     }
+
+  //     const mod = sum % 11
+  //     if (value.charAt(17).toUpperCase() !== validate[mod]) {
+  //       return Promise.reject('请输入正确的身份证号')
+  //     }
+  //   }
+
+  //   return Promise.resolve()
+  // }
+
+  const validatePhone = (_: any, value: string) => {
+    const reg = /^1[3-9]\d{9}$/
+    if (value && !reg.test(value)) {
+      return Promise.reject('请输入正确的手机号')
+    }
+    return Promise.resolve()
+  }
+
   useEffect(() => {
     if (!item) return
     form.setFieldsValue(item)
@@ -35,12 +79,12 @@ export const OutsiderModal: FC<OutsiderModalProps> = ({ visible, item, setVisibl
         <Form.Item label='姓名' required rules={[{ required: true }]} name='name'>
           <Input maxLength={30} placeholder='请输入' />
         </Form.Item>
-        <Form.Item label='联系方式' name='phone'>
+        <Form.Item label='联系方式' name='phone' rules={[{ validator: validatePhone }]}>
           <Input maxLength={30} placeholder='请输入' />
         </Form.Item>
-        <Form.Item label='身份证号' name='papers'>
+        {/* <Form.Item label='身份证号' name='papers' rules={[{ validator: validateIdCard }]}>
           <Input maxLength={30} placeholder='请输入' />
-        </Form.Item>
+        </Form.Item> */}
         <Form.Item label='所在单位' name='remark'>
           <Input maxLength={30} placeholder='请输入' />
         </Form.Item>

+ 3 - 3
src/pages/D_storeManage/D3staff/constants.ts

@@ -11,7 +11,7 @@ export const D3STAFF_PARAM_ROWS2: D3StaffSearchType[] = [
 
 export const D3STAFF_TABLE_COLUMNS = [
   ['txt', '业务编号', 'num'],
-  ['txt', '入库时间', 'name'],
+  ['dateRes', '入库时间', 'date'],
   ['txtChange', '入库人员', 'sonTypeName', sonTypeNameObj],
   ['txt', '入库事由', 'reason'],
   ['txt', '相关库房', 'storageName'],
@@ -23,8 +23,8 @@ export const D3STAFF_TABLE_COLUMNS = [
 
 export const D3STAFF_OUTSIDER_TABLE_COLUMNS = [
   ['txt', '姓名', 'name'],
-  ['txt', '联系方式', 'phone'],
-  ['txt', '身份证号', 'papers'],
+  ['desensitize', '联系方式', 'phone'],
+  // ['txt', '身份证号', 'papers'],
   ['txt', '所在单位', 'remark']
 ]
 

+ 1 - 1
src/pages/D_storeManage/D3staff/index.tsx

@@ -256,7 +256,7 @@ function D3staff() {
 
   return (
     <div className={styles.D3staff}>
-      <div className='pageTitle'>资源使用</div>
+      <div className='pageTitle'>人员出入库</div>
 
       {/* 第一行 */}
       <div className='C1top'>

+ 1 - 1
src/pages/F_exhibition/F1exhibition/constants.ts

@@ -28,7 +28,7 @@ export const F1_SON_TYPE_OBJ = {
   [F1_SON_TYPE_ENUM.OUT]: '馆外展览'
 }
 export const F1_SON_TYPE_NAME_OBJ = {
-  [F1_SON_TYPE_NAME_ENUM.FIXED]: '固定展览',
+  [F1_SON_TYPE_NAME_ENUM.FIXED]: '常设展览',
   [F1_SON_TYPE_NAME_ENUM.TEMP]: '临时展览',
   [F1_SON_TYPE_NAME_ENUM.THEME]: '主题展览'
 }

+ 16 - 11
src/utils/exportTemplates.ts

@@ -7,11 +7,12 @@ import {
   arrangeImages,
   calcTablePages,
   getExcelColumnLetter,
+  getImageUrlsFromHtml,
   ITEMPLATE,
   numberToChinese,
   removeHtmlTags
 } from './exportWordUtils'
-import { myTableTransferSize } from '@/components/MyTable'
+import { getDesensitizeTxt, myTableTransferSize } from '@/components/MyTable'
 import dayjs from 'dayjs'
 import { D7CEHCK_COLLECTION_RESULT_OPTIONS } from '@/pages/D_storeManage/D7check/constants'
 import { exportTempExcel, getImageBase64Extension } from './exportExcelUtils'
@@ -494,9 +495,7 @@ export const exportWordHandler = async (type: EXPORT_WORD_ENUM, data: Record<any
     case EXPORT_WORD_ENUM.COLLECTION_INVENTORY:
       temp = {
         ...temp,
-        year: date.format('YYYY'),
-        month: date.format('MM'),
-        day: date.format('DD')
+        sonNum2: dayjs(temp.date).format('YYYY') + temp.num
       }
       temp.goods.forEach((i: any) => {
         i.checker = i.cusForm[`${i.id}-checker`]
@@ -538,16 +537,14 @@ export const exportWordHandler = async (type: EXPORT_WORD_ENUM, data: Record<any
       temp = {
         ...temp,
         sonSource: resJiLianFu(temp.sonSource),
-        createTime: dayjs(temp.createTime).format('YYYY年MM月DD日')
+        sonNum2: dayjs(temp.date).format('YYYY') + temp.num,
+        date: dayjs(temp.date).format('YYYY年MM月DD日')
       }
       break
     case EXPORT_WORD_ENUM.COLLECTION_RELOCATION:
-      console.log(temp.goods)
       temp = {
         ...temp,
-        year: date.format('YYYY'),
-        month: date.format('MM'),
-        day: date.format('DD'),
+        sonNum2: dayjs(temp.date).format('YYYY') + temp.num,
         date: dayjs(temp.date).format('YYYY年MM月DD日')
       }
       break
@@ -591,17 +588,25 @@ export const exportWordHandler = async (type: EXPORT_WORD_ENUM, data: Record<any
         members: memberss.map((i: any) => i.name),
         companys: memberss.map((i: any) => i.remark || '空'),
         idCards: memberss.map((i: any) => i.papers || '空'),
-        phones: memberss.map((i: any) => i.phone || '空')
+        phones: memberss.map((i: any) => (i.phone ? getDesensitizeTxt(i.phone) : '空'))
       }
       break
     case EXPORT_WORD_ENUM.RELIC_REPAIR_LIST:
     case EXPORT_WORD_ENUM.COLLECTION_CURRENT_STATUS:
       const ___date = dayjs(temp.date)
+      const rtf = JSON.parse(temp.rtf).txtArr[0].txt
+      const stack = []
+      try {
+        for (const url of getImageUrlsFromHtml(rtf)) {
+          stack.push(await getBase64Sync(url))
+        }
+      } catch (err) {}
       temp = {
         ...temp,
         year: ___date.format('YYYY'),
         page,
-        rtf: removeHtmlTags(JSON.parse(temp.rtf).txtArr[0].txt)
+        rtf: removeHtmlTags(rtf),
+        imgs: stack
       }
       break
     case EXPORT_WORD_ENUM.COLLECTION_LIST:

+ 12 - 0
src/utils/exportWordUtils.ts

@@ -192,6 +192,18 @@ export const removeHtmlTags = (html: string) => {
     .trim() // 去除首尾空格
 }
 
+export const getImageUrlsFromHtml = (htmlString: string) => {
+  const imgRegex = /<img[^>]+src="([^">]+)"/g
+  const urls: string[] = []
+  let match
+
+  while ((match = imgRegex.exec(htmlString)) !== null) {
+    urls.push(match[1])
+  }
+
+  return urls
+}
+
 export const getExcelColumnLetter = (index: number) => {
   let result = ''
   let remaining = index

+ 94 - 85
src/utils/pass.ts

@@ -1,100 +1,109 @@
 function randomWord(randomFlag: boolean, min: number, max: number = 15) {
-  let str = "";
-  let range = min;
+  let str = ''
+  let range = min
   const arr = [
-    "0",
-    "1",
-    "2",
-    "3",
-    "4",
-    "5",
-    "6",
-    "7",
-    "8",
-    "9",
-    "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',
+    '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'
+  ]
   // 随机产生
   if (randomFlag) {
-    range = Math.round(Math.random() * (max - min)) + min;
+    range = Math.round(Math.random() * (max - min)) + min
   }
   for (var i = 0; i < range; i++) {
-    const pos = Math.round(Math.random() * (arr.length - 1));
-    str += arr[pos];
+    const pos = Math.round(Math.random() * (arr.length - 1))
+    str += arr[pos]
   }
-  return str;
+  return str
 }
 
-const encodeStr = (str: string, strv = "") => {
-  const NUM = 2;
-  const front = randomWord(false, 8);
-  const middle = randomWord(false, 8);
-  const end = randomWord(false, 8);
+const encodeStr = (str: string, strv = '') => {
+  const NUM = 2
+  const front = randomWord(false, 8)
+  const middle = randomWord(false, 8)
+  const end = randomWord(false, 8)
 
-  const str1 = str.substring(0, NUM);
-  const str2 = str.substring(NUM);
+  const str1 = str.substring(0, NUM)
+  const str2 = str.substring(NUM)
 
   if (strv) {
-    const strv1 = strv.substring(0, NUM);
-    const strv2 = strv.substring(NUM);
-    return [
-      front + str2 + middle + str1 + end,
-      front + strv2 + middle + strv1 + end,
-    ];
+    const strv1 = strv.substring(0, NUM)
+    const strv2 = strv.substring(NUM)
+    return [front + str2 + middle + str1 + end, front + strv2 + middle + strv1 + end]
   }
 
-  return front + str2 + middle + str1 + end;
-};
+  return front + str2 + middle + str1 + end
+}
+
+export const decodeStr = (encodedStr: string, NUM: number = 2) => {
+  // 移除前后各8字符的前后缀
+  const content = encodedStr.substring(8, encodedStr.length - 8)
+
+  // 中间部分由 str2 + middle + str1 组成
+  // middle也是固定8字符
+  const str2 = content.substring(0, content.length - 8 - NUM)
+  const str1 = content.substring(content.length - NUM)
+
+  return str1 + str2
+}
 
-export default encodeStr;
+export default encodeStr