commit d33c9cc7d3403895f8dcacdfa459cafa18243bfe Author: linxd <544554903@qq.com> Date: Mon Jun 16 09:25:19 2025 +0800 Initial commit diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..8e90ca6 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,35 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +**/node_modules +/src/utils/request-temp.js + +# production +/.vscode + +# misc +.DS_Store +npm-debug.log* +yarn-error.log + +/coverage +.idea +yarn.lock +package-lock.json +*bak +.vscode + +# visual studio code +.history +*.log + +functions/mock +.temp/** + +# umi +.umi +.umi-production + +# screenshot +screenshot +.firebase \ No newline at end of file diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..7e3649a --- /dev/null +++ b/.editorconfig @@ -0,0 +1,16 @@ +# http://editorconfig.org +root = true + +[*] +indent_style = space +indent_size = 2 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[*.md] +trim_trailing_whitespace = false + +[Makefile] +indent_style = tab diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..16116a2 --- /dev/null +++ b/.eslintignore @@ -0,0 +1,4 @@ +/lambda/ +/scripts +/config +.history \ No newline at end of file diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 0000000..56160f6 --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,20 @@ +module.exports = { + extends: [require.resolve('@umijs/fabric/dist/eslint')], + globals: { + ANT_DESIGN_PRO_ONLY_DO_NOT_USE_IN_YOUR_PRODUCTION: true, + page: true, + REACT_APP_ENV: true, + //商城2.0跳转地址 + REACT_APP_MALL_V2_URL: false, + //各系统跳转参数 + REACT_APP_CLIENT_KEY: true, + // REACT_APP_CLIENT_SECRET: true, + //密码加密参数 + REACT_APP_PASSWORD_CIPHERMODE: true, + REACT_APP_PASSWORD_PUBLICKEY: true, + //当前环境 + START_ENV: true, + //询价查看报价跳转地址 + REACT_APP_XUNJIA_REDIRECT: true, + }, +}; diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7fd9f58 --- /dev/null +++ b/.gitignore @@ -0,0 +1,40 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +**/node_modules +# roadhog-api-doc ignore +/src/utils/request-temp.js +_roadhog-api-doc + +# production +/dist +/.vscode + +# misc +.DS_Store +npm-debug.log* +yarn-error.log + +/coverage +.idea +yarn.lock +package-lock.json +*bak +.vscode + +# visual studio code +.history +*.log +functions/* +.temp/** + +# umi +.umi +.umi-production + +# screenshot +screenshot +.firebase +.eslintcache + +build diff --git a/.gitpod.yml b/.gitpod.yml new file mode 100644 index 0000000..32d8e64 --- /dev/null +++ b/.gitpod.yml @@ -0,0 +1,6 @@ +ports: + - port: 8000 + onOpen: open-preview +tasks: + - init: npm install + command: npm start diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..d17efb4 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,23 @@ +**/*.svg +package.json +.umi +.umi-production +/dist +.dockerignore +.DS_Store +.eslintignore +*.png +*.toml +docker +.editorconfig +Dockerfile* +.gitignore +.prettierignore +LICENSE +.eslintcache +*.lock +yarn-error.log +.history +CNAME +/build +/public \ No newline at end of file diff --git a/.prettierrc.js b/.prettierrc.js new file mode 100644 index 0000000..7b597d7 --- /dev/null +++ b/.prettierrc.js @@ -0,0 +1,5 @@ +const fabric = require('@umijs/fabric'); + +module.exports = { + ...fabric.prettier, +}; diff --git a/.stylelintrc.js b/.stylelintrc.js new file mode 100644 index 0000000..c203078 --- /dev/null +++ b/.stylelintrc.js @@ -0,0 +1,5 @@ +const fabric = require('@umijs/fabric'); + +module.exports = { + ...fabric.stylelint, +}; diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..2b4571c --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,46 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment include: + +- Using welcoming and inclusive language +- Being respectful of differing viewpoints and experiences +- Gracefully accepting constructive criticism +- Focusing on what is best for the community +- Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +- The use of sexualized language or imagery and unwelcome sexual attention or advances +- Trolling, insulting/derogatory comments, and personal or political attacks +- Public or private harassment +- Publishing others' private information, such as a physical or electronic address, without explicit permission +- Other conduct which could reasonably be considered inappropriate in a professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at afc163@gmail.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] + +[homepage]: http://contributor-covenant.org +[version]: http://contributor-covenant.org/version/1/4/ diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..c17ba2f --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019 Alipay.inc + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/azure-pipelines.yml b/azure-pipelines.yml new file mode 100644 index 0000000..3c30244 --- /dev/null +++ b/azure-pipelines.yml @@ -0,0 +1,87 @@ +# Node.js +# Build a general Node.js project with npm. +# Add steps that analyze code, save build artifacts, deploy, and more: +# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript +name: ant design pro + +trigger: + - master + +jobs: + - job: lintAndBuild + + pool: + vmImage: 'Ubuntu-16.04' + + steps: + - checkout: self + clean: false + - script: npm install + displayName: install + - script: npm run lint + displayName: lint + - script: npm run tsc + displayName: tsc + - script: npm run build + env: + PROGRESS: none + displayName: build + + - job: test + pool: + vmImage: 'Ubuntu-16.04' + + container: + image: circleci/node:latest-browsers + options: '-u root' + + steps: + - script: npm install + displayName: install + - script: npm run test:all + env: + PROGRESS: none + UMI_UI: none + displayName: test + + - job: Windows + pool: + vmImage: 'windows-latest' + steps: + - task: NodeTool@0 + inputs: + versionSpec: '12.x' + - script: npm install + displayName: install + - script: npm run lint + displayName: lint + - script: npm run tsc + displayName: tsc + - script: npm run test:all + env: + PROGRESS: none + UMI_UI: none + displayName: test + - script: npm run build + env: + PROGRESS: none + displayName: build + + - job: MacOS + pool: + vmImage: 'macOS-latest' + steps: + - task: NodeTool@0 + inputs: + versionSpec: '12.x' + - script: npm install + displayName: install + - script: npm run lint + displayName: lint + - script: npm run tsc + displayName: tsc + - script: npm run + env: + PROGRESS: none + UMI_UI: none + displayName: build diff --git a/config/config.UAT.ts b/config/config.UAT.ts new file mode 100644 index 0000000..a022290 --- /dev/null +++ b/config/config.UAT.ts @@ -0,0 +1,45 @@ +import { defineConfig } from 'umi'; +import proxy from './proxy'; +export default defineConfig({ + proxy: proxy['UAT'], + define:{ + //商城2.0跳转地址 + REACT_APP_MALL_V2_URL:'http://111.198.162.67/zglt/index_hzf.jsp?id=dev', + + //各系统跳转参数 + REACT_APP_CLIENT_KEY : 'KgPEkttG', + // REACT_APP_CLIENT_SECRET :'ae5bdb183c502355d2055b3de73300aa73cbfdf3', + + //密码加密参数 + REACT_APP_PASSWORD_CIPHERMODE:'1', + REACT_APP_PASSWORD_PUBLICKEY:'0428D625CEEB71CE823BD7D78DFEE7B122F2DA5C4D21E32253AD684D0FE21810394A799639C0CDFBFEB535A1DFD6A366A637E582CE0B1466A5FE7858841135DE6B', + + //当前环境 + START_ENV:'UAT', + + //询价查看报价跳转地址 + // REACT_APP_XUNJIA_REDIRECT: 'http://10.0.204.215:8280/provider_uat', + //询价-查看报价详情-虚拟用户uid + REACT_APP_XUNJIA_UID: 'admin_entrance', + + // //智慧客服ws地址 + // REACT_APP_CUSTOMERSERVICE_WS_REDIRECT: 'ws://10.242.31.158:18022/api/api/biz-customer-service', + + //智慧客服用户中心地址 + REACT_APP_CUSTOMERSERVICE_USERCENTER: 'http://10.242.31.158:18022/auth/oauth/authorize?response_type=code', + + //智慧客服client_id + REACT_APP_CUSTOMERSERVICE_CLIENT_ID: 'COsHJydx', + + //智慧客服地址 + REACT_APP_CUSTOMERSERVICE_REDIRECT: 'http://10.242.31.158:8632', + + // //智慧客服文档中心查看图片地址 + // REACT_APP_CUSTOMERSERVICE_DOC_REDIRECT: 'http://cos.gz-tst.cos.tg.unicom.local/349553515466:mall/', + + // //智慧客服加密公钥私钥ciphercode + // REACT_APP_CUSTOMERSERVICE_PUBLICKEY : '0428D625CEEB71CE823BD7D78DFEE7B122F2DA5C4D21E32253AD684D0FE21810394A799639C0CDFBFEB535A1DFD6A366A637E582CE0B1466A5FE7858841135DE6B', + // REACT_APP_CUSTOMERSERVICE_PRIVATEKEY : '4F7144028D4DCF88FA50F0E2B3FFDDCF63BBE17D1700537DCE037687D3AA3DA7', + // REACT_APP_CUSTOMERSERVICE_CIPHERCODE : 1, + }, +}); diff --git a/config/config.dev.ts b/config/config.dev.ts new file mode 100644 index 0000000..d7f0893 --- /dev/null +++ b/config/config.dev.ts @@ -0,0 +1,45 @@ +import { defineConfig } from 'umi'; +import proxy from './proxy'; +export default defineConfig({ + proxy: proxy['dev'], + define: { + //商城2.0跳转地址 + REACT_APP_MALL_V2_URL: 'http://111.198.162.67/zglt/index_hzf.jsp?id=dev', + + //各系统跳转参数 + REACT_APP_CLIENT_KEY: 'KgPEkttG', + // REACT_APP_CLIENT_SECRET: 'ae5bdb183c502355d2055b3de73300aa73cbfdf3', + + //密码加密参数 + REACT_APP_PASSWORD_CIPHERMODE: '1', + REACT_APP_PASSWORD_PUBLICKEY: '0428D625CEEB71CE823BD7D78DFEE7B122F2DA5C4D21E32253AD684D0FE21810394A799639C0CDFBFEB535A1DFD6A366A637E582CE0B1466A5FE7858841135DE6B', + + //当前环境 + START_ENV: 'DEV', + + //询价查看报价跳转地址 + // REACT_APP_XUNJIA_REDIRECT: 'http://10.0.204.215:8080/provider_dev', + //询价-查看报价详情-虚拟用户uid + REACT_APP_XUNJIA_UID: 'admin_entrance', + + //智慧客服用户中心地址 + REACT_APP_CUSTOMERSERVICE_USERCENTER: 'http://10.242.31.158:8100/auth/oauth/authorize?response_type=code', + + //智慧客服client_id + REACT_APP_CUSTOMERSERVICE_CLIENT_ID: 'COsHJydx', + + //智慧客服地址 + REACT_APP_CUSTOMERSERVICE_REDIRECT: 'http://10.242.31.158:8632', + + // //智慧客服ws地址 + // REACT_APP_CUSTOMERSERVICE_WS_REDIRECT: 'ws://10.242.37.148:18022/api/api/biz-customer-service', + + // //智慧客服文档中心查看图片地址 + // REACT_APP_CUSTOMERSERVICE_DOC_REDIRECT: 'http://cos.gz-tst.cos.tg.unicom.local/349553515466:mall/', + + // //智慧客服加密公钥私钥ciphercode + // REACT_APP_CUSTOMERSERVICE_PUBLICKEY : '0428D625CEEB71CE823BD7D78DFEE7B122F2DA5C4D21E32253AD684D0FE21810394A799639C0CDFBFEB535A1DFD6A366A637E582CE0B1466A5FE7858841135DE6B', + // REACT_APP_CUSTOMERSERVICE_PRIVATEKEY : '4F7144028D4DCF88FA50F0E2B3FFDDCF63BBE17D1700537DCE037687D3AA3DA7', + // REACT_APP_CUSTOMERSERVICE_CIPHERCODE : 1, + }, +}); diff --git a/config/config.prod.ts b/config/config.prod.ts new file mode 100644 index 0000000..61ff507 --- /dev/null +++ b/config/config.prod.ts @@ -0,0 +1,43 @@ +import { defineConfig } from 'umi'; +import proxy from './proxy'; +export default defineConfig({ + proxy: proxy['prod'], + define:{ + //商城2.0跳转地址 + REACT_APP_MALL_V2_URL:'http://111.198.162.67/zglt/index_hzf.jsp?id=dev', + + //各系统跳转参数 + REACT_APP_CLIENT_KEY : 'KgPEkttG', + // REACT_APP_CLIENT_SECRET :'ae5bdb183c502355d2055b3de73300aa73cbfdf3', + + //密码加密参数 + REACT_APP_PASSWORD_CIPHERMODE:'1', + REACT_APP_PASSWORD_PUBLICKEY:'04819CF427F9150FEEBD91E8D2346F203FC47312D212022A967D8372EA30B9581CCEEFCE2670BDDAF2E8DA1620EA73948126078ED9FF9773AA3A94EE6C80035A18', + + //当前环境 + START_ENV:'PROD', + + //询价查看报价跳转地址 + // REACT_APP_XUNJIA_REDIRECT: 'https://60.10.26.178/provider', + //询价-查看报价详情-虚拟用户uid + REACT_APP_XUNJIA_UID: 'admin_entrance', + //智慧客服用户中心地址 + REACT_APP_CUSTOMERSERVICE_USERCENTER: 'https://uscm.chinaunicom.cn:18023/auth/oauth/authorize?response_type=code', + + //智慧客服client_id + REACT_APP_CUSTOMERSERVICE_CLIENT_ID: 'COsHJydx', + + //智慧客服地址 + REACT_APP_CUSTOMERSERVICE_REDIRECT: 'https://uscm.chinaunicom.cn:18011', + // //智慧客服ws地址 + // REACT_APP_CUSTOMERSERVICE_WS_REDIRECT: 'ws://uscm.unicom.local:18022/api/api/biz-customer-service', + + // //智慧客服文档中心查看图片地址 + // REACT_APP_CUSTOMERSERVICE_DOC_REDIRECT: 'http://cos.xx-pbc.cos.tg.unicom.local/349553515466:mall/', + + // //智慧客服加密公钥私钥ciphercode + // REACT_APP_CUSTOMERSERVICE_PUBLICKEY : '0428D625CEEB71CE823BD7D78DFEE7B122F2DA5C4D21E32253AD684D0FE21810394A799639C0CDFBFEB535A1DFD6A366A637E582CE0B1466A5FE7858841135DE6B', + // REACT_APP_CUSTOMERSERVICE_PRIVATEKEY : '4F7144028D4DCF88FA50F0E2B3FFDDCF63BBE17D1700537DCE037687D3AA3DA7', + // REACT_APP_CUSTOMERSERVICE_CIPHERCODE : 1, + }, +}); diff --git a/config/config.sim.ts b/config/config.sim.ts new file mode 100644 index 0000000..43156ec --- /dev/null +++ b/config/config.sim.ts @@ -0,0 +1,43 @@ +import { defineConfig } from 'umi'; +import proxy from './proxy'; +export default defineConfig({ + proxy: proxy['sim'], + define: { + //商城2.0跳转地址 + REACT_APP_MALL_V2_URL: 'http://111.198.162.67/zglt/index_hzf.jsp?id=dev', + + //各系统跳转参数 + REACT_APP_CLIENT_KEY: 'KgPEkttG', + // REACT_APP_CLIENT_SECRET: 'ae5bdb183c502355d2055b3de73300aa73cbfdf3', + + //密码加密参数 + REACT_APP_PASSWORD_CIPHERMODE: '1', + REACT_APP_PASSWORD_PUBLICKEY: '0428D625CEEB71CE823BD7D78DFEE7B122F2DA5C4D21E32253AD684D0FE21810394A799639C0CDFBFEB535A1DFD6A366A637E582CE0B1466A5FE7858841135DE6B', + + //当前环境 + START_ENV: 'sim', + + //询价查看报价跳转地址 + // REACT_APP_XUNJIA_REDIRECT: 'http://10.0.204.215:8080/provider', + //询价-查看报价详情-虚拟用户uid + REACT_APP_XUNJIA_UID: 'admin_entrance', + //智慧客服用户中心地址 + REACT_APP_CUSTOMERSERVICE_USERCENTER: 'http://10.242.31.158:8100/auth/oauth/authorize?response_type=code', + + //智慧客服client_id + REACT_APP_CUSTOMERSERVICE_CLIENT_ID: 'COsHJydx', + + //智慧客服地址 + REACT_APP_CUSTOMERSERVICE_REDIRECT: 'http://10.242.31.158:8632', + // //智慧客服ws地址 + // REACT_APP_CUSTOMERSERVICE_WS_REDIRECT: 'ws://10.242.31.54:18022/api/api/biz-customer-service', + + // //智慧客服文档中心查看图片地址 + // REACT_APP_CUSTOMERSERVICE_DOC_REDIRECT: 'http://cos.xx-pbc.cos.tg.unicom.local/349553515466:mall/', + + // //智慧客服加密公钥私钥ciphercode + // REACT_APP_CUSTOMERSERVICE_PUBLICKEY : '0428D625CEEB71CE823BD7D78DFEE7B122F2DA5C4D21E32253AD684D0FE21810394A799639C0CDFBFEB535A1DFD6A366A637E582CE0B1466A5FE7858841135DE6B', + // REACT_APP_CUSTOMERSERVICE_PRIVATEKEY : '4F7144028D4DCF88FA50F0E2B3FFDDCF63BBE17D1700537DCE037687D3AA3DA7', + // REACT_APP_CUSTOMERSERVICE_CIPHERCODE : 1, + }, +}); diff --git a/config/config.ts b/config/config.ts new file mode 100644 index 0000000..c3955ff --- /dev/null +++ b/config/config.ts @@ -0,0 +1,38 @@ +import { defineConfig } from 'umi'; +import defaultSettings from './defaultSettings'; +// import proxy from './proxy'; +import PageRoutes from './router.config' +const { REACT_APP_ENV } = process.env; +export default defineConfig({ + hash: true, + antd: {}, + dva: { + hmr: true, + }, + locale: { + default: 'zh-CN', + antd: true, + // default true, when it is true, will use `navigator.language` overwrite default + baseNavigator: true, + }, + //全局加载样式 + // dynamicImport: { + // loading: '@/components/PageLoading/index', + // }, + targets: { + ie: 11, + }, + // umi routes: https://umijs.org/docs/routing + routes: PageRoutes, + // Theme for antd: https://ant.design/docs/react/customize-theme-cn + theme: { + // ...darkTheme, + 'primary-color': defaultSettings.primaryColor, + }, + // @ts-ignore + title: false, + ignoreMomentLocale: true, + manifest: { + basePath: '/', + }, +}); diff --git a/config/defaultSettings.ts b/config/defaultSettings.ts new file mode 100644 index 0000000..d281703 --- /dev/null +++ b/config/defaultSettings.ts @@ -0,0 +1,25 @@ +import { Settings as ProSettings } from '@ant-design/pro-layout'; + +type DefaultSettings = ProSettings & { + pwa: boolean; +}; + +const proSettings: DefaultSettings = { + navTheme: 'light', + primaryColor: '#b30000', + layout: 'side', + contentWidth: 'Fluid', + fixedHeader: false, + fixSiderbar: true, + colorWeak: false, + menu: { + locale: true, + }, + title: '招投标系统', + pwa: false, + iconfontUrl: '', +}; + +export type { DefaultSettings }; + +export default proSettings; diff --git a/config/proxy.ts b/config/proxy.ts new file mode 100644 index 0000000..15913ac --- /dev/null +++ b/config/proxy.ts @@ -0,0 +1,98 @@ +export default { + dev: { + // '/api/wfap/v1/audit/bill/find/by/procid': { + // target: 'http://10.242.37.148:8891/',//审批单 dev环境自动审批,暂时用不到 + // changeOrigin: true, + // pathRewrite: { '^': '' }, + // }, + '/api/*': { + // target: 'http://10.242.37.148:18022',//连接天宫的ng + target: 'http://localhost:3000',//连接天宫的ng + changeOrigin: true, + pathRewrite: { '^': '' }, + }, + }, + UAT: { + '/api/core-service-ebtp-userinfo': { + target: 'http://localhost:18023', + changeOrigin: true, + pathRewrite: { '/api/core-service-ebtp-userinfo': '' }, + }, + '/api/biz-service-ebtp-bid': { + target: 'http://localhost:18003', + changeOrigin: true, + pathRewrite: { 'biz-service-ebtp-bid': '' }, + }, + '/api/biz-service-ebtp-extend': { + target: 'http://localhost:18018', + changeOrigin: true, + pathRewrite: { '/api/biz-service-ebtp-extend': '' }, + }, + '/api/biz-service-ebtp-project': { + target: 'http://localhost:18012', + changeOrigin: true, + pathRewrite: { '/api/biz-service-ebtp-project': '' }, + }, + '/api/sys-manager-ebtp-project': { + target: 'http://localhost:18030', + changeOrigin: true, + pathRewrite: { '/api/sys-manager-ebtp-project': '' }, + }, + '/api/biz-service-ebtp-rsms': { + target: 'http://localhost:18014', + changeOrigin: true, + pathRewrite: { '/api/biz-service-ebtp-rsms': '' }, + }, + '/api/biz-service-ebtp-agency': { + target: 'http://localhost:18099', + changeOrigin: true, + pathRewrite: { '/api/biz-service-ebtp-agency': '' }, + }, + '/api/biz-supplier-manage': { + target: 'http://localhost:18096', + changeOrigin: true, + pathRewrite: { '/api/biz-supplier-manage': '' }, + } + + // '/api/wfap/v1/audit/bill/find/by/procid': { + // target: 'http://10.242.31.158:8891/',//审批单 uat环境自动审批,暂时用不到 + // changeOrigin: true, + // pathRewrite: { '^': '' }, + // }, + // '/living/api/*': { + // // target: 'https://ai.cubigdata.cn:5001',//连接天宫的ng + // target: 'http://localhost:3000',//连接天宫的ng + // changeOrigin: true, + // pathRewrite: { '/living/api': '' }, + // }, + // '/api/*': { + // target: 'http://10.242.31.158:18022',//连接天宫的ng + // changeOrigin: true, + // pathRewrite: { '^': '' }, + // }, + // '/doc/v1.0/*': { + // target: 'http://10.242.31.158:8806',//连接天宫的ng + // changeOrigin: true, + // pathRewrite: { '^': '' }, + // }, + }, + sim: { + // '/api/wfap/v1/audit/bill/find/by/procid': { + // target: 'http://10.242.31.158:8891/',//审批单 uat环境自动审批,暂时用不到 + // changeOrigin: true, + // pathRewrite: { '^': '' }, + // }, + '/api/*': { + target: 'http://10.242.31.54:18022',//连接天宫的ng + changeOrigin: true, + pathRewrite: { '^': '' }, + }, + }, + prod: { + '/api/*': { + target: 'http://uscm.unicom.local:18022',//连接天宫的ng + changeOrigin: true, + pathRewrite: { '^': '' }, + }, + } +}; diff --git a/config/router.config.ts b/config/router.config.ts new file mode 100644 index 0000000..8dd2a76 --- /dev/null +++ b/config/router.config.ts @@ -0,0 +1,122 @@ +import menuaZhaoBiao from './ZhaoBiao/router_menubProject.config'; +import transfer from './router_transfer'; +import home from './HomePage/router_home'; +import juryRoom from './JuryRoom/router_menuJury.config'; +import approvalForm from './router_approval_form'; +import partyMemberTopic from './router_partyMemberTopic'; +import highQualityOperation from './router_highQualityOperation'; +import { elecBidEvaluation, monitor, monitorScreen } from './router_elecEvaluation'; +export default [ + //========================================================================登陆 + ...transfer,//跳转、登陆 + { + path: '/userformal', + // component: '../layouts/UserLayout', + routes: [ + { + name: 'login', + path: '/userformal/login', + component: './userformal/login', + }, + ], + }, + { + path: '/loading', + routes: [ + { + path: '/loading', + component: './Loading', + }, + ], + }, + //日历组件暂时用 + // { + // path: '/Calendar', + // component: './MainPage/ProjectManager/components/CalendarForm', + // }, + //视频播放-视频播放列表(暂时用) + { + path: '/ElecEvaluation/Monitor/videoplay', + component: './ElecEvaluation/Monitor/RoomDetail/videoplay', + }, + //富文本组件 + // { + // path: '/editor', + // component: './MainPage/ProjectManager/components/WangEditor', + // }, + //401错误页 + { + exact: true, + path: '/401', + component: './401', + }, + { + exact: true, + path: '/404', + component: './404', + }, + //==========================================================================菜单路由 + { + path: '/', + component: '../layouts/SecurityLayout', + routes: [ + { + path: '/', + component: '../layouts/BasicLayout', + //authority: ['ebtp-expert'], + routes: [ + {//专家登陆地址 + path: '/', + redirect: '/userexpert/login', + }, + ...home,//各角色主页 + ...menuaZhaoBiao,//项目菜单所有路由 + ...elecBidEvaluation,//电子评标室-监控大屏 + {//问卷调查 + name: 'Questionnaire', + icon: 'UnorderedListOutlined', + path: '/Questionnaire', + routes: [ + {//问卷调查 + name: 'QuestionList', + path: '/Questionnaire/questionList', + component: './Questionnaire/questionList' + }, + {//问卷调查新增 + name: 'questionAdd', + path: '/Questionnaire/questionAdd', + component: './Questionnaire/questionAdd' + }, + {//问卷统计 + name: 'QuestionStatistics', + path: '/Questionnaire/questionStatistics', + component: './Questionnaire/questionStatistics' + }, + ], + }, + {//我的工作台 + name: 'workbench', + icon: 'DesktopOutlined', + //authority: ['ebtp-expert'], + path: '/workbench', + routes: [ + { name: 'commonFiles', path: '/workbench/files', component: './workbench/files/components/FilesList' },//共享文档下载-所有角色 + { name: 'commonFilesManage', path: '/workbench/filesManage', component: './workbench/filesManage/components/filesManage' },//共享文档管理-系统管理员 + ] + }, + { name: 'systemMessage', path: '/SystemMessage/message', component: './SystemMessage/message' },//系统消息-所有角色 + { + component: './404', + }, + ], + }, + { + component: './404', + }, + ], + }, + { + component: './404', + }, + +]; diff --git a/jest.config.js b/jest.config.js new file mode 100644 index 0000000..4c4eeaf --- /dev/null +++ b/jest.config.js @@ -0,0 +1,9 @@ +module.exports = { + testURL: 'http://localhost:8000', + testEnvironment: './tests/PuppeteerEnvironment', + verbose: false, + globals: { + ANT_DESIGN_PRO_ONLY_DO_NOT_USE_IN_YOUR_PRODUCTION: false, + localStorage: null, + }, +}; diff --git a/jsconfig.json b/jsconfig.json new file mode 100644 index 0000000..f87334d --- /dev/null +++ b/jsconfig.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "baseUrl": ".", + "paths": { + "@/*": ["./src/*"] + } + } +} diff --git a/mock/listTableList.ts b/mock/listTableList.ts new file mode 100644 index 0000000..179890a --- /dev/null +++ b/mock/listTableList.ts @@ -0,0 +1,172 @@ +// eslint-disable-next-line import/no-extraneous-dependencies +import { Request, Response } from 'express'; +import { parse } from 'url'; +import { TableListItem, TableListParams } from '@/pages/ListTableList/data'; + +// mock tableListDataSource +const genList = (current: number, pageSize: number) => { + const tableListDataSource: TableListItem[] = []; + + for (let i = 0; i < pageSize; i += 1) { + const index = (current - 1) * 10 + i; + tableListDataSource.push({ + key: index, + disabled: i % 6 === 0, + href: 'https://ant.design', + avatar: [ + 'https://gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png', + 'https://gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png', + ][i % 2], + name: `TradeCode ${index}`, + owner: '曲丽丽', + desc: '这是一段描述', + callNo: Math.floor(Math.random() * 1000), + status: Math.floor(Math.random() * 10) % 4, + updatedAt: new Date(), + createdAt: new Date(), + progress: Math.ceil(Math.random() * 100), + }); + } + tableListDataSource.reverse(); + return tableListDataSource; +}; + +let tableListDataSource = genList(1, 100); + +function getRule(req: Request, res: Response, u: string) { + let realUrl = u; + if (!realUrl || Object.prototype.toString.call(realUrl) !== '[object String]') { + realUrl = req.url; + } + const { current = 1, pageSize = 10 } = req.query; + const params = (parse(realUrl, true).query as unknown) as TableListParams; + + let dataSource = [...tableListDataSource].slice( + ((current as number) - 1) * (pageSize as number), + (current as number) * (pageSize as number), + ); + const sorter = JSON.parse(params.sorter as any); + if (sorter) { + dataSource = dataSource.sort((prev, next) => { + let sortNumber = 0; + Object.keys(sorter).forEach((key) => { + if (sorter[key] === 'descend') { + if (prev[key] - next[key] > 0) { + sortNumber += -1; + } else { + sortNumber += 1; + } + return; + } + if (prev[key] - next[key] > 0) { + sortNumber += 1; + } else { + sortNumber += -1; + } + }); + return sortNumber; + }); + } + if (params.filter) { + const filter = JSON.parse(params.filter as any) as { + [key: string]: string[]; + }; + if (Object.keys(filter).length > 0) { + dataSource = dataSource.filter((item) => { + return Object.keys(filter).some((key) => { + if (!filter[key]) { + return true; + } + if (filter[key].includes(`${item[key]}`)) { + return true; + } + return false; + }); + }); + } + } + + if (params.name) { + dataSource = dataSource.filter((data) => data.name.includes(params.name || '')); + } + const result = { + data: dataSource, + total: tableListDataSource.length, + success: true, + pageSize, + current: parseInt(`${params.currentPage}`, 10) || 1, + }; + + return res.json(result); +} + +function postRule(req: Request, res: Response, u: string, b: Request) { + + let realUrl = u; + if (!realUrl || Object.prototype.toString.call(realUrl) !== '[object String]') { + realUrl = req.url; + } + + const body = (b && b.body) || req.body; + const { method, name, desc, key } = body; + + switch (method) { + /* eslint no-case-declarations:0 */ + case 'delete': + tableListDataSource = tableListDataSource.filter((item) => key.indexOf(item.key) === -1); + break; + case 'post': + (() => { + const i = Math.ceil(Math.random() * 10000); + const newRule = { + key: tableListDataSource.length, + href: 'https://ant.design', + avatar: [ + 'https://gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png', + 'https://gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png', + ][i % 2], + name, + owner: '曲丽丽', + desc, + callNo: Math.floor(Math.random() * 1000), + status: Math.floor(Math.random() * 10) % 2, + updatedAt: new Date(), + createdAt: new Date(), + progress: Math.ceil(Math.random() * 100), + }; + tableListDataSource.unshift(newRule); + return res.json(newRule); + })(); + return; + + case 'update': + (() => { + let newRule = {}; + tableListDataSource = tableListDataSource.map((item) => { + if (item.key === key) { + newRule = { ...item, desc, name }; + return { ...item, desc, name }; + } + return item; + }); + return res.json(newRule); + })(); + return; + default: + break; + } + + const result = { + list: tableListDataSource, + pagination: { + total: tableListDataSource.length, + }, + }; + + res.json(result); +} + +export default { + 'GET /api/rule': getRule, + 'POST /api/rule': postRule, +}; diff --git a/mock/newList.ts b/mock/newList.ts new file mode 100644 index 0000000..cd23e8b --- /dev/null +++ b/mock/newList.ts @@ -0,0 +1,131 @@ + +import { Request, Response } from 'express'; +//获取日历数据 +const getCalendarList = (req:Request ,res: Response) => { + const body = req.body; + const { year,month } = body; + const getData = (month1: any,year1: any) => { + if(year1 == 2021 || year1 == '2021') { + let data: any + switch (month1) { + case 1: + data = { + '2021-01-01': {number: 2, message: ['10:00','13:40']}, + '2021-01-07': {number: 3, message: ['11:00','13:40','13:40']}, + '2021-01-08': {number: 1, message: ['13:00']}, + '2021-01-14': {number: 2, message: ['12:10','13:40']}, + '2021-01-25': {number: 3, message: ['10:30','13:40','13:40']}, + } + break; + case 2: + data = { + '2021-02-06': {number: 1, message: ['10:00','13:40']}, + '2021-02-12': {number: 5, message: ['10:00','13:40','10:00','13:40','10:00']}, + } + break; + case 3: + data = { + '2021-03-09': {number: 6, message: ['10:00','13:40','10:00','13:40','10:00','13:40']}, + '2021-03-15': {number: 1, message: ['10:00','13:40']}, + '2021-03-21': {number: 4, message: ['10:00','13:40','10:00','13:40']}, + '2021-03-22': {number: 2, message: ['10:00','13:40']}, + '2021-03-30': {number: 3, message: ['10:00','13:40','13:40']}, + } + break; + case 4: + data = { + '2021-04-01': {number: 2, message: ['10:00','13:40']}, + '2021-04-07': {number: 2, message: ['10:00','13:40']}, + '2021-04-08': {number: 2, message: ['10:00','13:40']}, + '2021-04-14': {number: 2, message: ['10:00','13:40']}, + '2021-04-19': {number: 2, message: ['10:00','13:40']}, + } + break; + case 5: + data = { + '2021-05-03': {number: 2, message: ['10:00','13:40']}, + '2021-05-09': {number: 2, message: ['10:00','13:40']}, + '2021-05-18': {number: 2, message: ['10:00','13:40']}, + '2021-05-22': {number: 2, message: ['10:00','13:40']}, + } + break; + case 6: + data = { + '2021-06-01': {number: 2, message: ['10:00','13:40']}, + '2021-06-07': {number: 2, message: ['10:00','13:40']}, + '2021-06-09': {number: 2, message: ['10:00','13:40']}, + '2021-06-14': {number: 2, message: ['10:00','13:40']}, + '2021-06-21': {number: 2, message: ['10:00','13:40']}, + } + break; + case 7: + data = { + '2021-07-08': {number: 2, message: ['10:00','13:40']}, + '2021-07-09': {number: 2, message: ['10:00','13:40']}, + '2021-07-10': {number: 2, message: ['10:00','13:40']}, + '2021-07-14': {number: 2, message: ['10:00','13:40']}, + '2021-07-24': {number: 2, message: ['10:00','13:40']}, + } + break; + case 8: + data = { + '2021-08-12': {number: 2, message: ['10:00','13:40']}, + '2021-08-13': {number: 2, message: ['10:00','13:40']}, + '2021-08-14': {number: 2, message: ['10:00','13:40']}, + '2021-08-19': {number: 2, message: ['10:00','13:40']}, + } + break; + case 9: + data = { + '2021-09-11': {number: 2, message: ['10:00','13:40']}, + '2021-09-17': {number: 2, message: ['10:00','13:40']}, + '2021-09-18': {number: 2, message: ['10:00','13:40']}, + } + break; + case 10: + data = { + '2021-10-02': {number: 2, message: ['10:00','13:40']}, + '2021-10-10': {number: 2, message: ['10:00','13:40']}, + } + break; + case 11: + data = { + '2021-11-12': {number: 2, message: ['10:00','13:40']}, + '2021-11-13': {number: 2, message: ['10:00','13:40']}, + '2021-11-14': {number: 2, message: ['10:00','13:40']}, + '2021-11-15': {number: 2, message: ['10:00','13:40']}, + '2021-11-16': {number: 2, message: ['10:00','13:40']}, + } + break; + case 12: + data = { + '2021-12-07': {number: 2, message: ['10:00','13:40']}, + '2021-12-08': {number: 2, message: ['10:00','13:40']}, + '2021-12-14': {number: 2, message: ['10:00','13:40']}, + } + break; + default: + } + return data + } + } + (() => { + const newRule = { + code: 200, + data: { + ...getData(year,month-1), + ...getData(year,month), + ...getData(year,month+1) + }, + message: "success", + success: true + } + + return res.json(newRule); + })(); + return; +} + +export default { + 'POST /api/calendar': getCalendarList, +} \ No newline at end of file diff --git a/mock/notices.ts b/mock/notices.ts new file mode 100644 index 0000000..b9e3bf2 --- /dev/null +++ b/mock/notices.ts @@ -0,0 +1,105 @@ +import { Request, Response } from 'express'; + +const getNotices = (req: Request, res: Response) => { + res.json([ + { + id: '000000001', + avatar: 'https://gw.alipayobjects.com/zos/rmsportal/ThXAXghbEsBCCSDihZxY.png', + title: '你收到了 14 份新周报', + datetime: '2017-08-09', + type: 'notification', + }, + { + id: '000000002', + avatar: 'https://gw.alipayobjects.com/zos/rmsportal/OKJXDXrmkNshAMvwtvhu.png', + title: '你推荐的 曲妮妮 已通过第三轮面试', + datetime: '2017-08-08', + type: 'notification', + }, + { + id: '000000003', + avatar: 'https://gw.alipayobjects.com/zos/rmsportal/kISTdvpyTAhtGxpovNWd.png', + title: '这种模板可以区分多种通知类型', + datetime: '2017-08-07', + read: true, + type: 'notification', + }, + { + id: '000000004', + avatar: 'https://gw.alipayobjects.com/zos/rmsportal/GvqBnKhFgObvnSGkDsje.png', + title: '左侧图标用于区分不同的类型', + datetime: '2017-08-07', + type: 'notification', + }, + { + id: '000000005', + avatar: 'https://gw.alipayobjects.com/zos/rmsportal/ThXAXghbEsBCCSDihZxY.png', + title: '内容不要超过两行字,超出时自动截断', + datetime: '2017-08-07', + type: 'notification', + }, + { + id: '000000006', + avatar: 'https://gw.alipayobjects.com/zos/rmsportal/fcHMVNCjPOsbUGdEduuv.jpeg', + title: '曲丽丽 评论了你', + description: '描述信息描述信息描述信息', + datetime: '2017-08-07', + type: 'message', + clickClose: true, + }, + { + id: '000000007', + avatar: 'https://gw.alipayobjects.com/zos/rmsportal/fcHMVNCjPOsbUGdEduuv.jpeg', + title: '朱偏右 回复了你', + description: '这种模板用于提醒谁与你发生了互动,左侧放『谁』的头像', + datetime: '2017-08-07', + type: 'message', + clickClose: true, + }, + { + id: '000000008', + avatar: 'https://gw.alipayobjects.com/zos/rmsportal/fcHMVNCjPOsbUGdEduuv.jpeg', + title: '标题', + description: '这种模板用于提醒谁与你发生了互动,左侧放『谁』的头像', + datetime: '2017-08-07', + type: 'message', + clickClose: true, + }, + { + id: '000000009', + title: '任务名称', + description: '任务需要在 2017-01-12 20:00 前启动', + extra: '未开始', + status: 'todo', + type: 'event', + }, + { + id: '000000010', + title: '第三方紧急代码变更', + description: '冠霖提交于 2017-01-06,需在 2017-01-07 前完成代码变更任务', + extra: '马上到期', + status: 'urgent', + type: 'event', + }, + { + id: '000000011', + title: '信息安全考试', + description: '指派竹尔于 2017-01-09 前完成更新并发布', + extra: '已耗时 8 天', + status: 'doing', + type: 'event', + }, + { + id: '000000012', + title: 'ABCD 版本发布', + description: '冠霖提交于 2017-01-06,需在 2017-01-07 前完成代码变更任务', + extra: '进行中', + status: 'processing', + type: 'event', + }, + ]); +}; + +export default { + 'GET /api/notices': getNotices, +}; diff --git a/mock/profileBasicMock.ts b/mock/profileBasicMock.ts new file mode 100644 index 0000000..b52499a --- /dev/null +++ b/mock/profileBasicMock.ts @@ -0,0 +1,86 @@ +const basicGoods = [ + { + id: '1234561', + name: '矿泉水 550ml', + barcode: '12421432143214321', + price: '2.00', + num: '1', + amount: '2.00', + }, + { + id: '1234562', + name: '凉茶 300ml', + barcode: '12421432143214322', + price: '3.00', + num: '2', + amount: '6.00', + }, + { + id: '1234563', + name: '好吃的薯片', + barcode: '12421432143214323', + price: '7.00', + num: '4', + amount: '28.00', + }, + { + id: '1234564', + name: '特别好吃的蛋卷', + barcode: '12421432143214324', + price: '8.50', + num: '3', + amount: '25.50', + }, +]; + +const basicProgress = [ + { + key: '1', + time: '2017-10-01 14:10', + rate: '联系客户', + status: 'processing', + operator: '取货员 ID1234', + cost: '5mins', + }, + { + key: '2', + time: '2017-10-01 14:05', + rate: '取货员出发', + status: 'success', + operator: '取货员 ID1234', + cost: '1h', + }, + { + key: '3', + time: '2017-10-01 13:05', + rate: '取货员接单', + status: 'success', + operator: '取货员 ID1234', + cost: '5mins', + }, + { + key: '4', + time: '2017-10-01 13:00', + rate: '申请审批通过', + status: 'success', + operator: '系统', + cost: '1h', + }, + { + key: '5', + time: '2017-10-01 12:00', + rate: '发起退货申请', + status: 'success', + operator: '用户', + cost: '5mins', + }, +]; + +const getProfileBasicData = { + basicGoods, + basicProgress, +}; + +export default { + 'GET /api/profile/basic': getProfileBasicData, +}; diff --git a/mock/route.ts b/mock/route.ts new file mode 100644 index 0000000..418d10f --- /dev/null +++ b/mock/route.ts @@ -0,0 +1,5 @@ +export default { + '/api/auth_routes': { + '/form/advanced-form': { authority: ['admin', 'user'] }, + }, +}; diff --git a/mock/user.ts b/mock/user.ts new file mode 100644 index 0000000..0a7f305 --- /dev/null +++ b/mock/user.ts @@ -0,0 +1,154 @@ +import { Request, Response } from 'express'; + +function getFakeCaptcha(req: Request, res: Response) { + return res.json('captcha-xxx'); +} +// 代码中会兼容本地 service mock 以及部署站点的静态数据 +export default { + // 支持值为 Object 和 Array + 'GET /api/currentUser': { + name: 'Serati Ma', + avatar: 'https://gw.alipayobjects.com/zos/antfincdn/XAosXuNZyF/BiazfanxmamNRoxxVxka.png', + userid: '00000001', + email: 'antdesign@alipay.com', + signature: '海纳百川,有容乃大', + title: '交互专家', + group: '蚂蚁集团-某某某事业群-某某平台部-某某技术部-UED', + tags: [ + { + key: '0', + label: '很有想法的', + }, + { + key: '1', + label: '专注设计', + }, + { + key: '2', + label: '辣~', + }, + { + key: '3', + label: '大长腿', + }, + { + key: '4', + label: '川妹子', + }, + { + key: '5', + label: '海纳百川', + }, + ], + notifyCount: 12, + unreadCount: 11, + country: 'China', + geographic: { + province: { + label: '浙江省', + key: '330000', + }, + city: { + label: '杭州市', + key: '330100', + }, + }, + address: '西湖区工专路 77 号', + phone: '0752-268888888', + }, + // GET POST 可省略 + 'GET /api/users': [ + { + key: '1', + name: 'John Brown', + age: 32, + address: 'New York No. 1 Lake Park', + }, + { + key: '2', + name: 'Jim Green', + age: 42, + address: 'London No. 1 Lake Park', + }, + { + key: '3', + name: 'Joe Black', + age: 32, + address: 'Sidney No. 1 Lake Park', + }, + ], + 'POST /api/login/account': (req: Request, res: Response) => { + const { password, userName, type } = req.body; + if (password === 'ant.design' && userName === 'admin') { + res.send({ + status: 'ok', + type, + currentAuthority: 'admin', + }); + return; + } + if (password === 'ant.design' && userName === 'user') { + res.send({ + status: 'ok', + type, + currentAuthority: 'user', + }); + return; + } + if (type === 'mobile') { + res.send({ + status: 'ok', + type, + currentAuthority: 'admin', + }); + return; + } + + res.send({ + status: 'error', + type, + currentAuthority: 'guest', + }); + }, + 'POST /api/register': (req: Request, res: Response) => { + res.send({ status: 'ok', currentAuthority: 'user' }); + }, + 'GET /api/500': (req: Request, res: Response) => { + res.status(500).send({ + timestamp: 1513932555104, + status: 500, + error: 'error', + message: 'error', + path: '/base/category/list', + }); + }, + 'GET /api/404': (req: Request, res: Response) => { + res.status(404).send({ + timestamp: 1513932643431, + status: 404, + error: 'Not Found', + message: 'No message available', + path: '/base/category/list/2121212', + }); + }, + 'GET /api/403': (req: Request, res: Response) => { + res.status(403).send({ + timestamp: 1513932555104, + status: 403, + error: 'Unauthorized', + message: 'Unauthorized', + path: '/base/category/list', + }); + }, + 'GET /api/401': (req: Request, res: Response) => { + res.status(401).send({ + timestamp: 1513932555104, + status: 401, + error: 'Unauthorized', + message: 'Unauthorized', + path: '/base/category/list', + }); + }, + + 'GET /api/login/captcha': getFakeCaptcha, +}; diff --git a/package.json b/package.json new file mode 100644 index 0000000..9353ae1 --- /dev/null +++ b/package.json @@ -0,0 +1,175 @@ +{ + "name": "ant-design-pro", + "version": "4.2.1", + "private": true, + "description": "An out-of-box UI solution for enterprise applications", + "scripts": { + "start-dev": "cross-env UMI_UI=none UMI_ENV=dev LOGIN_PATH=ebtp-frontend umi dev --port=3000", + "start-UAT": "cross-env NODE_OPTIONS=--openssl-legacy-provider UMI_UI=none UMI_ENV=UAT LOGIN_PATH=ebtp-frontend umi dev --port=3000", + "start-sim": "cross-env UMI_UI=none UMI_ENV=sim LOGIN_PATH=ebtp-frontend umi dev --port=3000", + "start-prod": "cross-env UMI_UI=none UMI_ENV=prod LOGIN_PATH=prod/ebtp-frontend umi dev --port=3000", + "build-dev": "cross-env UMI_ENV=dev LOGIN_PATH=ebtp-frontend umi build", + "build-UAT": "cross-env UMI_ENV=UAT LOGIN_PATH=ebtp-frontend umi build", + "build-sim": "cross-env UMI_ENV=sim LOGIN_PATH=ebtp-frontend umi build", + "build-prod": "cross-env UMI_ENV=prod LOGIN_PATH=prod/ebtp-frontend umi build", + "analyze": "cross-env ANALYZE=1 umi build", + "build": "umi build", + "deploy": "npm run site && npm run gh-pages", + "dev": "npm run start:dev", + "docker-hub:build": "docker build -f Dockerfile.hub -t ant-design-pro ./", + "docker-prod:build": "docker-compose -f ./docker/docker-compose.yml build", + "docker-prod:dev": "docker-compose -f ./docker/docker-compose.yml up", + "docker:build": "docker-compose -f ./docker/docker-compose.dev.yml build", + "docker:dev": "docker-compose -f ./docker/docker-compose.dev.yml up", + "docker:push": "npm run docker-hub:build && npm run docker:tag && docker push antdesign/ant-design-pro", + "docker:tag": "docker tag ant-design-pro antdesign/ant-design-pro", + "fetch:blocks": "pro fetch-blocks && npm run prettier", + "gh-pages": "gh-pages -d dist", + "i18n-remove": "pro i18n-remove --locale=zh-CN --write", + "postinstall": "umi g tmp", + "lint": "umi g tmp && npm run lint:js && npm run lint:style && npm run lint:prettier", + "lint-staged:js": "eslint --ext .js,.jsx,.ts,.tsx ", + "lint:fix": "eslint --fix --cache --ext .js,.jsx,.ts,.tsx --format=pretty ./src && npm run lint:style", + "lint:js": "eslint --cache --ext .js,.jsx,.ts,.tsx --format=pretty ./src", + "lint:prettier": "prettier --check \"src/**/*\" --end-of-line auto", + "lint:style": "stylelint --fix \"src/**/*.less\" --syntax less", + "prettier": "prettier -c --write \"src/**/*\"", + "site": "npm run fetch:blocks && npm run build", + "start:dev": "cross-env REACT_APP_ENV=dev MOCK=none umi dev", + "start:no-mock": "cross-env MOCK=none umi dev", + "start:no-ui": "cross-env UMI_UI=none umi dev", + "start:pre": "cross-env REACT_APP_ENV=pre umi dev", + "start:test": "cross-env REACT_APP_ENV=test MOCK=none umi dev", + "pretest": "node ./tests/beforeTest", + "test": "umi test", + "test:all": "node ./tests/run-tests.js", + "test:component": "umi test ./src/components", + "tsc": "tsc --noEmit" + }, + "lint-staged": { + "**/*.less": "stylelint --syntax less", + "**/*.{js,jsx,ts,tsx}": "npm run lint-staged:js", + "**/*.{js,jsx,tsx,ts,less,md,json}": [ + "prettier --write" + ] + }, + "browserslist": [ + "> 1%", + "last 2 versions", + "not ie <= 10" + ], + "dependencies": { + "@ant-design/icons": "4.6.2", + "@ant-design/pro-card": "1.11.8", + "@ant-design/pro-descriptions": "1.7.0", + "@ant-design/pro-layout": "6.16.2", + "@ant-design/pro-list": "1.6.0", + "@ant-design/pro-table": "2.34.0", + "@material-ui/core": "4.11.3", + "@types/react-cookies": "0.1.0", + "@umijs/route-utils": "1.0.37", + "antd": "4.15.1", + "array-move": "3.0.1", + "axios": "0.21.1", + "classnames": "2.3.1", + "dva": "2.4.1", + "echarts": "^5.2.2", + "echarts-for-react": "^3.0.2", + "lodash": "4.17.21", + "moment": "^2.29.4", + "omit.js": "2.0.2", + "prop-types": "15.7.2", + "qs": "6.10.1", + "react": "16.14.0", + "react-axios": "2.0.5", + "react-cookies": "0.1.1", + "react-dom": "16.14.0", + "react-fast-marquee": "1.3.2", + "react-helmet-async": "^1.0.9", + "react-player": "^2.12.0", + "react-signature-canvas": "^1.0.3", + "react-sortable-hoc": "^1.11.0", + "sm-crypto": "0.2.5", + "umi": "^3.4.8", + "umi-request": "^1.3.5", + "use-merge-value": "1.0.2", + "wangeditor": "4.7.5" + }, + "devDependencies": { + "@ant-design/pro-cli": "^1.0.18", + "@types/classnames": "^2.2.7", + "@types/express": "^4.17.0", + "@types/history": "^4.7.2", + "@types/jest": "^26.0.0", + "@types/lodash": "^4.14.144", + "@types/qs": "^6.5.3", + "@types/react": "^16.9.17", + "@types/react-dom": "^16.8.4", + "@types/react-helmet": "^6.1.0", + "@types/react-signature-canvas": "^1.0.2", + "@umijs/fabric": "^2.2.0", + "@umijs/plugin-blocks": "^2.0.5", + "@umijs/preset-ant-design-pro": "^1.2.0", + "@umijs/preset-react": "^1.4.8", + "@umijs/preset-ui": "^2.0.9", + "@umijs/yorkie": "^2.0.3", + "carlo": "^0.9.46", + "chalk": "^4.0.0", + "cross-env": "^7.0.3", + "cross-port-killer": "^1.1.1", + "detect-installer": "^1.0.1", + "enzyme": "^3.11.0", + "eslint": "^7.1.0", + "express": "^4.17.1", + "gh-pages": "^3.0.0", + "jsdom-global": "^3.0.2", + "lint-staged": "^10.0.0", + "mockjs": "^1.0.1-beta3", + "prettier": "^2.0.1", + "pro-download": "1.0.1", + "puppeteer-core": "^5.0.0", + "react-iframe": "^1.8.0", + "react-pdf-js": "^4.0.1", + "stylelint": "^13.0.0", + "typescript": "^3.9.7" + }, + "engines": { + "node": ">=10.0.0" + }, + "checkFiles": [ + "src/**/*.js*", + "src/**/*.ts*", + "src/**/*.less", + "config/**/*.js*", + "scripts/**/*.js" + ], + "create-umi": { + "ignoreScript": [ + "docker*", + "functions*", + "site", + "generateMock" + ], + "ignoreDependencies": [ + "netlify*", + "serverless" + ], + "ignore": [ + ".dockerignore", + ".git", + ".github", + ".gitpod.yml", + "CODE_OF_CONDUCT.md", + "Dockerfile", + "Dockerfile.*", + "lambda", + "LICENSE", + "netlify.toml", + "README.*.md", + "azure-pipelines.yml", + "docker", + "CNAME", + "create-umi" + ] + } +} diff --git a/public/CNAME b/public/CNAME new file mode 100644 index 0000000..30c2d4d --- /dev/null +++ b/public/CNAME @@ -0,0 +1 @@ +preview.pro.ant.design \ No newline at end of file diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100644 index 0000000..29f0ff4 Binary files /dev/null and b/public/favicon.ico differ diff --git a/public/home_bg.png b/public/home_bg.png new file mode 100644 index 0000000..7c92a4b Binary files /dev/null and b/public/home_bg.png differ diff --git a/public/icons/icon-128x128.png b/public/icons/icon-128x128.png new file mode 100644 index 0000000..48d0e23 Binary files /dev/null and b/public/icons/icon-128x128.png differ diff --git a/public/icons/icon-192x192.png b/public/icons/icon-192x192.png new file mode 100644 index 0000000..938e9b5 Binary files /dev/null and b/public/icons/icon-192x192.png differ diff --git a/public/icons/icon-512x512.png b/public/icons/icon-512x512.png new file mode 100644 index 0000000..21fc108 Binary files /dev/null and b/public/icons/icon-512x512.png differ diff --git a/public/information-release/ebtp/background.jpg b/public/information-release/ebtp/background.jpg new file mode 100644 index 0000000..844ff96 Binary files /dev/null and b/public/information-release/ebtp/background.jpg differ diff --git a/public/information-release/ebtp/ebtp-release-jl-screen.html b/public/information-release/ebtp/ebtp-release-jl-screen.html new file mode 100644 index 0000000..0e6d868 --- /dev/null +++ b/public/information-release/ebtp/ebtp-release-jl-screen.html @@ -0,0 +1,209 @@ + + + + + + + + 信息发布屏 + + + +
+
+
+ --:--:-- + ----.--.-- 星期-- + 吉林联通电子评标室 + (该会议室最多可容纳人数:--) +
+
+
+
+
+
+

+    会议名称:——
+    会议事项:——
+    会议时间:——
+    预约人员:——
+    联系方式:——
+

+
+
+
+ + + + + + \ No newline at end of file diff --git a/public/logo.svg b/public/logo.svg new file mode 100644 index 0000000..113f6d9 --- /dev/null +++ b/public/logo.svg @@ -0,0 +1,25 @@ + + + + + + + + + + + + diff --git a/public/pro_icon.svg b/public/pro_icon.svg new file mode 100644 index 0000000..e075b78 --- /dev/null +++ b/public/pro_icon.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/public/screen/jsWebControl-1.0.0.min.js b/public/screen/jsWebControl-1.0.0.min.js new file mode 100644 index 0000000..54f7cb0 --- /dev/null +++ b/public/screen/jsWebControl-1.0.0.min.js @@ -0,0 +1 @@ +var WebControl=function(){"use strict";function e(t){return(e="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(t)}function t(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function n(e,t){for(var n=0;ne.length)&&(t=e.length);for(var n=0,o=new Array(t);n0?le:ce)(e)},fe=Math.min,he=function(e){return e>0?fe(de(e),9007199254740991):0},pe=Math.max,ve=Math.min,be=function(e){return function(t,n,o){var i,r=_(t),a=he(r.length),s=function(e,t){var n=de(e);return n<0?pe(n+t,0):ve(n,t)}(o,a);if(e&&n!=n){for(;a>s;)if((i=r[s++])!=i)return!0}else for(;a>s;s++)if((e||s in r)&&r[s]===n)return e||s||0;return!e&&-1}},me={includes:be(!0),indexOf:be(!1)}.indexOf,ge=function(e,t){var n,o=_(e),i=0,r=[];for(n in o)!S(Y,n)&&S(o,n)&&r.push(n);for(;t.length>i;)S(o,n=t[i++])&&(~me(r,n)||r.push(n));return r},ye=["constructor","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","toLocaleString","toString","valueOf"],_e=ye.concat("length","prototype"),we={f:Object.getOwnPropertyNames||function(e){return ge(e,_e)}},ke={f:Object.getOwnPropertySymbols},Ce=ue("Reflect","ownKeys")||function(e){var t=we.f(E(e)),n=ke.f;return n?t.concat(n(e)):t},Se=function(e,t){for(var n=Ce(t),o=T.f,i=z.f,r=0;ri;)for(var s,u=g(arguments[i++]),c=r?We(u).concat(r(u)):We(u),d=c.length,f=0;d>f;)s=c[f++],l&&!a.call(u,s)||(n[s]=u[s]);return n}:Ae;Te({target:"Object",stat:!0,forced:Object.assign!==Me},{assign:Me});ae.Object.assign;var Fe=!!Object.getOwnPropertySymbols&&!c((function(){return!String(Symbol())})),Be=Fe&&!Symbol.sham&&"symbol"==e(Symbol.iterator),Le=Z("wks"),Je=u.Symbol,je=Be?Je:Je&&Je.withoutSetter||V,Ne=function(e){return S(Le,e)||(Fe&&S(Je,e)?Le[e]=Je[e]:Le[e]=je("Symbol."+e)),Le[e]},Ze={};Ze[Ne("toStringTag")]="z";var He="[object z]"===String(Ze),Ge=Ne("toStringTag"),Ve="Arguments"==b(function(){return arguments}()),Ke=He?b:function(e){var t,n,o;return void 0===e?"Undefined":null===e?"Null":"string"==typeof(n=function(e,t){try{return e[t]}catch(e){}}(t=Object(e),Ge))?n:Ve?b(t):"Object"==(o=b(t))&&"function"==typeof t.callee?"Arguments":o},Xe=He?{}.toString:function(){return"[object "+Ke(this)+"]"};He||re(Object.prototype,"toString",Xe,{unsafe:!0});var Ye,$e,Qe,et=function(e){return function(t,n){var o,i,r=String(y(t)),a=de(n),s=r.length;return a<0||a>=s?e?"":void 0:(o=r.charCodeAt(a))<55296||o>56319||a+1===s||(i=r.charCodeAt(a+1))<56320||i>57343?e?r.charAt(a):o:e?r.slice(a,a+2):i-56320+(o-55296<<10)+65536}},tt={codeAt:et(!1),charAt:et(!0)},nt=!c((function(){function e(){}return e.prototype.constructor=null,Object.getPrototypeOf(new e)!==e.prototype})),ot=X("IE_PROTO"),it=Object.prototype,rt=nt?Object.getPrototypeOf:function(e){return e=De(e),S(e,ot)?e[ot]:"function"==typeof e.constructor&&e instanceof e.constructor?e.constructor.prototype:e instanceof Object?it:null},at=Ne("iterator"),st=!1;[].keys&&("next"in(Qe=[].keys())?($e=rt(rt(Qe)))!==Object.prototype&&(Ye=$e):st=!0),null==Ye&&(Ye={}),S(Ye,at)||W(Ye,at,(function(){return this}));var ut,ct={IteratorPrototype:Ye,BUGGY_SAFARI_ITERATORS:st},lt=l?Object.defineProperties:function(e,t){E(e);for(var n,o=We(t),i=o.length,r=0;i>r;)T.f(e,n=o[r++],t[n]);return e},dt=ue("document","documentElement"),ft=X("IE_PROTO"),ht=function(){},pt=function(e){return" + + + + + + + + + + + +
+ + + +
+ 即将进入 + + +
+
+ + + \ No newline at end of file diff --git a/src/service-worker.js b/src/service-worker.js new file mode 100644 index 0000000..03b3d51 --- /dev/null +++ b/src/service-worker.js @@ -0,0 +1,70 @@ +/* eslint-disable eslint-comments/disable-enable-pair */ +/* eslint-disable no-restricted-globals */ +/* eslint-disable no-underscore-dangle */ +/* globals workbox */ +workbox.core.setCacheNameDetails({ + prefix: 'antd-pro', + suffix: 'v1', +}); +// Control all opened tabs ASAP +workbox.clientsClaim(); + +/** + * Use precaching list generated by workbox in build process. + * https://developers.google.com/web/tools/workbox/reference-docs/latest/workbox.precaching + */ +workbox.precaching.precacheAndRoute(self.__precacheManifest || []); + +/** + * Register a navigation route. + * https://developers.google.com/web/tools/workbox/modules/workbox-routing#how_to_register_a_navigation_route + */ +workbox.routing.registerNavigationRoute('/index.html'); + +/** + * Use runtime cache: + * https://developers.google.com/web/tools/workbox/reference-docs/latest/workbox.routing#.registerRoute + * + * Workbox provides all common caching strategies including CacheFirst, NetworkFirst etc. + * https://developers.google.com/web/tools/workbox/reference-docs/latest/workbox.strategies + */ + +/** + * Handle API requests + */ +workbox.routing.registerRoute(/\/api\//, workbox.strategies.networkFirst()); + +/** + * Handle third party requests + */ +workbox.routing.registerRoute( + /^https:\/\/gw\.alipayobjects\.com\//, + workbox.strategies.networkFirst(), +); +workbox.routing.registerRoute( + /^https:\/\/cdnjs\.cloudflare\.com\//, + workbox.strategies.networkFirst(), +); +workbox.routing.registerRoute(/\/color.less/, workbox.strategies.networkFirst()); + +/** + * Response to client after skipping waiting with MessageChannel + */ +addEventListener('message', (event) => { + const replyPort = event.ports[0]; + const message = event.data; + if (replyPort && message && message.type === 'skip-waiting') { + event.waitUntil( + self.skipWaiting().then( + () => + replyPort.postMessage({ + error: null, + }), + (error) => + replyPort.postMessage({ + error, + }), + ), + ); + } +}); diff --git a/src/services/bidev.js b/src/services/bidev.js new file mode 100644 index 0000000..ef92bc1 --- /dev/null +++ b/src/services/bidev.js @@ -0,0 +1,92 @@ +import request from '@/utils/request'; +import { stringify } from 'qs'; +// 查询项目经理评审室列表 +export async function fetchManagerList(params) { + return request(`/api/biz-service-ebtp-process/v1/bizassessroom/manager/list`, + { method: 'POST', data: { ...params } }); +} +// 开启评审 +export async function openBizassessroom(params) { + return request(`/api/biz-service-ebtp-process/v1/bizassessroom/openRoom/${params.id}`, + { method: 'POST' }); +} +// 开启评审多轮招募 +export async function zmmultiOpenBizassessroom(params) { + return request(`/api/biz-service-ebtp-process/v1/assessroom/zmmulti/openRoom/${params.id}`, + { method: 'POST' }); +} + +export async function resetVerificationCode(params) { + return request(`/api/biz-service-ebtp-process/v1/bizassessroom/update/captcha/${params.id}`, + { method: 'post' }); +} + +export async function fetchJuryList(params) { + return request(`/api/biz-service-ebtp-process/v1/bizassessroom/jury/list?${stringify(params)}`); +} + +export async function fetchSupplierList(params) { + return request(`/api/biz-service-ebtp-process/v1/bizassessroom/supplier/list?${stringify(params)}`); +} + +export async function fetchJuryMemInfo(params) { + return request(`/api/biz-service-ebtp-rsms/v1/jury/member/baseinfo/${params.roomId}`); +} + +export async function updateJuryMemInfo(params) { + return request(`/api/biz-service-ebtp-rsms/v1/jury/member/update`, + { method: 'POST', params: params }); +} + +export async function validateVerificationCode(params) { + return request(`/api/biz-service-ebtp-process/v1/bizassessroom/check/captcha?${stringify(params)}`, + { method: 'POST' }); +} + +export async function fetchbidslist(params) { + return request(`/api/biz-service-ebtp-tender/v1/supplier_register/assessroom/suppliers?${stringify(params)}`); +} + +export async function pushRedirectRe(params) { + return request(`/api/biz-service-ebtp-rsms/v1/jury/member/confirm`, { method: 'post', data: params }); +} +// 查询初审汇总表 +export async function fetchPreList(params) { + return request(`/api/biz-service-ebtp-rsms/v1/bid/eval/summary/findEarlySummary`, { + method: 'POST', + data: { + ...params + } + }); +} +// 查询供应商信息 +export async function fetchPreSupplierList(params) { + return request(`/api/biz-service-ebtp-rsms/v1/bid/eval/detail/findRegister?${stringify(params)}`); +} +// 查询详审汇总表 +export async function fetchPreListt(params) { + return request(`/api/biz-service-ebtp-rsms/v1/bid/eval/summary/findResultSummary`, { + method: 'POST', + data: { + ...params + } + }); +} + +// 查询有限数量制(公开比选) +export async function bxmultifetchPreListt(params) { + return request(`/api/biz-service-ebtp-rsms/v1/bxmulti/eval/summary/findResultSummary`, { + method: 'POST', + data: { + ...params + } + }); +} +// 根据评审室id获取确认承诺书状态 +export async function getCheckedByRoomId(params) { + return request(`/api/biz-service-ebtp-rsms/v1/jury/member/check/confirmStatus?${stringify(params)}`) +} +//开启评审室判断供应商数量 +export async function checkOpenBidSupplier(params) { + return request(`/api/biz-service-ebtp-tender/v1/supplier_register/tender/count/${params}`) +} diff --git a/src/services/common.ts b/src/services/common.ts new file mode 100644 index 0000000..76a41fa --- /dev/null +++ b/src/services/common.ts @@ -0,0 +1,29 @@ +import request from '@/utils/request'; +/** + * 根据评审室id获取评审室信息 + * 2021.8.11 zhoujianlong + * @param data + * @returns + */ +export async function getRoomDataById(params: any) { + return request(`/api/biz-service-ebtp-process/v1/bizassessroom/${params}`); +} + +/** + * 根据标段id获取标段信息 + * 2021.8.11 zhoujianlong + * @param data + * @returns + */ +export async function getSectionDataById(params: any) { + return request(`/api/biz-service-ebtp-project/v1/projectSection/${params}`); +} +/** + * 根据projectId,tpId,项目id获取项目信息 + * 2023.4.19 zhoujianlong + * @param id + * @returns + */ +export async function getProjectDataById(id?: any) { + return request(`/api/biz-service-ebtp-project/v1/projectRecord/${id}`); +} \ No newline at end of file diff --git a/src/services/dashboard.js b/src/services/dashboard.js new file mode 100644 index 0000000..6a89b27 --- /dev/null +++ b/src/services/dashboard.js @@ -0,0 +1,99 @@ +import request from '@/utils/request'; +import { stringify } from 'qs'; + +export async function fetchDowntlist(params) { + return request(`/api/biz-service-ebtp-project/v1/projectRecord/getUserProjectRecordListByProcurementMode/${params.limit}`,{ + method: 'POST', + data: { + ...params + }}) +} + +export async function fetchprojectRecords(params) { + return request(`/api/biz-service-ebtp-project/v1/projectRecord/getUserProjectRecordCount/${params.selectDate}`,{ + method: 'POST', + data: { + ...params + }}); +} + +export async function fetchJuryUpList(params) { + return request(`/api/biz-service-ebtp-process/v1/bizassessroom/jury/reviewcount/${params.selectDate}`) +} + +export async function fetchJuryDownlist(params) { + return request(`/api/biz-service-ebtp-process/v1/bizassessroom/jury/list?${stringify(params)}`) +} + +export async function fetchSupplierUpList(params) { + return request(`/api/biz-service-ebtp-tender/v1/index/project/register`,{ + method: 'POST', + data: { + ...params + }}); +} + +export async function fetchSupplierDownLeftList() { + return request(`/api/biz-service-ebtp-tender/v1/index/project/invited`) +} + +export async function fetchSupplierDownRightList(params) { + return request(`/api/biz-service-ebtp-tender/v1/index/project/processing`,{ + method: 'POST', + data: { + ...params + }}) +} + + +export async function fetchtlist(params) { + return request(`/api/biz-service-ebtp-extend/v1/bizbidnotice/list`,{ + method: 'POST', + data: { + ...params + }}) +} + +export async function fetchtlistre(params) { + return request(`/api/biz-service-ebtp-extend/v1/message/describeSiteMsg`, { + method: 'POST', + data: { + ...params + } + }) +} + +export async function fetchtPageList(params) { + return request('/api/biz-service-ebtp-auction/v1/bidders/InteriorManagerProjectList/getPageList',{ + method: 'POST', + data: { + ...params + } + }); +} + +export async function fetchtShotList(params) { + return request('/api/biz-service-ebtp-auction/v1/bidders/myInnershot/getPageList',{ + method: 'POST', + data: { + ...params + } + }); +} + +export async function fetchDisposalList(params) { // 内拍处置经理首页项目统计 + return request(`/api/biz-service-ebtp-auction/v1/auction/count/${params.selectDate}`) +} + +export async function fetchParticipants(params) { // 内拍参拍人首页项目统计 + return request(`/api/biz-service-ebtp-auction/v1/auction/biddersCount/${params.selectDate}`) +} + +export async function fetchtClarify(params) { // 首页澄清列表 + return request('/api/biz-service-ebtp-extend/v1/message/selectMsgListByType',{ + method: 'POST', + data: { + ...params + } + }); +} \ No newline at end of file diff --git a/src/services/downLoad.ts b/src/services/downLoad.ts new file mode 100644 index 0000000..a7d94c2 --- /dev/null +++ b/src/services/downLoad.ts @@ -0,0 +1,13 @@ +import request from '@/utils/request'; +/** + * 根据项目id获取引用供应商资质库信息状态 + * 2021.8.6 zhoujianlong + * @param data + * @returns + */ +export async function getStatusByProId(params: any) { + return request('/api/biz-service-ebtp-resps/v1/tdoc/isQuoteSupplier', { + method: 'POST', + params: params + }); +} \ No newline at end of file diff --git a/src/services/download_.ts b/src/services/download_.ts new file mode 100644 index 0000000..b1c4b58 --- /dev/null +++ b/src/services/download_.ts @@ -0,0 +1,56 @@ +import { downloadSecretKeyPath, findFilelistPath, findFilelistPathBySecond, getSnowIdPath, removeFilePath } from '@/utils/DownloadUtils'; +import request from '@/utils/request'; +/** + * 获取密钥(用于下载附件) + * @param {主键} fileId + * @returns + */ +export async function getDownloadSecretKey({ fileId }: any) { + return request(downloadSecretKeyPath, { + method: 'GET', + params: { fileId }, + }); +} +/** + * 获取雪花id + * @returns + */ +export async function createNewFileBid() { + return request(getSnowIdPath, { + method: 'GET' + }) +} +/** + * 根据fileId删除文件 + * @param {主键} fileId + * @returns + */ +export async function removeFileByOid(fileId: string) { + return request(removeFilePath, { + method: 'POST', + params: { fileId }, + }) +} + +/** + * 根据objectIdList查询文件列表 + * @param {业务id列表} objectIdList + * @returns + */ +export async function getFilelist(objectIdList: string[]) { + return request(findFilelistPath, { + method: 'POST', + data: [...objectIdList], + }) +} + +/** + * 根据bid查询文件列表(2.0) + * @param {业务id列表} id + * @returns + */ +export async function getFilelistBySecond(id: string, p: string) { + return fetch(findFilelistPathBySecond + '?id=' + id + '&p=' + p, { + method: 'POST', + }) +} \ No newline at end of file diff --git a/src/services/login.ts b/src/services/login.ts new file mode 100644 index 0000000..4f9b7c6 --- /dev/null +++ b/src/services/login.ts @@ -0,0 +1,135 @@ +import request from '@/utils/request'; +import { getEncrypt } from '@/utils/session'; + +export interface LoginParamsType { + userName: string; + password: string; + captcha: string; + tmpToken: string; +} + +export interface FaceLoginParamsType { + userName: string; + multipartFiles: Blob; +} + + +const sm2 = require('sm-crypto').sm2; +const encrypt = getEncrypt(); + + + + +// 天宫合作方登录 +export async function CooperfakeAccountLogin(params: LoginParamsType) { + // return request('/api/mall-auth/partnerLogin', { + return request('/api/sys-manager-ebtp-project/auth/partnerLogin', { + method: 'POST', + requestType: 'form', + headers: { + 'clientId': `${REACT_APP_CLIENT_KEY}`, + }, + data: { + 'username': params.userName, + // 'password': params.password, + 'password': '04' + sm2.doEncrypt(params.password, encrypt.publicKey, encrypt.cipherMode), + 'captcha': params.captcha, + 'token': params.tmpToken, + }, + }); +} + + +// 天宫专家登录 +export async function ZjfakeAccountLogin(params: LoginParamsType) { + // return request('/api/mall-auth/expertLogin', { + return request('/api/auth/expertLogin', { + method: 'POST', + requestType: 'form', + headers: { + 'clientId': `${REACT_APP_CLIENT_KEY}`, + }, + data: { + 'identityCard': params.userName, + // 'password': params.password, + 'password': '04' + sm2.doEncrypt(params.password, encrypt.publicKey, encrypt.cipherMode), + captcha: params.captcha, + token: params.tmpToken, + }, + }); +} + +// 专家人脸登录 +export async function ZjfakeFaceLogin(params: FaceLoginParamsType) { + var formData = new FormData(); + formData.append('idNo', params.userName); + formData.append('multipartFiles', params.multipartFiles, 'upload_face.jpeg'); + return request('/api/core-service-ebtp-userinfo/outer/v1/ebtp/face/faceCompare', { + method: 'POST', + requestType: 'form', + mode: 'cors', + body: formData + }); +} + +// 天宫云门户 +export async function CloudfakeAccountLogin(params: LoginParamsType) { + // return request('/api/mall-auth/login', { + return request('/api/auth/login', { + method: 'POST', + requestType: 'form', + headers: { + 'clientId': `${REACT_APP_CLIENT_KEY}`, + }, + data: { + 'username': params.userName, + // 'password': params.password, + 'password': '04' + sm2.doEncrypt(params.password, encrypt.publicKey, encrypt.cipherMode), + captcha: params.captcha, + token: params.tmpToken, + }, + }); +} +/** + * 刷新Token + * @param params + * @returns + */ +export async function refreshTokenApi(params: any) { + return request('/api/core-service-ebtp-userinfo/v1/auth/oauth/token', { + method: 'POST', + requestType: 'form', + data: params, + }); +} + +export async function getPassword(params: any) { // 获取后台验证码接口 + return request('/api/core-service-ebtp-userinfo/v1/userpassword/validatePassword', { + method: 'POST', + params: params + }); +} +/** + * 发送手机验证码 + * @param params + * @returns + */ +export async function getFakeCaptcha(params: any) { + return request('/api/notification/v1/notification/savaSmsByPhoneNew', { + method: 'POST', + data: { ...params }, + requestType: 'json', + }); +} + +/** + * 用户登出 + * @param params + * @returns + */ +export async function logoutTokenApi() { + return request('/api/core-service-ebtp-userinfo/v1/userinfo/logout', { + method: 'GET', + // params: params + }); +} diff --git a/src/services/untilService.ts b/src/services/untilService.ts new file mode 100644 index 0000000..68acc42 --- /dev/null +++ b/src/services/untilService.ts @@ -0,0 +1,45 @@ +import request from '@/utils/request'; +import {doc} from "prettier"; +/*雪花id获取*/ +export async function SnowflakeID() { + return request('/api/core-service-ebtp-updownload/v1/business/id', {method: 'get'}) +} +/*文档中心 根据bid获取文件列表 直接返回 upload组件 fileList 格式*/ +export async function getFileBidList(BidID: any) { + if(BidID==null||BidID==""||BidID==undefined){ + return ; + } + const Msg = []; + await request('/api/core-service-ebtp-updownload/v1/attachment/find', + { + method: 'post', + data: { + "bidList": [BidID] + } + } + ).then(res => { + if (res?.[BidID]?.length > 0) { + for (const f in res[BidID]) { + Msg.push( + { + uid: res[BidID][f].id, + name: res[BidID][f].filename, + status: 'done', + url: '/api/core-service-ebtp-updownload/v1/attachment/download/oid/' + res[BidID][f].id, + } + ) + } + + } + }) + return Msg; +} +/*文档中心 逻辑删除 根据objectid */ +export async function deleteFileObjId(ObjId: any) { + request('/api/core-service-ebtp-updownload/v1/attachment/item/'+ObjId, + { + method: 'delete', + } + ) + +} diff --git a/src/services/user.ts b/src/services/user.ts new file mode 100644 index 0000000..1988721 --- /dev/null +++ b/src/services/user.ts @@ -0,0 +1,13 @@ +import request from '@/utils/request'; + +export async function query(): Promise { + return request('/api/users'); +} + +export async function queryCurrent(): Promise { + return request('/api/currentUser'); +} + +export async function queryNotices(): Promise { + return request('/api/notices'); +} diff --git a/src/shime.d.ts b/src/shime.d.ts new file mode 100644 index 0000000..2d80117 --- /dev/null +++ b/src/shime.d.ts @@ -0,0 +1,2 @@ + +declare module 'rc-tween-one/lib/plugin/ChildrenPlugin' \ No newline at end of file diff --git a/src/typings.d.ts b/src/typings.d.ts new file mode 100644 index 0000000..d2c439a --- /dev/null +++ b/src/typings.d.ts @@ -0,0 +1,62 @@ +declare module 'slash2'; +declare module '*.css'; +declare module '*.less'; +declare module '*.scss'; +declare module '*.sass'; +declare module '*.svg'; +declare module '*.png'; +declare module '*.jpg'; +declare module '*.jpeg'; +declare module '*.gif'; +declare module '*.bmp'; +declare module '*.tiff'; +declare module 'omit.js'; + +// google analytics interface +interface GAFieldsObject { + eventCategory: string; + eventAction: string; + eventLabel?: string; + eventValue?: number; + nonInteraction?: boolean; +} +interface Window { + ga: ( + command: 'send', + hitType: 'event' | 'pageview', + fieldsObject: GAFieldsObject | string, + ) => void; + reloadAuthorized: () => void; +} + +declare let ga: Function; + +declare interface Window { + ntkoBrowser: any; +} + +// preview.pro.ant.design only do not use in your production ; +// preview.pro.ant.design 专用环境变量,请不要在你的项目中使用它。 +declare let ANT_DESIGN_PRO_ONLY_DO_NOT_USE_IN_YOUR_PRODUCTION: 'site' | undefined; + +declare const REACT_APP_ENV: 'test' | 'dev' | 'pre' | false; +/**ENV-商城2.0跳转地址 */ +declare const REACT_APP_MALL_V2_URL: string +/**ENV-系统跳转参数KEY */ +declare const REACT_APP_CLIENT_KEY: string +/**ENV-系统跳转参数SECRET */ +// declare const REACT_APP_CLIENT_SECRET: string +/**ENV-密码加密参数CIPHERMODE */ +declare const REACT_APP_PASSWORD_CIPHERMODE: string +/**ENV-密码加密参数PUBLICKEY */ +declare const REACT_APP_PASSWORD_PUBLICKEY: string +/**ENV-环境参数 */ +declare const START_ENV: string +/**ENV-询价查看报价跳转地址 */ +// declare const REACT_APP_XUNJIA_REDIRECT: string +/**ENV-询价查看报价跳转地址 */ +declare const REACT_APP_XUNJIA_UID: string +//智慧客服 +declare const REACT_APP_CUSTOMERSERVICE_USERCENTER: string +declare const REACT_APP_CUSTOMERSERVICE_CLIENT_ID: string +declare const REACT_APP_CUSTOMERSERVICE_REDIRECT: string diff --git a/src/utils/AboutAnnouncementHelp.ts b/src/utils/AboutAnnouncementHelp.ts new file mode 100644 index 0000000..169722d --- /dev/null +++ b/src/utils/AboutAnnouncementHelp.ts @@ -0,0 +1,105 @@ +/** + * 公告时间相关提示 工具 + */ +import { getDefId, getProOpenTenderForm } from "@/utils/session"; +import { getURLInformation } from "./CommonUtils"; +/** +* 文件获取开始时间 +* */ +export function AnnouncementGetMsg1(Msg?: any) { + let msg = null; + msg = Msg + "需晚于当前时间"; + return msg; +} +export function AnnouncementGetMsg2(Msg1?: any, Msg2?: any) { + let msg = null; + let days = 5; + let defId = getDefId(); + if (defId == "negotiation_competitive_public"//竞争性谈判-公开参与 + || defId == "negotiation_competitive_invite"//竞争性谈判-邀请参与 + || defId == "negotiation_single"//单一来源 + || defId == "negotiation_single_simple"//单一来源简化 + ) { + days = 3 + } + + msg = Msg1 + "需与" + Msg2 + "间隔不少于" + days + "天"; + return msg; +} +export function AnnouncementGetMsg3(Msg1?: any, Msg2?: any, Msg3?: any) { + let msg = null; + let defId = getDefId(); + let roomType = getURLInformation('roomType') //预审后审标识 1-预审阶段 2-后审阶段 + let tendF = getProOpenTenderForm(); + if (defId == "negotiation_competitive_public"//竞争性谈判-公开参与 + || defId == "negotiation_competitive_invite"//竞争性谈判-邀请参与 + || defId == "negotiation_single"//单一来源 + || defId == "negotiation_single_simple"//单一来源简化 + || defId == "recruit_multi"//招募 多轮 + || defId == "recruit"//招募 单轮 + ) { + msg = Msg1 + "需晚于或等于" + Msg2; + } else if (defId == "comparison_one_prequalification"//公开比选一阶段-资格预审 + || defId == "comparison_multi_prequalification"//公开比选多阶段-资格预审 + || defId == "comparison_one"//公开比选一阶段 + || defId == "comparison_multi"//公开比选多阶段 + ) { + msg = Msg1 + "需与" + Msg3 + "间隔不少于8天";//2022.2.21比选时间间隔业务逻辑修改 + } else if (defId == "bid_qualification"//公开招标-资格后审 + || defId == "bid_invitation"//邀请招标 + ) { + /*依法必招*/ + if (tendF == "open_tender_form_1") { + msg = Msg1 + "需与" + Msg3 + "间隔不少于20天,并且晚于或等于" + Msg2; + } else { + msg = Msg1 + "需与" + Msg3 + "间隔不少于15天,并且晚于或等于" + Msg2; + } + } else if (defId == "bid_prequalification"//公开招标-资格预审 + ) { + if (roomType == '1') {//预审阶段 + msg = Msg1 + "需与" + Msg2 + "间隔不少于5天"; + } else { //后审阶段 + /*依法必招*/ + if (tendF == "open_tender_form_1") { + msg = Msg1 + "需与" + Msg3 + "间隔不少于20天,并且晚于或等于" + Msg2; + } else { + msg = Msg1 + "需与" + Msg3 + "间隔不少于15天,并且晚于或等于" + Msg2; + } + } + } + + return msg; +} +export function AnnouncementGetMsg4(Msg1?: any, Msg2?: any) { + let msg = null; + let defId = getDefId(); + if (defId == "bid_prequalification"//公开招标-资格预审 + || defId == "bid_qualification"//公开招标-资格后审 + || defId == "bid_invitation"//邀请招标 + ) { + msg = Msg1 + "需与" + Msg2 + "相同"; + /* + * * -12- negotiation_competitive_public 竞争性谈判-公开参与 + * -13- negotiation_competitive_invite 竞争性谈判-邀请参与 + * * -14- negotiation_single 单一来源 + * * -6- comparison_one_prequalification 公开比选一阶段-资格预审 + * -7- comparison_multi_prequalification 公开比选多阶段-资格预审 + * -8- comparison_one 公开比选一阶段 + * -9- comparison_multi 公开比选多阶段 + * * -10- recruit 公开招募 即 单轮 + * */ + } else if (defId == "negotiation_competitive_public"//竞争性谈判-公开参与 + || defId == "negotiation_competitive_invite"//竞争性谈判-邀请参与 + || defId == "negotiation_single"//单一来源 + || defId == "negotiation_single_simple"//单一来源简化 + || defId == "comparison_one_prequalification"//公开比选一阶段-资格预审 + || defId == "comparison_multi_prequalification"//公开比选多阶段-资格预审 + || defId == "comparison_one"//公开比选一阶段 + || defId == "comparison_multi"//公开比选多阶段 + || defId == "recruit"//公开招募 即 单轮 + ) { + msg = Msg1 + "需晚于或等于" + Msg2; + } + + return msg; +} diff --git a/src/utils/Authorized.ts b/src/utils/Authorized.ts new file mode 100644 index 0000000..5c78964 --- /dev/null +++ b/src/utils/Authorized.ts @@ -0,0 +1,19 @@ +import RenderAuthorize from '@/components/Authorized'; +import { getAuthority } from './authority'; +/* eslint-disable eslint-comments/disable-enable-pair */ +/* eslint-disable import/no-mutable-exports */ +let Authorized = RenderAuthorize(getAuthority()); + +// Reload the rights component +const reloadAuthorized = (): void => { + Authorized = RenderAuthorize(getAuthority()); +}; + +/** + * hard code + * block need it。 + */ +window.reloadAuthorized = reloadAuthorized; + +export { reloadAuthorized }; +export default Authorized; diff --git a/src/utils/CommonUtils.ts b/src/utils/CommonUtils.ts new file mode 100644 index 0000000..52ee6b4 --- /dev/null +++ b/src/utils/CommonUtils.ts @@ -0,0 +1,338 @@ +/* + * @Author: liqiang + * @Date: 2020-11-24 15:26:54 + * @LastEditTime: 2021-03-05 13:49:12 + * @LastEditors: Please set LastEditors + * @Description: In User Settings Edit + * @FilePath: \ebtp-cloud-frontend\src\utils\CommonUtils.ts + */ + +/** + * 判断是否等于空 + * @param value + */ +export function isEmpty(value: any) { + return value === null || value === void 0 || value === ''; +} +/** + * 判断不等于空 + * @param value + */ +export function isNotEmpty(value: any) { + return value !== null && value !== void 0 && value !== ''; +} + +/** + * proTable下拉选格式转换 + * @param data 字典数据 + */ +export function proTableValueEnum(data: any) { + let json = {}; + if (isEmpty(data)) { + return json; + } + for (const item of data) { + json[item.code] = { text: item.dicName }; + } + return json; +} +/** + * 字典返回值 + * @param data 字典数据 + */ +export function returnDictVal(data: any, value: any) { + let val = ''; + if (isEmpty(data)) { + return val; + } + for (const item of data) { + item.code === value ? val = item.dicName : null; + } + return val; +} +/** + * procurementType标的类型转换多个 20220927 + */ +export function multipleTypeTransform(value: string | null | undefined, valueEnum: any): string { + if (valueEnum && value) { + return value.split(",").map(item => valueEnum[item].text).join(); + } + return "-"; +} + +/** + * 获取url路径信息 + * @param name + */ +export function getURLInformation(name: string) { + let reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i"); + let r = window.location.search.substr(1).match(reg); + return r !== null ? unescape(r[2]) : null; +} +/** + * 获取url路径参数信息 + * @param name + * @returns + */ +export function getUrlParam(name: string) { + var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"); //构造一个含有目标参数的正则表达式对象 + var r = window.location.search.substr(1).match(reg); //匹配目标参数 + if (r != null) return decodeURI(r[2]); //decodeURI参数内容。 + return null; //返回参数值 +} +/** + * 获取全部url路径信息 + * @param name + * @returns 包含全部参数的对象 + */ +export function getTotalURLInformation() { + let query: any = location.search.substring(1) + let params = {} + query = query.split('&') + query?.forEach((ele: any, index: any) => { + let q = query[index].split('=') + if (q.length == 2) { + params[q[0]] = q[1] + } + }); + return params +} +/** + * 跨工程跳转 + * @param url url多个参数 & => %26 + */ +export function JumpToOutside(url: string) { + const uri = encodeURIComponent(url) + window.location.href = (`http://10.242.31.158:8100/auth/oauth/authorize?response_type=code&client_id=KgPEkttG&redirect_uri=${uri}&mall3_token=${sessionStorage.getItem('Authorization')}`) +} + + + + +/** + * proTable下拉选格式转换 增加筛选 仅展示inspect中数据 + * @param data 字典数据 + */ +export function proTableValueEnumOther(data: any, inspect?: any) { + let json = {}; + if (isEmpty(data)) { + return json; + } + for (const item of data) { + if (inspect.toString().indexOf(item.code) >= 0) { + json[item.code] = { text: item.dicName }; + } + } + return json; +} +/** + * 根据字典值返回字典名称数据 + * @param dictData + * @param value + */ +export function getDictName(dictData: any, value: any) { + if (isEmpty(dictData)) { + return ''; + } + for (const item of dictData) { + if (value === item.code) { + return item.dicName; + } + } + return ''; +} +/** + * 根据采购方式获取proTypeCode + * @param bidMethodDict + */ +export function getProTypeCodeByBidMethodDict(bidMethodDict: any) { + if (isEmpty(bidMethodDict)) { + return ''; + } + let proTypeCode; + switch (bidMethodDict) { + case 'procurement_mode_1': + case 'procurement_mode_2': + proTypeCode = 'procurement_mode_1,procurement_mode_2'; + break; + case 'procurement_mode_3': + proTypeCode = 'procurement_mode_3'; + break; + case 'procurement_mode_4': + proTypeCode = 'procurement_mode_4'; + break; + case 'procurement_mode_5': + case 'procurement_mode_6': + proTypeCode = 'procurement_mode_5,procurement_mode_6'; + break; + case 'procurement_mode_7': + proTypeCode = 'procurement_mode_7'; + break; + case 'procurement_mode_8': + proTypeCode = 'procurement_mode_8'; + break; + case 'procurement_mode_9': + proTypeCode = 'procurement_mode_8'; + break; + default: + proTypeCode = ''; + } + return proTypeCode; +} +/** + * 根据获取字典名 + * @param data + * @param value + */ +export function getDictNameByVal(data: any[], value: any) { + if (isEmpty(data) || isEmpty(value)) { + return ""; + } + for (const item of data) { + if (item.code === String(value)) { + return item.dicName; + } + } + return ""; +} +/** + * 获取当前路由相对路径 + * @returns + */ +export function getUrlRelativePath() { + let url = document.location.toString(); + let arrUrl = url.split("//"); + let start = arrUrl[1].indexOf("/"); + let relUrl = arrUrl[1].substring(start); + if (relUrl.indexOf("?") != -1) { + relUrl = relUrl.split("?")[0]; + } + return relUrl; +} +/** + * 获取目标字符第几次出现的位置 + * @param str + * @param cha + * @param num + * @returns + */ +function findString(str: string, cha: string, num: number) { + let x = str.indexOf(cha); + for (var i = 0; i < num; i++) { + x = str.indexOf(cha, x + 1); + } + return x; +} + +const projectTypeCodeMaps = new Map(); +//招标 +projectTypeCodeMaps.set("/Bid", ["procurement_mode_1", "procurement_mode_2"]); +//比选 +projectTypeCodeMaps.set("/Comparison", ["procurement_mode_3"]); +//招募 +projectTypeCodeMaps.set("/Recruit", ["procurement_mode_4"]); +//谈判 +projectTypeCodeMaps.set("/Negotiation", ["procurement_mode_5", "procurement_mode_6",]); +//询价 +projectTypeCodeMaps.set("/Inquiry", ["procurement_mode_7"]); + +/** + * 获取ProTypeCode + * @returns + */ +export function getProjectTypeCode() { + let url = getUrlRelativePath(); + for (const item of projectTypeCodeMaps.keys()) { + if (url.indexOf(item) !== -1) { + return projectTypeCodeMaps.get(item); + } + } + return []; +} +/** + * 根据传入采购方式返回该路径 + * @param bidMethodDict + * @returns + */ +export function getBidMethodDictTypeCode(bidMethodDict: string) { + for (const [key, value] of projectTypeCodeMaps.entries()) { + if (value.indexOf(bidMethodDict) !== -1) { + return key; + } + } + let url = getUrlRelativePath(), + index = findString(url, "/", 1); + url = url.substring(0, index); + return url; +} +/** + * 将阿拉伯数字翻译成中文的大写数字 + * @param num + * @returns + */ +export const numberToChinese = (num: any) => { + var AA = new Array("零", "一", "二", "三", "四", "五", "六", "七", "八", "九", "十"); + var BB = new Array("", "十", "百", "仟", "萬", "億", "点", ""); + var a = ("" + num).replace(/(^0*)/g, "").split("."), + k = 0, + re = ""; + for (var i = a[0].length - 1; i >= 0; i--) { + switch (k) { + case 0: + re = BB[7] + re; + break; + case 4: + if (!new RegExp("0{4}//d{" + (a[0].length - i - 1) + "}$") + .test(a[0])) + re = BB[4] + re; + break; + case 8: + re = BB[5] + re; + BB[7] = BB[5]; + k = 0; + break; + } + if (k % 4 == 2 && a[0].charAt(i + 2) != '0' && a[0].charAt(i + 1) == '0') + re = AA[0] + re; + if (a[0].charAt(i) != '0') + re = AA[a[0].charAt(i)] + BB[k % 4] + re; + k++; + } + + if (a.length > 1) // 加上小数部分(如果有小数部分) + { + re += BB[6]; + for (var i = 0; i < a[1].length; i++) + re += AA[a[1].charAt(i)]; + } + if (re == '一十') + re = "十"; + if (re.match(/^一/) && re.length == 3) + re = re.replace("一", ""); + return re; +} +/** + * 页面内锚点滚动方法 + * @param anchorName + */ +export const scrollToAnchor = (anchorName: string) => { + if (anchorName) { + // 找到锚点 + let anchorElement = document.getElementById(anchorName); + // 如果对应id的锚点存在,就跳转到锚点 + if (anchorElement) { anchorElement.scrollIntoView({ block: 'start', behavior: 'smooth' }); } + } +} +/** + * 删除行首行尾的空白字符方法(包括空格、制表符、换页符等等) + * @param str + * @returns + */ +export const trim = (str: string): string => { + if (isNotEmpty(str)) { + let _str = str.replace(/(^\s*)|(\s*$)/g, ""); + _str = _str.replace(/[<>|\\/??::*""“”\s\r\n\t]/g, ""); + return _str; + } + return ''; +} \ No newline at end of file diff --git a/src/utils/CustomerService.ts b/src/utils/CustomerService.ts new file mode 100644 index 0000000..d23d9d6 --- /dev/null +++ b/src/utils/CustomerService.ts @@ -0,0 +1,69 @@ + /*客服系统专用*/ + //跨系统post传参 + export const bizServiceCustomService = REACT_APP_CUSTOMERSERVICE_USERCENTER + '&client_id=' + REACT_APP_CUSTOMERSERVICE_CLIENT_ID + '&redirect_uri=' + REACT_APP_CUSTOMERSERVICE_REDIRECT + '/redirect?page=home&mall3_token=';//智慧客服 + //export const bizServiceCustomService = REACT_APP_CUSTOMERSERVICE_USERCENTER + '&client_id=S00hFPxc&redirect_uri=http://localhost:3000/redirect?page=home&mall3_token=';//智慧客服 + export function windowOpenChatUI(inputList:any,pathname:string) { + if(inputList && inputList.length>0){ + var tempForm = document.getElementById('tempForm_CustomerService') as HTMLFormElement + if(tempForm) document.body.removeChild(tempForm); + tempForm = document.createElement("form") + tempForm.id="tempForm_CustomerService" + tempForm.method="post" + tempForm.action = bizServiceCustomService + sessionStorage.getItem('Authorization') + tempForm.target='_blank' + inputList.map((input: any)=>{ + let labelName= input.label!=null?`_CustomerServiceLabel_${input.label}`:'' + var hideInput = document.createElement("input") + hideInput.type="hidden" + hideInput.name= input.paraName + hideInput.value = input.isEncode?`${encodeURI(input.paraVal)}${labelName}`:`${input.paraVal}${labelName}` + tempForm.appendChild(hideInput) + }) + var input = document.createElement("input") + input.id = 'tempInput_CustomerService' + input.name= 'sceneUrl' + input.value= pathname + input.type="hidden" + tempForm.appendChild(input) + document.body.appendChild(tempForm); + if(tempForm){ + tempForm.submit(); + document.body.removeChild(tempForm); + } + } + } + //创建临时表单 + export function createHiddenForm(inputList:any,pathname:string) { + if(inputList && inputList.length>0){ + var tempForm = document.getElementById('tempForm_CustomerService') as HTMLFormElement + if(tempForm) document.body.removeChild(tempForm); + tempForm = document.createElement("form") + tempForm.id="tempForm_CustomerService" + tempForm.method="post" + tempForm.action = bizServiceCustomService + sessionStorage.getItem('Authorization') + tempForm.target='_blank' + inputList.map((input: any)=>{ + let labelName= input.label!=null?`_CustomerServiceLabel_${input.label}`:'' + var hideInput = document.createElement("input") + hideInput.type="hidden" + hideInput.name= input.paraName + hideInput.value = input.isEncode?`${encodeURI(input.paraVal)}${labelName}`:`${input.paraVal}${labelName}` + tempForm.appendChild(hideInput) + }) + var input = document.createElement("input") + input.id = 'tempInput_CustomerService' + input.name= 'sceneUrl' + input.value= pathname + input.type="hidden" + tempForm.appendChild(input) + document.body.appendChild(tempForm); + } + } + //提交临时表单 + export function submitHiddenForm() { + var tempForm = document.getElementById('tempForm_CustomerService') as HTMLFormElement + if(tempForm){ + tempForm.submit(); + document.body.removeChild(tempForm); + } + } \ No newline at end of file diff --git a/src/utils/DateUtils.ts b/src/utils/DateUtils.ts new file mode 100644 index 0000000..4937f7d --- /dev/null +++ b/src/utils/DateUtils.ts @@ -0,0 +1,181 @@ +/* + * @Author: liqiang + * @Date: 2020-12-02 14:25:23 + * @LastEditTime: 2021-03-25 15:46:32 + * @LastEditors: Please set LastEditors + * @Description: 日期工具类 + * @FilePath: \ebtp-cloud-frontend\src\utils\DateUtils.ts + */ + +import moment from "moment"; +import { isEmpty } from "./CommonUtils"; +/** + * 日期时间格式 + */ +export const dateTimeFormatter = 'yyyy-MM-DD HH:mm:ss'; + +/** + * 用于保存 日期格式化 + * @param date + */ +export function saveDateTimeFormatter(date: any) { + if (isEmpty(date)) { + return date; + } + return date.format(dateTimeFormatter); +} +/** + * 用于回显 日期格式化 + * @param date + */ +export function echoDateTimeFormatter(date: any) { + if (isEmpty(date)) { + return date; + } + return moment(date, dateTimeFormatter); +} +/** + * 判断当前时间是否超过指定时间 + */ +export function nowExceedSpecifiedTime(specifiedTime: string) { + let now = new Date(), + specified = new Date(specifiedTime); + return now.getTime() > specified.getTime(); +} + +export function showTimeDefaultValue() { + return moment('YYYY/MM/DD HH:mm:ss'); +} + +function range(start: any, end: any) { + const result = []; + for (let i = start; i < end; i++) { + result.push(i); + } + return result; +} +/** + * 禁止选择当前之前的日期 + * @param current + */ +export function datePickerDisabledDate(current: any) { + return current && current < moment().subtract(1, 'days').endOf('day'); +} +/** + * 禁止选择当前之前的时间 + * @param current + */ +export function datePickerDisabledTime(current: any) { + if (current) { + let today = moment().date(); + if (today == current.date()) { + let hour = Number(moment().hour()); + let minute = Number(moment().minutes()); + return { + disabledHours: () => range(0, hour), + disabledMinutes: () => hour === current.hour() ? range(0, minute) : [] + }; + } else { + return { + disabledHours: () => [], + disabledMinutes: () => [] + }; + } + } + return { + disabledHours: () => range(0, 24), + disabledMinutes: () => range(0, 60), + disabledSeconds: () => range(0, 60) + }; +} + +/** + * 判断当前时间是否在两个时间段之内 + * @param d1 开始时间 + * @param d2 结束时间 + */ +export function nowInDateBetwen(d1: any, d2: any) { + if (isEmpty(d1) || isEmpty(d2)) { + return false; + } + //如果时间格式是正确的,那下面这一步转化时间格式就可以不用了 + // let dateBegin = new Date(d1.replace(/-/g, "/"));//将-转化为/,使用new Date + // let dateEnd = new Date(d2.replace(/-/g, "/"));//将-转化为/,使用new Date + //将-转化为/,使用new Date + let dateBegin = new Date(d1), + //将-转化为/,使用new Date + dateEnd = new Date(d2), + //获取当前时间 + dateNow = new Date(); + let beginDiff = dateNow.getTime() - dateBegin.getTime();//时间差的毫秒数 + let beginDayDiff = Math.floor(beginDiff / (24 * 3600 * 1000));//计算出相差天数 + //时间差的毫秒数 + let endDiff = dateEnd.getTime() - dateNow.getTime(); + //计算出相差天数 + let endDayDiff = Math.floor(endDiff / (24 * 3600 * 1000)); + //已过期 + if (endDayDiff < 0) { + return false + } + //没到开始时间 + if (beginDayDiff < 0) { + return false; + } + return true; +} +/** + * 获取最大时间 + * @param arr + */ +export function getMaxDate(arr: string[]) { + if (isEmpty(arr) || arr.length === 0) { + return null; + } + let index = 0; + for (let i = 1; i < arr.length; i++) { + let date = new Date(arr[i]); + index = new Date(arr[index]).getTime() > date.getTime() ? index : i; + } + return arr[index]; +} +/** + * 判断两个日期间隔天数 + * @param date1 + * @param date2 + */ +export function judgmentIntervalDay(date1: any, date2: any) { + // let dateSpan, + // iDays; + // date1 = Date.parse(date1); + // date2 = Date.parse(date2); + // dateSpan = date2 - date1; + // dateSpan = Math.abs(dateSpan); + // iDays = Math.floor(dateSpan / (24 * 3600 * 1000)); + // return iDays + date1 = moment(date1).startOf('day') + date2 = moment(date2).startOf('day') + return date2?.diff(date1, "days") +}; +/** + * 判断第一个时间是否大于第二个 + * @param date1 + * @param date2 + */ +export function judgmentOfTwoTimePeriods(date1: string, date2: string) { + let d1 = new Date(date1), + d2 = new Date(date2); + return d1.getTime() > d2.getTime(); +} +/** + * 给日期加n天或者减n天 + * @param date + * @param day + */ +export function addOrSubtractADayFromTheDate(date: string, day: number) { + if(isEmpty(date)){ + return null; + } + let d1 = new Date(date); + let d2 = d1.setDate(d1.getDate() + day); + return moment(d2).format(dateTimeFormatter); +} diff --git a/src/utils/Download.js b/src/utils/Download.js new file mode 100644 index 0000000..640f52a --- /dev/null +++ b/src/utils/Download.js @@ -0,0 +1,164 @@ +/** + * @desc:这是一个文件下载组件 + * @param:参数说明 + * apiUrl:接口地址 + * objectId: objectId + * fileId: fileId + * icon: 下载图片设置 + * text: 下载文本设置 + * method: //请求方式 + * fileName: //下载文件命名 + * type: //文件格式 + * btnName: //按钮名称 + * form: //map集合 用到的参数 + * downFileBtnClass: 按钮样式设置 + * downFileBtnClass: 按钮样式设置 + * + */ +import React, { PureComponent } from 'react'; +import PropTypes from 'prop-types'; +import { Button, Icon, message } from 'antd'; +import { getSessionUserData, getUserToken } from '@/utils/session'; +import request from 'umi-request'; +import '@/assets/xsy_style.less' +import './utils.less' +import { downloadFileObjectId, downloadFile } from './DownloadUtils'; + + +class FileDown extends PureComponent { + constructor(props) { + super(props); + this.state = { + loadingStatus: true, + buttonDisabled: false + } + } + + //文件下载操作 + handleDownFile = (event, apiUrl, objectId, fileId, method, fileName, type, form) => { + event.preventDefault(); + event.stopPropagation(); + //开启loading 按钮置灰 + this.setState({ + loadingStatus: false, + buttonDisabled: true, + }); + if (objectId) { + downloadFileObjectId(objectId); + } else if (fileId) { + downloadFile({ uid: fileId }); + } else { + if (fileName != undefined) { + let haveParam = apiUrl.indexOf('?') != -1;//判断路径里是否有? + apiUrl = haveParam ? apiUrl + '&n=' + fileName : apiUrl + '?n=' + fileName + '.' + type; + } + window.location.href = apiUrl; + } + // window.fetch(apiUrl, { + // method: method, + // params: method === "GET" ? { ...form?.getFieldsValue() } : null, + // data: method === "POST" ? { ...form?.getFieldsValue() } : null, + // headers:{ + // JwtToken: getSessionUserData() == null ? null : getSessionUserData().userId, + // Authorization: getUserToken(), + // }, + // // 重要 + // responseType: 'blob', + // }).then(res => { + // // const blob = new Blob([res]); + // // const objectURL = URL.createObjectURL(blob); + // // let btn = document.createElement('a'); + // // btn.download = `${fileName}.${type}`; + // // btn.href = objectURL; + // // btn.click(); + // // URL.revokeObjectURL(objectURL); + // // btn = null; + // // 这里才是下载附件逻辑处理的地方 + // res.blob().then(blob => { + // const blobUrl = window.URL.createObjectURL(blob); + // const aElement = document.createElement("a"); + // const filename = `${fileName}.${type}`; // 设置文件名称 + // aElement.href = blobUrl; // 设置a标签路径 + // aElement.download = filename; + // aElement.click(); + // window.URL.revokeObjectURL(blobUrl); + // }); + + // this.setState({ + // loadingStatus: true, + // buttonDisabled: false, + // }); + // }).catch((error) => { + // //关闭loading 按钮恢复正常 + // this.setState({ + // loadingStatus: true, + // buttonDisabled: false, + // }); + // message.error('下载失败'); + // }); + setTimeout(() => { + this.setState({ + loadingStatus: true, + buttonDisabled: false, + }); + }, 1000); + }; + + render() { + const { apiUrl, objectId, fileId, icon, method, fileName, type, btnName, form, tag, } = + { + tag: "0", + ...this.props + }; + const { loadingStatus, buttonDisabled } = this.state; + + + return ( + <> + { + tag === 'a' ? + : + tag === 'vrbre' ? + : + + } + + ); + } +} + +//定义属性 类型以及是否必填项 +FileDown.proTypes = { + apiUrl: PropTypes.isRequired,//地址 + objectId: PropTypes.isRequired, //objectId + fileId: PropTypes.isRequired, //fileId + method: PropTypes.isRequired,//请求方式 + fileName: PropTypes.isRequired,//下载文件命名 + type: PropTypes.isRequired,//文件格式 + btnName: PropTypes.isRequired,//按钮名称 + form: PropTypes.isRequired,//map集合 用到的参数 +}; +//定义属性的默认值 +FileDown.defaultProps = { + icon: 'download', +}; +export default FileDown; diff --git a/src/utils/DownloadNew.tsx b/src/utils/DownloadNew.tsx new file mode 100644 index 0000000..e74fa8d --- /dev/null +++ b/src/utils/DownloadNew.tsx @@ -0,0 +1,100 @@ +import React, { useState, } from 'react'; +import { Button, message } from 'antd'; +import { getSessionUserData, getUserToken } from '@/utils/session'; +interface FileDownProps { + apiUrl?: any,//地址 + method?: any,//请求方式 + fileName?: any,//下载文件命名 + type?: any,//文件格式 + btnName?: any,//按钮名称 + form?: any,//map集合 用到的参数 + complete?: () => void,//李强 下载完执行刷新 + beforeClick?: () => Promise,//李丹 点击前调用 +} +const FileDown: React.FC = (props) => { + const { apiUrl, method, fileName, type, btnName, form, complete, beforeClick } = props + const [loadingStatus, loadingStatusSet] = useState(true); + const [buttonDisabled, buttonDisabledSet] = useState(false); + //文件下载操作 + async function handleDownFile(event: any, apiUrl: any, method: any, fileName: any, type: any, form: any) { + event.preventDefault(); + event.stopPropagation(); + //开启loading 按钮置灰 + loadingStatusSet(false); + buttonDisabledSet(true); + if (beforeClick != undefined) { + await beforeClick().then((res) => { + if (res) { + if (fileName != undefined) { + let haveParam = apiUrl.indexOf('?') != -1;//判断路径里是否有? + apiUrl = haveParam ? apiUrl + '&n=' + fileName : apiUrl + '?n=' + fileName + '.' + type; + } + window.location.href = apiUrl; + } + }).catch(() => { + loadingStatusSet(true); + buttonDisabledSet(false); + if (complete != undefined) { + complete(); + } + }) + } else { + window.location.href = apiUrl; + } + loadingStatusSet(true); + buttonDisabledSet(false); + if (complete != undefined) { + complete(); + } + // window.fetch(apiUrl, { + // method: method, + // params: method === "GET" && form != null ? { ...form?.getFieldsValue() } : null, + // data: method === "POST" && form != null ? { ...form?.getFieldsValue() } : null, + // headers: { + // JwtToken: getSessionUserData() == null ? null : getSessionUserData().userId, + // Authorization: getUserToken(), + // }, + // // 重要 + // responseType: 'blob', + // }).then(res => { + // // const blob = new Blob([res]); + // // const objectURL = URL.createObjectURL(blob); + // // let btn = document.createElement('a'); + // // btn.download = `${fileName}.${type}`; + // // btn.href = objectURL; + // // btn.click(); + // // URL.revokeObjectURL(objectURL); + // // btn = null; + // // 这里才是下载附件逻辑处理的地方 + // res.blob().then(blob => { + // const blobUrl = window.URL.createObjectURL(blob); + // const aElement = document.createElement("a"); + // const filename = `${fileName}.${type}`; // 设置文件名称 + // aElement.href = blobUrl; // 设置a标签路径 + // aElement.download = filename; + // aElement.click(); + // window.URL.revokeObjectURL(blobUrl); + // }); + // loadingStatusSet(true); + // buttonDisabledSet(false); + // complete(); + // }).catch((error) => { + // //关闭loading 按钮恢复正常 + // loadingStatusSet(true); + // buttonDisabledSet(false); + // complete(); + // message.error('下载失败'); + // }); + }; + + return ( + + ) +}; +export default FileDown; \ No newline at end of file diff --git a/src/utils/DownloadUtils.ts b/src/utils/DownloadUtils.ts new file mode 100644 index 0000000..1fca0a1 --- /dev/null +++ b/src/utils/DownloadUtils.ts @@ -0,0 +1,226 @@ +/* + * @Author: zhoujianlong + * @Date: 2022-03-03 09:06:36 + * @Last Modified by: zhoujianlong + * @Last Modified time: 2022-12-23 23:21:01 + */ + +import { getDownloadSecretKey, getFilelist, getFilelistBySecond } from "@/services/download_"; +import { message } from "antd"; +import { Dispatch, SetStateAction, useEffect, useRef, useState } from "react"; +import { isEmpty, isNotEmpty } from "./CommonUtils"; + +/** + * 文件上传 + */ +export const uploadAttachmentPath = '/api/doc/v1.0/files/upload'; +/** + * 获取密钥 + */ +export const downloadSecretKeyPath = '/api/doc/api/data-service-document-center/outer/v1.0/files/getSecretKey'; +/** + * 文件下载(必须有密钥) + */ +export const downloadAttachmentPath = '/api/doc/api/data-service-document-center/outer/v1.0/files/getDownload'; +/** + * 获取雪花id + */ +export const getSnowIdPath = '/api/core-service-ebtp-updownload/v1/business/id'; +/** + * 文件物理删除 + */ +export const removeFilePath = '/api/doc/v1.0/files/disk'; +/** + * 查询文件列表(根据objectId) + */ +export const findFilelistPath = '/api/doc/v1.0/files/queryReturn'; +/** + * 图片展示 + */ +export const pictureDisplayPath = '/api/doc/v1.0/files/display'; +/** + * 文件下载(不用文件流) + */ +export const downloadPath = '/api/doc/v1.0/files/download'; +/** + * 查询文件列表(根据2.0 bid) + */ +export const findFilelistPathBySecond = '/downloadfile/v1/file/getFileListById'; +/** +* 文件下载(根据2.0 bid fileId) +*/ +export const downloadPathBySecond = '/downloadfile/v1/file/downloadFileStreamById'; + +export interface FilelistProps { + uid: string, + name: string, + status: 'uploading' | 'done' | 'error' | 'removed', + url: string, +} +/** + * 校验3.0 ObjectId + * @param objectId + * @returns + */ +export const checkObjectId = (objectId: string) => { + const pattern = /[a-zA-Z]+/; + return objectId.length == 19 && !pattern.test(objectId); +} +/** + * 取当前时间时间戳(加密) + * @returns + */ +const getTimeStamp = () => { + const cipherMode = '1'; + const publicKey = '045631900E382D3DA75BD3E977CD6B28556DA3DF15820945F9BFB69E0F7456DF22D4EAB9CCD45B3B4959B85CEB4A2C4BB03AB5E4C08BA6A79E5B7C6AB63C20D932'; + const sm2 = require('sm-crypto').sm2; + const date = Math.round(new Date().getTime() / 1000); + return '04' + sm2.doEncrypt(date, publicKey, cipherMode); +} +/** + * 文件下载 + * @param {fileId} uid + */ +export const downloadFile = async ({ uid, name }: any) => { + if (isNotEmpty(uid)) { + if (checkObjectId(uid)) {//判断3.0 fileId + const keyRes = await getDownloadSecretKey({ fileId: uid });//获取key + keyRes?.success && (window.location.href = downloadAttachmentPath + '?fileId=' + uid + '&documentSecretKey=' + keyRes?.data); + } else { + window.location.href = downloadPathBySecond + '?id=' + uid + '&p=' + getTimeStamp(); + } + // keyRes?.success && window.fetch(downloadAttachmentPath + '?fileId=' + uid + '&documentSecretKey=' + keyRes?.data, { + // method: "GET", + // headers: { + // Authorization: getUserToken(), + // currentRoleCode: getSessionRoleData()?.roleCode, + // }, + // credentials: 'include', + // }).then((response) => { + // // 这里才是下载附件逻辑处理的地方 + // response.blob().then(blob => { + // const blobUrl = window.URL.createObjectURL(blob); + // const aElement = document.createElement("a"); + // aElement.href = blobUrl; // 设置a标签路径 + // aElement.download = name; + // aElement.click(); + // window.URL.revokeObjectURL(blobUrl); + // }); + // }); + } +} +/** + * objectId文件下载(只含一个文件) + * @param {业务Id} objectId + */ +export const downloadFileObjectId = (objectId: string) => { + if (isNotEmpty(objectId)) { + if (checkObjectId(objectId)) {//判断3.0 objectId + getFilelist([objectId]).then(res => { + if (res?.success && res?.data?.length > 0) { + downloadFile({ uid: res?.data[res?.data?.length - 1].fileId }); + } else { + message.info("文档中心错误或文件不存在"); + } + }) + } else { + window.location.href = downloadPathBySecond + '?id=' + objectId + '&p=' + getTimeStamp(); + } + } +} +/** + * objectId获取文件下载链接(只含一个文件) + * @param {业务Id} objectId + * @returns + */ +export const getDownloadFileUrl = async (objectId: string) => { + let url = null; + if (isNotEmpty(objectId)) { + if (checkObjectId(objectId)) {//判断3.0 objectId + await getFilelist([objectId]).then(async res => { + if (res?.success && res?.data?.length > 0) { + const keyRes = await getDownloadSecretKey({ fileId: res?.data[res?.data?.length - 1].fileId });//获取key + url = downloadAttachmentPath + '?fileId=' + res?.data[res?.data?.length - 1].fileId + '&documentSecretKey=' + keyRes?.data + } + }) + } else { + url = downloadPathBySecond + '?id=' + objectId + '&p=' + getTimeStamp(); + } + + } + return url; +} +/** + * objectId获取文件下载链接 + * @param objectId + * @returns + */ +export const useDownLoadUrl = (objectId: string): string[] => { + const [url, setUrl] = useState(""); + useEffect(() => { + const getFileUrl = async () => { + console.log("objectId", objectId); + await getFilelist([objectId]).then(async res => { + if (res?.success && res?.data?.length > 0) { + const keyRes = await getDownloadSecretKey({ fileId: res?.data[res?.data?.length - 1].fileId });//获取key + let url = downloadAttachmentPath + '?fileId=' + res?.data[res?.data?.length - 1].fileId + '&documentSecretKey=' + keyRes?.data; + setUrl(url); + } + }) + } + if (isNotEmpty(objectId)) { + if (checkObjectId(objectId)) {//判断3.0 objectId + getFileUrl(); + } else { + let url = downloadPathBySecond + '?id=' + objectId + '&p=' + getTimeStamp(); + setUrl(url); + } + + } + }, [objectId]) + + return [url]; +} +/** + * 获取文件列表 + * @param objectId + * @returns + */ +export async function getFileListByBid(objectId: string) { + let result: FilelistProps[] = []; + if (isEmpty(objectId)) { + return []; + } + if (checkObjectId(objectId)) {//判断3.0 objectId + return getFilelist([objectId]).then(res => { + if (res?.success && res?.data?.length > 0) { + res?.data?.forEach(({ fileId, originalName, filePath }: any) => { + result.push({ + uid: fileId, + name: originalName, + status: 'done', + url: originalName.endsWith(".png") || originalName.endsWith(".jpg") || originalName.endsWith(".jpeg") ? pictureDisplayPath + '?filePath=' + filePath : 'javascript:void(0);', + }) + }); + return result; + } + return []; + }) + } else { + return getFilelistBySecond(objectId, getTimeStamp()).then(response => response.json()).then(res => { + if (res?.length > 0) { + res?.forEach(({ id, bid, filename }: any) => { + result.push({ + uid: id, + name: filename, + status: 'done', + url: 'javascript:void(0);', + }) + }); + return result; + } + return []; + }) + } + +} \ No newline at end of file diff --git a/src/utils/ExtendUpload/index.tsx b/src/utils/ExtendUpload/index.tsx new file mode 100644 index 0000000..3e4571b --- /dev/null +++ b/src/utils/ExtendUpload/index.tsx @@ -0,0 +1,173 @@ +import React, { useEffect, useState } from 'react'; +import { Upload, Button, message, Modal, Spin } from "antd"; +import { UploadOutlined, CloseSquareOutlined, ExclamationCircleOutlined } from '@ant-design/icons'; +import { getSessionRoleData, getUserToken } from '@/utils/session'; +import { UploadProps } from 'antd/lib/upload/interface'; +import { downloadFile, getFileListByBid, uploadAttachmentPath } from '../DownloadUtils'; +import { createNewFileBid, removeFileByOid } from '@/services/download_'; + +interface ExtendUploadProps { + bid?: string; + value?: any; + onChange?: (value: any) => void; + btnName?: string; + maxCount?: number; + maxSize?: number; + uploadProps?: UploadProps; +} +const ExtendUpload: React.FC = (props) => { + + + const { bid, onChange, btnName, maxCount, maxSize, uploadProps } = { + maxCount: 0, + maxSize: 30, + btnName: "上传", + ...props + }; + + const [spin, setSpin] = useState(false);//加载 + const [returnValue, setReturnValue] = useState(""); + const [fileList, setFileList] = useState([]); + + const triggerChange = (changedValue: any) => { + if (onChange) { + onChange(changedValue); + } + }; + + useEffect(() => { + initBidValue(bid) + }, [bid]) + + //初始化bid方法 + const initBidValue = async (bid: any) => { + if (bid !== "" && bid !== null && bid !== undefined) { + fileListById(bid) + setReturnValue(bid); + } else { + await createNewFileBid().then(res => { + setReturnValue(res.id); + triggerChange(""); + }) + } + } + + const fileBeforeUpload = (curFile: any, curFileList: any) => { + const promise = new Promise((resolve, reject) => { + if (maxSize === 0) { + + } else { + let curSize = curFile.size / 1024 / 1024; + if (maxSize <= curSize) { + message.error(`当前附件大小为"` + curSize.toFixed(2) + `M",超过允许的最大值"` + maxSize + `M",不可以继续上传!`); + reject(false); + } + } + if (maxCount === 0) { + + } else { + let curCount = fileList.length; + if (maxCount <= curCount) { + message.error(`当前附件数量为"` + curCount + `",已经达到允许的最大数量"` + maxCount + `",不可以继续上传!`); + reject(false); + } + } + resolve(curFile); + }); + return promise; + } + //fileChange中查询文件列表的方法封装 + const fileListById = (fileId: any) => { + getFileListByBid(fileId).then(res => { + setFileList(res); + if (res?.length > 0) { + triggerChange(fileId); + } else { + triggerChange(""); + } + }).finally(() => { + setSpin(false); + }) + } + + const fileChange = async (info: any) => { + const { file, fileList } = info; + setSpin(true); + if (file.status === 'uploading' || file.status === 'removed' || file.status === 'done' || file.status === 'error') { + if (file.status === 'uploading') { + setFileList(fileList); + } else { + if (file.status === 'removed') { + if (file?.uid !== "") { + await removeFileByOid(file.uid) + } + message.success("删除成功"); + } else if (file.status === 'done') { + if (file?.response?.success) { + message.success("上传成功"); + } else { + message.warn(file.response.message); + } + } else if (file.status === 'error') { + message.error("上传服务错误,请稍后再试"); + } + //重新获取文件列表并确认是否返回文件id + fileListById(returnValue) + } + } else { + fileListById(returnValue) + } + } + + const fileRemove = (info: any) => { + const promise = new Promise(function (resolve, reject) { + Modal.confirm({ + title: '删除附件', + icon: , + content: '确定要删除选中的附件?', + centered: true, + onOk() { + resolve(true); + }, + onCancel() { + reject(); + }, + }); + }); + return promise; + } + + return ( + <> + + , + }} + fileList={fileList} + > + {!uploadProps?.disabled ? + + : null} + + + + ) +} +export default ExtendUpload diff --git a/src/utils/FlowUtils.ts b/src/utils/FlowUtils.ts new file mode 100644 index 0000000..b871dde --- /dev/null +++ b/src/utils/FlowUtils.ts @@ -0,0 +1,283 @@ +/* + * @Author:liqiang + * @Date: 2021-02-07 10:35:17 + * @LastEditTime: 2021-04-02 16:35:09 + * @Description: 根据流程不同显示不同名称 + * @FilePath: \ebtp-cloud-frontend\src\utils\Flow.ts + */ + +import { isEmpty } from "./CommonUtils"; +import { getDefId } from "./session"; + +export const moduleName = { + //名称(招标、资审、招募) + name: 'name', + //标段名称 + section: 'section', + //文件名称 (资审 招标 采购 招募 询价) + fileName: 'fileName', + //(投标 应答 资审投标) + response: 'response', + //费用名 + cost: 'cost', + //开标 评审 + review: 'review' +} + +export const flowName = [ + '', + 'bid_prequalification', + 'bid_qualification', + 'bid_centralized_prequalification', + 'bid_centralized_prequalification_bid', + 'bid_invitation', + 'comparison_one_prequalification', + 'comparison_multi_prequalification', + 'comparison_one', + 'comparison_multi', + 'recruit', + 'recruit_multi', + 'negotiation_competitive_public', + 'negotiation_competitive_invite', + 'negotiation_single', + 'inquiry', + 'auction', +]; + +//流程map +const flow = setFlowName(); + +/** + * 根据传入模块名获取流程名称 + * @param name + */ +export function getFlowName(name: string) { + let defId = String(getDefId()), + data = flow.get(defId); + if (isEmpty(defId) || isEmpty(data)) { + return ''; + } + return isEmpty(data[name]) ? "" : data[name]; +} + +export function getAllFlowNameByRoomType(bidMethodDict: any, roomType: any) { + if (bidMethodDict === 'procurement_mode_1' && roomType === '2') { + return getbidQualification(); + } else if (bidMethodDict === 'procurement_mode_3' && roomType === '2') { + return getComparisonOne(); + } + return getAllFlowName(); +} +/** + * 获取招标后审名称 + * @returns + */ +export function getbidQualification() { + let defId = flowName[2]; + return flow.get(defId); +} +/** + * 获取比选后审名称 + */ +export function getComparisonOne() { + let defId = String(getDefId()); + switch (defId) { + //公开比选一阶段-资格预审 + case "comparison_one_prequalification": + // 公开比选一阶段 + case "comparison_one": + return flow.get("comparison_one"); + //公开比选多阶段-资格预审 + case "comparison_multi_prequalification": + //公开比选多阶段 + case "comparison_multi": + return flow.get("comparison_multi"); + default: + return {}; + } +} +/** + * 获取流程所有数据名称 + * @param name + */ +export function getAllFlowName() { + let defId = String(getDefId()), + data = flow.get(defId); + return isEmpty(data) ? {} : data; +} +/** + * 设置流程名称 + */ +function setFlowName() { + let map = new Map(); + for (let i = 1; i < flowName.length; i++) { + map.set(flowName[i], dependingOnTheProcess(i)); + } + return map; +} +/** + * 根据流程不同显示不同名称 + * -1- 公开招标-资格预审 + * -2- 公开招标-资格后审 + * -3- 公开招标-集中资格预审 + * -4- 公开招标-集中资格预审招标 + * -5- 邀请招标 + * -6- 公开比选一阶段-资格预审 + * -7- 公开比选多阶段-资格预审 + * -8- 公开比选一阶段 + * -9- 公开比选多阶段 + * -10- 公开招募 + * -11- 常态化招募 + * -12- 竞争性谈判-公开参与 + * -13- 竞争性谈判-邀请参与 + * -14- 单一来源 + * -15- 询价 + * -16- 内拍 + * @param i + */ +function dependingOnTheProcess(i: number) { + let data = {}; + switch (i) { + //公开招标-资格预审 + case 1: + data[moduleName.section] = '标段'; + data[moduleName.fileName] = '资审'; + data[moduleName.name] = '资审'; + data[moduleName.response] = '投标'; + data[moduleName.cost] = '标书费(元)'; + data[moduleName.review] = '开标'; + break; + //公开招标-资格后审 + case 2: + data[moduleName.section] = '标段'; + data[moduleName.fileName] = '招标'; + data[moduleName.name] = '招标'; + data[moduleName.response] = '投标'; + data[moduleName.cost] = '标书费(元)'; + data[moduleName.review] = '开标'; + break; + //公开招标-集中资格预审 + case 3: + data[moduleName.section] = '标段'; + data[moduleName.fileName] = '资审'; + data[moduleName.name] = '资审'; + data[moduleName.response] = '投标'; + data[moduleName.cost] = '标书费(元)'; + data[moduleName.review] = '开标'; + break; + //公开招标-集中资格预审招标 + case 4: + data[moduleName.section] = '标段'; + data[moduleName.fileName] = '资审'; + data[moduleName.name] = '资审'; + data[moduleName.response] = '投标'; + data[moduleName.cost] = '标书费(元)'; + data[moduleName.review] = '开标'; + break; + //邀请招标 + case 5: + data[moduleName.section] = '标段'; + data[moduleName.fileName] = '招标'; + data[moduleName.name] = '招标'; + data[moduleName.response] = '投标'; + data[moduleName.cost] = '标书费(元)'; + data[moduleName.review] = '开标'; + break; + //公开比选一阶段-资格预审 + case 6: + data[moduleName.section] = '采购包'; + data[moduleName.fileName] = '资审'; + data[moduleName.name] = '资审'; + data[moduleName.response] = '应答'; + data[moduleName.cost] = '采购文件费用(元)'; + data[moduleName.review] = '开启'; + break; + //公开比选多阶段-资格预审 + case 7: + data[moduleName.section] = '采购包'; + data[moduleName.fileName] = '资审'; + data[moduleName.name] = '资审'; + data[moduleName.response] = '应答'; + data[moduleName.cost] = '采购文件费用(元)'; + data[moduleName.review] = '开始评审'; + break; + //公开比选一阶段 + case 8: + data[moduleName.section] = '采购包'; + data[moduleName.fileName] = '采购'; + data[moduleName.name] = '采购'; + data[moduleName.response] = '应答'; + data[moduleName.cost] = '采购文件费用(元)'; + data[moduleName.review] = '开启'; + break; + //公开比选多阶段 + case 9: + data[moduleName.section] = '采购包'; + data[moduleName.fileName] = '采购'; + data[moduleName.name] = '采购'; + data[moduleName.response] = '应答'; + data[moduleName.cost] = '采购文件费用(元)'; + data[moduleName.review] = '开始评审'; + break; + // 公开招募 + case 10: + data[moduleName.section] = '包件'; + data[moduleName.fileName] = '招募'; + data[moduleName.name] = '招募'; + data[moduleName.response] = '应答'; + data[moduleName.cost] = '招募文件费用(元)'; + data[moduleName.review] = '开始评审'; + break; + //常态化招募 + case 11: + data[moduleName.section] = '包件'; + data[moduleName.fileName] = '招募'; + data[moduleName.name] = '招募'; + data[moduleName.response] = '应答'; + data[moduleName.cost] = '招募文件费用(元)'; + data[moduleName.review] = '开始评审'; + break; + //竞争性谈判-公开参与 + case 12: + data[moduleName.section] = '采购包'; + data[moduleName.fileName] = '采购'; + data[moduleName.name] = '采购'; + data[moduleName.response] = '应答'; + data[moduleName.cost] = '采购文件费用(元)'; + data[moduleName.review] = '开始评审'; + break; + //竞争性谈判-邀请参与 + case 13: + data[moduleName.section] = '采购包'; + data[moduleName.fileName] = '采购'; + data[moduleName.name] = '采购'; + data[moduleName.response] = '应答'; + data[moduleName.cost] = '采购文件费用(元)'; + data[moduleName.review] = '开始评审'; + break; + //单一来源 + case 14: + data[moduleName.section] = '采购包'; + data[moduleName.fileName] = '采购'; + data[moduleName.name] = '采购'; + data[moduleName.response] = '应答'; + data[moduleName.cost] = '采购文件费用(元)'; + data[moduleName.review] = '评审'; + break; + //询价 + case 15: + data[moduleName.section] = '采购包'; + data[moduleName.fileName] = '询价'; + data[moduleName.name] = '询价'; + data[moduleName.response] = '应答'; + data[moduleName.cost] = '询价文件费用(元)'; + data[moduleName.review] = '评审'; + break; + //内拍 + case 16: + break; + default: + } + return data; +} + diff --git a/src/utils/IParticipateIn.tsx b/src/utils/IParticipateIn.tsx new file mode 100644 index 0000000..f6aa773 --- /dev/null +++ b/src/utils/IParticipateIn.tsx @@ -0,0 +1,369 @@ +/* + * @Author: liqiang + * @Date: 2021-03-04 17:19:02 + * @LastEditTime: 2021-04-01 14:05:08 + * @LastEditors: Please set LastEditors + * @Description: In User Settings Edit + * @FilePath: \ebtp-cloud-frontend\src\utils\IParticipateIn.tsx + */ +import { participationSave, participationSaveOther } from '@/pages/Tender/supplier/LookingForBusinessOpportunities/service'; +import ProTable from '@ant-design/pro-table'; +import { Button, Card, Checkbox, Form, Input, message, Modal } from 'antd'; +import React, { useEffect, useState } from 'react'; +import { useHistory } from 'umi'; +import { getBidMethodDictTypeCode, getProTypeCodeByBidMethodDict, isNotEmpty } from './CommonUtils'; +import { queryingPagingData } from './PageUtils'; + +interface IParticipateInItem { + projectData: any, + visible: boolean, + setVisible: (value: boolean) => void +} + +/** + * 获取标段名称 + * @param bidMethodDict + */ +function getBsName(bidMethodDict: string) { + if (bidMethodDict.indexOf("procurement_mode_4") !== -1) { + return '包件'; + } + if (bidMethodDict.indexOf("procurement_mode_3") !== -1 || bidMethodDict.indexOf("procurement_mode_5") !== -1) { + return '采购包'; + } + return '标段'; +} + +function getSectionCheckbox(data: any) { + let value = []; + let flag = true; + for (const item of data) { + if (flag) { + value.push( + + {item.bsName} + + ) + flag = false; + } else { + value.push( + + {item.bsName} + + ) + } + + } + return value; +} +const modalHeight = innerHeight * 96 / 100; +/** + * 我要参与 + * @param props + */ +const IParticipateIn: React.FC = (props) => { + const { projectData, visible, setVisible } = props; + const [form] = Form.useForm(); + //保存遮罩 + const [spinningLoading, setSpinningLoading] = useState(false); + //常用联系人模态框 + const [contactsVisible, setContactsVisible] = useState(false); + //标段名称 + const [bsName, setBsName] = useState(''); + //标段多选 + const [sectionCheckbox, setSectionCheckbox] = useState(); + //采购方式 + const [bidMethodDict, setBidMethodDict] = useState(''); + const history = useHistory(); + //联系人数据 + const [contactsItem, setContactsItem] = useState(null); + useEffect(() => { + if (isNotEmpty(projectData)) { + setBsName(getBsName(projectData.bidMethodDict)); + setBidMethodDict(projectData.bidMethodDict); + //标段信息 + let sectionVOList = projectData.sectionVOList; + if (sectionVOList.length === 0) { + // 当前项目报名截止! + message.warning('当前项目报名截止!'); + return; + } + setSectionCheckbox(getSectionCheckbox(sectionVOList)); + form.resetFields(); + setContactsItem(null); + let examinationMethodDict = ""; + if (bidMethodDict.indexOf("procurement_mode_4") > -1) { + examinationMethodDict = projectData?.examinationMethodDict.replace("recruitment_method_", "") + } + form.setFieldsValue({ + recruitType: examinationMethodDict, + projectId: projectData.id, + roomType: projectData.roomType + }) + } + }, [projectData]); + + /** + * 表单提交 + * @param value + */ + const formOnFinish = (value: any) => { + setSpinningLoading(true); + // value.bizSupplierContact = contactsItem === null ? { + // contactName: value.contactName, + // contactTelephone: value.contactTelephone, + // contactEmail: value.contactEmail, + // contactAddress: value.contactAddress, + // fixedLine: value.fixedLine, + // contactFax: value.contactFax + // } : contactsItem; + value.bizSupplierContact = form.getFieldsValue(); + delete value['id']; + /*招募方式 调用特殊接口 2021 02 08 dqh*/ + if (bidMethodDict.indexOf("procurement_mode_4") > -1) { + participationSaveOther(value).then(res => { + if (res.data) { + message.success('操作成功!', 2, () => { + history.push(`${getBidMethodDictTypeCode(bidMethodDict)}/Involved`); + setSpinningLoading(false); + }); + } else { + setSpinningLoading(false); + message.error('操作失败!'); + } + }) + } else { + participationSave(value).then(res => { + if (res.data) { + message.success('操作成功!', 2, () => { + history.push(`${getBidMethodDictTypeCode(bidMethodDict)}/Involved`); + setSpinningLoading(false); + }); + } else { + setSpinningLoading(false); + message.error('操作失败!'); + } + }) + } + } + + /** + * 常用联系人 + */ + const contacts = () => { + const onCancel = () => setContactsVisible(false); + const select = (data: any) => { + form.setFieldsValue(data); + setContactsItem(data); + setContactsVisible(false); + } + + const columns: any[] = [ + { + title: '序号', + valueType: 'index', + width: '7%' + }, + { + title: '姓名', + dataIndex: 'contactName', + width: '15%' + }, + { + title: 'id', + dataIndex: 'id', + hideInTable: true, + }, + { + title: '手机号码', + dataIndex: 'contactTelephone', + search: false, + width: '15%' + }, + { + title: '地址', + dataIndex: 'contactAddress', + search: false, + width: '25%' + }, + { + title: '电子邮箱', + dataIndex: 'contactEmail', + search: false, + width: '13%' + }, + { + title: '操作', + valueType: 'option', + width: '5%', + render: (_: any, record: any) => [ + select(record)}>选择 + ] + }, + ] + return ( + <> + + + queryingPagingData('/api/biz-service-ebtp-tender/v1/bizsuppliercontact/getSupplierContactByParam', 'post', params)} + /> + + + + ) + } + + + const createForm = () => { + return (
+

+ 您即将参与 {projectData?.projectName},请填写下列信息: +

+ + + + + + + setContactsVisible(true)}>常用联系人)} /> + + + 平台短信提醒功能仅支持联通号段,其他运营商号段暂不支持} + > + + + + + + + + + + + + + + + + + + + + + + + {sectionCheckbox} + + + +
+ ) + } + /** + * 我要参与 + */ + const modalBox = () => { + const OnOk = (): void => form.submit(); + const onCancel = (): void => setVisible(false); + return ( + <> + + 取消 + , + , + ]} + > + {createForm()} + + {contacts()} + + ) + } + + return modalBox(); +} + +export default IParticipateIn; \ No newline at end of file diff --git a/src/utils/InquiryBox.tsx b/src/utils/InquiryBox.tsx new file mode 100644 index 0000000..d3675b1 --- /dev/null +++ b/src/utils/InquiryBox.tsx @@ -0,0 +1,32 @@ +import { Modal } from 'antd'; +import React from 'react'; + +interface InquiryBoxItem { + visible: boolean, + message: string, + data: any, + setVisible: (value: boolean) => void, + onOk: (data: any) => void +} +/** + * 询问框 + * @param props + */ +const InquiryBox: React.FC = (props) => { + const { visible, message, data, setVisible, onOk } = props; + return ( + <> + setVisible(false)} + onOk={() => onOk(data)} + > + {message} + + + ) +} +export default InquiryBox; \ No newline at end of file diff --git a/src/utils/InvitationLetter.tsx b/src/utils/InvitationLetter.tsx new file mode 100644 index 0000000..daf885b --- /dev/null +++ b/src/utils/InvitationLetter.tsx @@ -0,0 +1,84 @@ +/* + * @Author: liqiang + * @Date: 2021-03-05 13:55:50 + * @LastEditTime: 2021-03-05 14:42:50 + * @LastEditors: Please set LastEditors + * @Description: 邀请函信息 + * @FilePath: \ebtp-cloud-frontend\src\utils\InvitationLetter.tsx + */ +import { getNoticeInfo } from '@/pages/Bid/Supplier/InvitationDetails/service'; +import { Button, Modal, Tabs } from 'antd'; +import React, { useEffect, useState } from 'react'; +import { isNotEmpty } from './CommonUtils'; +import ExtendUpload from './ExtendUpload'; + +interface InvitationLetterItem { + projectData: any, + visible: boolean, + setVisible: (value: boolean) => void +} +const { TabPane } = Tabs; +const modalHeight = innerHeight * 96 / 100; +const InvitationLetter: React.FC = (props) => { + const { projectData, visible, setVisible } = props; + const [announcementInformation, setAnnouncementInformation] = useState(); + useEffect(() => { + if (isNotEmpty(projectData)) { + getNoticeInfo(projectData.annoIds).then(res => { + setAnnouncementInformation(getAnnouncementInformation(res.data)); + }) + } + }, [projectData]); + + /** + * 获取邀请函 + * @param data + */ + const getAnnouncementInformation = (data: any) => { + if (data.length === 0) { + return
+

该项目没有公告

+
+ } + return ( + + {data.map((item: any, index: number) => { + return ( +
+

{String(item.annoNature) === '7' && '【变更公告】'}{item.annoTitle}

+
+

+

+ +
+ ) + }) + } +
+ ) + } + /** + * 关闭 + */ + const close = () => { + setVisible(false); + setAnnouncementInformation(null); + } + + return 取消 + ]} + > + {announcementInformation} + +} + +export default InvitationLetter; \ No newline at end of file diff --git a/src/utils/IpassVerification.ts b/src/utils/IpassVerification.ts new file mode 100644 index 0000000..1a646e4 --- /dev/null +++ b/src/utils/IpassVerification.ts @@ -0,0 +1,148 @@ +/* + * @Author: liqiang + * @Date: 2021-02-16 16:35:14 + * @LastEditTime: 2021-04-06 16:55:24 + * @LastEditors: Please set LastEditors + * @Description: ipass验证 + * @FilePath: \ebtp-cloud-frontend\src\utils\IpassVerification.ts + */ +import request from './request'; +import * as zwPlugin from './zwPlugin'; +import { Modal } from 'antd'; +const ccitCont1Value = 'CCIT Smartcard CSP V1.0'; +const ccitCont = ['CCITCont2', '2']; +const deviceDefault = ['DEVICE_DEFAULT', '1']; +const deviceDefaultValue = 'DEVICE_DEFAULT'; +const ccitCont2 = 'CCITCont2'; +const ipassKey = "12312312321"; +/** + * 上传验证供应商(验证组织结构代码) + */ +export function verificationSupplier(value:string) { + //判断是否安装控件 + if (!zwPlugin.CheckComSetup()) { + warning("未检测到控件,请先安装控件!"); + return false; + } + //获取版本号 + // let version = zwPlugin.getVersion(); + //判断是否插入key 0未插入 1已插入 + if (zwPlugin.isUKConnect() == 0) { + warning('请插入您的IPASS设备后重试!'); + return false; + } + //获取CSP + let cspNamebypid = zwPlugin.getCSPNamebypid(); + let contName = cspNamebypid === ccitCont1Value ? deviceDefaultValue : ccitCont2; + //初始化密钥服务提供者 + if (!zwPlugin.initProv(cspNamebypid, contName)) { + warning('初始化失败!'); + return false; + } + //获取证书 + let cert = ccitCont; + if (cspNamebypid === ccitCont1Value) { + cert = ['CCITCont1', '2']; + } + //获取证书 + let certificate = zwPlugin.getCert(cert[0], cert[1]); + if (certificate === null) { + warning('获取IPASS证书失败!'); + return false; + } + //获取组织机构代码 + let certExtension = zwPlugin.getCertExtension(certificate, '1.3.6.1.4.1.5315.100.5.13'); + //验证组织结构代码 + if (certExtension.toUpperCase() === value.toUpperCase()) { + return true; + } else { + warning(`IPASS代码(${certExtension})与组织机构代码(${value})不一致,验证失败!`); + return false; + } +} +/** + * 获取证书 + */ +function getCertificate(cspNamebypid: string) { + let cert = ccitCont; + if (cspNamebypid === ccitCont1Value) { + cert = deviceDefault; + } + //获取证书 + return zwPlugin.getCert(cert[0], cert[1]); +} + +function ipassVerification() { + //判断是否安装控件 + if (!zwPlugin.CheckComSetup()) { + warning("未检测到控件,请先安装控件!"); + return false; + } + //获取版本号 + // let version = zwPlugin.getVersion(); + //判断是否插入key 0未插入 1已插入 + if (zwPlugin.isUKConnect() == 0) { + warning('请插入您的IPASS设备后重试!'); + return false; + } + //获取CSP + let cspNamebypid = zwPlugin.getCSPNamebypid(); + let contName = cspNamebypid === ccitCont1Value ? deviceDefaultValue : ccitCont2; + //初始化密钥服务提供者 + if (!zwPlugin.initProv(cspNamebypid, contName)) { + warning('初始化失败!'); + return false; + } + //获取证书 + let certificate = getCertificate(cspNamebypid); + if (certificate === null) { + warning('获取IPASS证书失败!'); + return false; + } + return true; +} +/** + * ipass解密 + * @param value + */ +export function ipassDecrypt(value: string) { + if (!ipassVerification()) { + return null; + } + //解密 + let asymDecrypt = zwPlugin.AsymDecrypt(value); + if (asymDecrypt === null) { + warning('解密失败!'); + return null; + } + return asymDecrypt; +} + + +/** + * 提示框 + * @param info + */ +function warning(info: string) { + Modal.warning({ + title: info, + centered: true + }); +} + +/** + * 验证账号密码 + */ +function verifyYourAccountPassword() { + let srcData = 'ALG_SIGN_RsaWithSHA1', iSignAlg = '2'; + let signData = zwPlugin.signatureWithAlg(srcData, iSignAlg); + return signData; +} + + +/** + * 根据id获取项目信息 + */ +export async function isIPassDecode(id: any) { + return request('/api/biz-service-ebtp-project/v1/projectRecord/' + id); +} diff --git a/src/utils/MessageUtils.ts b/src/utils/MessageUtils.ts new file mode 100644 index 0000000..232fb98 --- /dev/null +++ b/src/utils/MessageUtils.ts @@ -0,0 +1,59 @@ +import { message, Modal } from "antd"; + +/* + * @Author: liqiang + * @Date: 2020-11-30 10:57:11 + * @LastEditTime: 2021-01-25 09:35:01 + * @LastEditors: Please set LastEditors + * @Description: 消息提示 + * @FilePath: \ebtp-cloud-frontend\src\utils\MessageUtils.ts + */ +/** + * 保存修改提示 + * @param res + */ +export function saveMessage(res: any) { + if (res.code === 200) { + if (res.data) { + message.success('保存成功!'); + return true; + } else { + message.error('操作失败!'); + return false; + } + } + return false; +} +/** + * 删除提示 + * @param res + */ +export function deleteMessage(res: any) { + if (res.code === 200) { + if (res.data) { + message.success('删除成功!'); + return true; + } else { + message.error('操作失败!'); + return false; + } + } + return false; + +} +/** + * 通用消息 + * @param res + */ +export function commonMessage(res: any) { + if (res.code === 200) { + if (res.data) { + message.success('操作成功!'); + return true; + } else { + message.error('操作失败!'); + return false; + } + } + return false; +} \ No newline at end of file diff --git a/src/utils/NumberUtils.ts b/src/utils/NumberUtils.ts new file mode 100644 index 0000000..a504a5a --- /dev/null +++ b/src/utils/NumberUtils.ts @@ -0,0 +1,96 @@ +import { isEmpty } from '@/utils/CommonUtils'; +/* + * @Author: liqiang + * @Date: 2020-11-27 16:12:36 + * @LastEditTime: 2021-03-30 15:52:01 + * @LastEditors: Please set LastEditors + * @Description: 数字工具类 + * @FilePath: \ebtp-cloud-frontend\src\utils\NumberUtils.ts + */ +/** + * 金额正则 + */ +const amountReplace = /(\d)(?=(\d{3})+(?!\d))/g; + +function getZero(num: number) { + let number = ''; + for (let i = 0; i < num; i++) { + number += '0'; + } + return number; +} +/** + * 数字转换金额格式 + * @param money 数字 + * @param retain 小数点后保留几位 + */ +export function digitalConversionAmount(money: string, retain: number) { + let zero = getZero(retain); + if (isEmpty(money)) { + return money; + } + if (money.indexOf('.') === -1) { + money = money.replace(amountReplace, '$1,') + '.' + zero; + } else { + let division = money.split('.'); + money = division[0].replace(amountReplace, '$1,'); + money = money + '.' + (division[1] + zero).substr(0, retain); + } + return money; +}; + +/** + * 根据传入的数字保留几位小数 + * @param number 数字 + * @param retain 小数点后保留几位 + */ +export function enterTheNumberToRetainTheDecimal(number: any, retain: number) { + if (isEmpty(number)) { + return number; + } + let index = String(number).indexOf('.'); + if (index === -1) { + return number; + } else { + number = String(number).substring(0, index + (retain + 1)); + return number; + } +} + +/** + * 加法 两个数相加 + * @param arg1 + * @param arg2 + * @returns + */ +export function algebraicAddition(arg1: number, arg2: number) { + let r1, r2, m, c; + try { + r1 = arg1.toString().split(".")[1].length; + } + catch (e) { + r1 = 0; + } + try { + r2 = arg2.toString().split(".")[1].length; + } + catch (e) { + r2 = 0; + } + c = Math.abs(r1 - r2); + m = Math.pow(10, Math.max(r1, r2)); + if (c > 0) { + let cm = Math.pow(10, c); + if (r1 > r2) { + arg1 = Number(arg1.toString().replace(".", "")); + arg2 = Number(arg2.toString().replace(".", "")) * cm; + } else { + arg1 = Number(arg1.toString().replace(".", "")) * cm; + arg2 = Number(arg2.toString().replace(".", "")); + } + } else { + arg1 = Number(arg1.toString().replace(".", "")); + arg2 = Number(arg2.toString().replace(".", "")); + } + return (arg1 + arg2) / m; +} diff --git a/src/utils/PageUtils.ts b/src/utils/PageUtils.ts new file mode 100644 index 0000000..db86c6d --- /dev/null +++ b/src/utils/PageUtils.ts @@ -0,0 +1,87 @@ +/* + * @Author: liqiang + * @Date: 2020-11-21 12:29:53 + * @LastEditTime: 2020-12-14 17:13:46 + * @LastEditors: Please set LastEditors + * @Description: In User Settings Edit + * @FilePath: \ebtp-cloud-frontend\src\utils\PageUtils.ts + */ +import request from '@/utils/request'; +import { RequestData } from '@ant-design/pro-table'; + +function requestData(data: any, success: boolean, total: number) { + return { + data: data, + success: success, + total: total, + } +} + +function setBasePageRequest(params: any) { + return { + ...params, + basePageRequest: { + "pageNo": params.current, + "pageSize": params.pageSize + } + }; +} + +/** + * 用于ProTable + * @param api 后台api路径 (/api/...) + * @param method 请求方法(get, post...) + * @param params 对象数据 ({}) + */ +export function queryingPagingData(api: string, method: string, params: any) { + sessionStorage.setItem("projectListPrm", JSON.stringify(params)); + return new Promise>((resolve, reject) => { + let parameters = setBasePageRequest(params); + get(api, method, parameters).then(res => { + if (res.code === 200) { + resolve(requestData(res.data.records, res.success, res.data.total)); + } else { + reject(requestData([], false, 0)) + } + }) + }); +} + +export async function get(api: string, method: string, params?: any) { + return request(api, { + method: method, + data: params, + }); +} + + + + + + +function setPageRequest(params: any) { + return { + ...params, + "pageNo": params.current, + "pageSize": params.pageSize + }; +} + +/** + * 用于ProTable + * @param api 后台api路径 (/api/...) + * @param method 请求方法(get, post...) + * @param params 对象数据 ({}) + */ +export function queryProTable(api: string, method: string, params: any) { + return new Promise>((resolve, reject) => { + let parameters = setPageRequest(params); + get(api, method, parameters).then(res => { + if (res.code === 200) { + resolve(requestData(res.data.records, res.success, res.data.total)); + } else { + reject(requestData([], false, 0)) + } + }) + }); +} \ No newline at end of file diff --git a/src/utils/PdfModal/PdfModal.tsx b/src/utils/PdfModal/PdfModal.tsx new file mode 100644 index 0000000..40254e5 --- /dev/null +++ b/src/utils/PdfModal/PdfModal.tsx @@ -0,0 +1,114 @@ +import React, { useEffect, useState } from 'react'; +import { Modal, Button } from 'antd'; +import PDF from 'react-pdf-js'; +import ProCard from '@ant-design/pro-card'; +import FileDown from '@/utils/Download'; +import { getFileListByBid, useDownLoadUrl } from '../DownloadUtils'; +/** + * Pdf Modal弹窗公共组件 + * 2021.8.25 zhoujianlong 根据定标结果通知书的弹出窗口改造初始版本,增加备注 + */ +interface PdfModalProps { + fileId: string; //文档中心id + downLoadFileName: string; //下载后的文件名称 + modalVisible: boolean; //Modal 弹出还是关闭 + onCancel: () => void; //关闭Modal方法 +} + +const PdfModal: React.FC = (props) => { + const { fileId, downLoadFileName, modalVisible, onCancel } = props; + const [url] = useDownLoadUrl(fileId); + const [page, setPage] = useState(1); //页码 + const [pages, setPages] = useState(0); //总页数 + const [fileExist, setFileExist] = useState('0'); //0:未验证,1:验证后有,2:验证后没有 + + useEffect(() => { + //判断文件是否存在 + getFileListByBid(fileId).then((res) => { + if (res !== undefined && res.length > 0) { + setFileExist('1'); + } else { + setFileExist('2'); + } + }); + }, [fileId]); + + //文档总页码 + const onDocumentComplete = (pages: any) => { + setPage(1); + setPages(pages); + }; + + //上一页 + const handlePrevious = () => { + setPage(page - 1); + }; + + //下一页 + const handleNext = () => { + setPage(page + 1); + }; + + const modalHeight = (window.innerHeight * 96) / 100; + + return ( + onCancel()} + width={'80%'} + centered + style={{ maxHeight: modalHeight }} + bodyStyle={{ maxHeight: modalHeight - 107, overflowY: 'auto' }} + footer={[ + <> + + {fileExist == '1' ? ( + <> + + + + + ) : null} + , + ]} + > + + {fileExist == '0' ? ( +
+ ) : fileExist == '1' ? url != "" && ( + <> + + + ) : ( + 对不起,您所查看的文件不存在,请与系统管理员联系! + )} + + + ); +}; + +export default PdfModal; diff --git a/src/utils/ReviewReportUpload/index.tsx b/src/utils/ReviewReportUpload/index.tsx new file mode 100644 index 0000000..13e6953 --- /dev/null +++ b/src/utils/ReviewReportUpload/index.tsx @@ -0,0 +1,56 @@ +import React from 'react'; +import { Form, Modal } from 'antd'; +import ExtendUpload from '@/utils/ExtendUpload'; + +interface ReviewReportUploadProps { + modalVisible: boolean;//modal visible + onCancel: (value?: string) => void//modal submit + fileId: string;//upload fileId + readOnly: boolean;//readonly status true-readonly false-not readonly +} + +const layout = { + labelCol: { span: 4 }, + wrapperCol: { span: 20 }, +}; + +const modalHeight = window.innerHeight * 96 / 100; + +/** + * 评审室-评审结果评审报告上传附件 + * @param props + * @returns + */ + +const ReviewReportUpload: React.FC = (props) => { + const { modalVisible, onCancel, fileId, readOnly } = props; + + const [form] = Form.useForm(); + + return ( + onCancel(form.getFieldValue('annexId'))} + okButtonProps={{ hidden: true }} + cancelText="返回" + style={{ maxHeight: modalHeight }} + bodyStyle={{ maxHeight: modalHeight - 107, overflowY: 'auto' }} + centered + > +
+ + + + +
+
+ ); +}; + +export default ReviewReportUpload; diff --git a/src/utils/RiskPrevention/index.tsx b/src/utils/RiskPrevention/index.tsx new file mode 100644 index 0000000..311cd86 --- /dev/null +++ b/src/utils/RiskPrevention/index.tsx @@ -0,0 +1,96 @@ +import React from 'react'; +import { Modal, Tag } from 'antd'; +import { ExclamationCircleOutlined } from '@ant-design/icons'; +import type { ProColumns } from '@ant-design/pro-table'; +import ProTable from '@ant-design/pro-table'; +import './riskStyle.less' + +interface RiskPreventionProps { + modalVisible: boolean; + onCancel: () => void; + data: Array; +} + +const modalHeight = window.innerHeight * 96 / 100; + +/** + * 风险防控通用 + * @param props + * @returns + */ +const RiskPrevention: React.FC = (props) => { + const { modalVisible, onCancel, data } = props; + + const columns: ProColumns[] = [ + { + dataIndex: 'regulationStrategy', + title: '规则响应策略', + width: '13%', + valueEnum: { + hard: { text: '强控', status: 'Error' }, + soft: { text: '软控', status: 'Warning' }, + alarm: { text: '预警', status: 'Processing' } + }, + }, + { + dataIndex: 'regulationName', + title: '规则模型名称', + width: '13%', + }, + { + dataIndex: 'regulationRank', + title: '风险响应等级', + width: '13%', + valueEnum: { + first: { text: '风险一级' }, + second: { text: '风险二级' }, + third: { text: '风险三级' } + }, + }, + { + dataIndex: 'message', + title: '规则相应内容', + }, + ]; + + return ( + onCancel()} + okButtonProps={{ hidden: true }} + > +
+ } color="warning" className="risk-top-tag"> + 当前业务操作受以下风控规则限制 + + {data?.map(item => { + return ( +
+
+ 场景名称:{item.sceneName} + {item.publishDepartName} +
+ + columns={columns} + dataSource={item.regulationData} + rowKey="regulationId" + size='small' + pagination={false} + toolBarRender={false} + search={false} + /> +
+ ) + })} +
+
+ ); +}; + +export default RiskPrevention; diff --git a/src/utils/RiskPrevention/riskStyle.less b/src/utils/RiskPrevention/riskStyle.less new file mode 100644 index 0000000..39813bd --- /dev/null +++ b/src/utils/RiskPrevention/riskStyle.less @@ -0,0 +1,19 @@ +.risk-top-tag { + font-size: 14px; + width: 100%; + padding: 8px 16px; +} + +.risk-table-title { + height: 40px; + line-height: 40px; + display: flex; + justify-content: space-between; + font-weight: bold; + .table-scene-name { + color: #7c7c7c; + } + :last-child { + color: #000; + } +} \ No newline at end of file diff --git a/src/utils/RiskPreventionSoft/index.tsx b/src/utils/RiskPreventionSoft/index.tsx new file mode 100644 index 0000000..d368695 --- /dev/null +++ b/src/utils/RiskPreventionSoft/index.tsx @@ -0,0 +1,118 @@ +import React, { useEffect, useState } from 'react'; +import { Modal, Tag } from 'antd'; +import { ExclamationCircleOutlined } from '@ant-design/icons'; +import type { ProColumns } from '@ant-design/pro-table'; +import ProTable from '@ant-design/pro-table'; +import './riskStyle.less' + +interface RiskPreventionSoftProps { + modalVisible: boolean; + onCancel: () => void; + onSubmit: () => void; + data: Array; +} + +const modalHeight = window.innerHeight * 96 / 100; + +/** + * 风险防控通用(软控) + * @param props + * @returns + */ +const RiskPreventionSoft: React.FC = (props) => { + const { modalVisible, onCancel, onSubmit, data } = props; + const [confirmButtonVisible, setConfirmButtonVisible] = useState(true);//是否显示确定按钮 + + const columns: ProColumns[] = [ + { + dataIndex: 'regulationStrategy', + title: '规则响应策略', + width: '13%', + valueEnum: { + hard: { text: '强控', status: 'Error' }, + soft: { text: '软控', status: 'Warning' }, + alarm: { text: '预警', status: 'Processing' } + }, + }, + { + dataIndex: 'regulationName', + title: '规则模型名称', + width: '13%', + }, + { + dataIndex: 'regulationRank', + title: '风险响应等级', + width: '13%', + valueEnum: { + first: { text: '风险一级' }, + second: { text: '风险二级' }, + third: { text: '风险三级' } + }, + }, + { + dataIndex: 'message', + title: '规则相应内容', + }, + ]; + useEffect(()=>{ + setConfirmButtonVisible(getButtonVisible()); + },[]) + + const getButtonVisible = () => { + console.log(data); + for (const risk of data) { + for (const result of risk.result) { + for (const regulationData of result.regulationData) { + if(regulationData.regulationStrategy=="hard"){ + return true; + } + } + } + } + return false; + } + + return ( + onCancel()} + okButtonProps={{hidden: confirmButtonVisible}} + onOk={() => { + onSubmit(); + onCancel(); + }} + > +
+ } color="warning" className="risk-top-tag"> + 当前业务操作受以下风控规则限制 + + {data.map(ite => ite?.result.map((item: any) => ( +
+
+ 场景名称:{item.sceneName} + {item.publishDepartName} +
+ + columns={columns} + dataSource={item.regulationData} + rowKey="regulationId" + size='small' + pagination={false} + toolBarRender={false} + search={false} + /> +
+ ) + ))} +
+
+ ); +}; + +export default RiskPreventionSoft; diff --git a/src/utils/RiskPreventionSoft/riskStyle.less b/src/utils/RiskPreventionSoft/riskStyle.less new file mode 100644 index 0000000..39813bd --- /dev/null +++ b/src/utils/RiskPreventionSoft/riskStyle.less @@ -0,0 +1,19 @@ +.risk-top-tag { + font-size: 14px; + width: 100%; + padding: 8px 16px; +} + +.risk-table-title { + height: 40px; + line-height: 40px; + display: flex; + justify-content: space-between; + font-weight: bold; + .table-scene-name { + color: #7c7c7c; + } + :last-child { + color: #000; + } +} \ No newline at end of file diff --git a/src/utils/SeleApprovalProcess/index.tsx b/src/utils/SeleApprovalProcess/index.tsx new file mode 100644 index 0000000..c68d431 --- /dev/null +++ b/src/utils/SeleApprovalProcess/index.tsx @@ -0,0 +1,91 @@ +/* + * @Author: zhoujianlong + * @Date: 2021-06-22 14:46:22 + * @Last Modified by: zhoujianlong + * @Last Modified time: 2021-08-03 14:09:26 + */ +import React, { useState } from 'react'; +import { Modal, Button, message, Spin } from 'antd'; +import ProTable, { ProColumns } from '@ant-design/pro-table'; +import { ApprovalProcess } from './service'; + +interface SeleApprovalProcessProps { + modalVisible: boolean; //弹窗visible + onCancel: () => void; //关闭弹窗方法回调 + data: Array[]; //传入列表展示的数组 + annoId: any; //传入id +} +/** + * 公告、变更公告、失败公告、邀请函、公示 选择审批流程 + */ +const SeleApprovalProcess: React.FC = (props) => { + const { modalVisible, onCancel, data, annoId } = props; + const modalHeight = (window.innerHeight * 96) / 100; + //loading + const [loading, setLoading] = useState(false); + //发起审批操作 + const toApprove = async (record: any) => { + setLoading(true); + await ApprovalProcess(annoId, { ...record }) + .then((res) => { + if (res?.code == 200 && res?.success == true) { + message.success('操作成功'); + onCancel(); + } + }) + .finally(() => { + setLoading(false); + }); + }; + + const columns: ProColumns[] = [ + { + title: '序号', + key: 'key', + render: (_, record: any, index: any) => index + 1, + }, + { + title: '流程名称', + dataIndex: 'workflowName', + key: 'workflowName', + }, + { + title: '操作', + dataIndex: 'options', + key: 'options', + render: (_: any, record: any) => ( + + ), + }, + ]; + + return ( + onCancel()} + footer={null} + > + + + + + ); +}; + +export default SeleApprovalProcess; diff --git a/src/utils/SeleApprovalProcess/service.ts b/src/utils/SeleApprovalProcess/service.ts new file mode 100644 index 0000000..1f1ad53 --- /dev/null +++ b/src/utils/SeleApprovalProcess/service.ts @@ -0,0 +1,23 @@ +import request from '@/utils/request'; +/** + * 提交审批操作 + * @param params + * @returns + */ +export async function ApprovalProcess(params: any, data: any) { + return request(`/api/biz-service-ebtp-bid/v1/anno/approval/${params}`, { + method: 'POST', + data: data, + }); +} + +/** + * 获取流程列表 + * @param params + * @returns + */ + export async function getApprProcessList(params: any) { + return request(`/api/biz-service-ebtp-bid/v1/anno/approval/list/${params}`, { + method: 'POST', + }); +} diff --git a/src/utils/SupplierList/index.tsx b/src/utils/SupplierList/index.tsx new file mode 100644 index 0000000..a02247f --- /dev/null +++ b/src/utils/SupplierList/index.tsx @@ -0,0 +1,86 @@ +import React from 'react'; +import { Button, Modal, Spin } from "antd"; +import ProTable, { ProColumns } from "@ant-design/pro-table" +import { getSupplierList } from "@/utils/SupplierList/service"; + + +/** + * 供应商列表 + * */ +interface SupplierData { + SupplierListType: any;// + spin: boolean, + addSupplier: (param: any) => void; + onCancel: () => void; +} + + +const SupplierList: React.FC = (props) => { + const { SupplierListType, spin, addSupplier, onCancel } = props; + + const columns1: ProColumns<{}>[] = [ + { + title: '供应商名称', + dataIndex: 'partnerName', + key: 'partnerName', + align: 'left', + }, + { + title: '供应商编号', + dataIndex: 'organizationCode', + key: 'organizationCode', + hideInSearch: true,//列表中显示,查询条件中不显示 + align: 'left', + }, + { + title: '操作', + dataIndex: 'status', + key: "", + hideInSearch: true,//列表中显示,查询条件中不显示 + align: 'left', + render: (_: any, record: any) => ( + <> + + + ) + }, + ]; + + return ( + <> + 取消} + > + + { + const msg = await getSupplierList({ ...params, pageNum: params.current }); + return { + data: msg.data?.records, success: msg?.success, total: msg.data?.total, + } + } + } + rowKey="partnerMdmCode" + pagination={{ + defaultPageSize: 10, + showQuickJumper: true, + }} + search={{ + defaultCollapsed: true, + labelWidth: 100, + span: 12 + }} + dateFormatter="string" + options={false} + /> + + + + ) +} +export default SupplierList diff --git a/src/utils/SupplierList/index4user.tsx b/src/utils/SupplierList/index4user.tsx new file mode 100644 index 0000000..83fe237 --- /dev/null +++ b/src/utils/SupplierList/index4user.tsx @@ -0,0 +1,90 @@ +import React from 'react'; +import { Button, Modal, Spin } from "antd"; +import ProTable, { ProColumns } from "@ant-design/pro-table" +import { getSupplierList, getSupplierUser } from "@/utils/SupplierList/service"; + + +/** + * 供应商列表 + * */ +interface SupplierData { + SupplierBodyType: any;// + spin: boolean, + chooseSupplierUser: (param: any) => void; + partnerMdmCode: any; + onCancel: () => void; + +} + + +const SupplierUserList: React.FC = (props) => { + const { SupplierBodyType, spin, chooseSupplierUser, partnerMdmCode, onCancel } = props; + + const columns1: ProColumns<{}>[] = [ + { + title: '联系人', + dataIndex: 'empName', + key: 'empName', + align: 'left', + }, + { + title: '账号', + dataIndex: 'userAccount', + key: 'userAccount', + align: 'left', + search: false, + }, + { + title: '电话', + dataIndex: 'mobile', + key: 'mobile', + align: 'left', + search: false, + }, + { + title: '操作', + dataIndex: 'status', + key: "", + align: 'left', + search: false, + render: (_: any, record: any) => ( + <> + + + ) + }, + ]; + + return ( + <> + 取消} + > + + { + const msg = await getSupplierUser({ + ...params, partnerMdmCode: partnerMdmCode, pageNum: params.current, pageSize: params.pageSize, + }); + return { + data: msg.data?.records, success: msg?.success, total: msg?.data.total, + } + } + } + rowKey="partnerMdmCode" + pagination={{ + defaultPageSize: 10, + showQuickJumper: true, + }} + dateFormatter="string" + options={false} + /> + + + + ) +} +export default SupplierUserList diff --git a/src/utils/SupplierList/service.ts b/src/utils/SupplierList/service.ts new file mode 100644 index 0000000..5abd9da --- /dev/null +++ b/src/utils/SupplierList/service.ts @@ -0,0 +1,47 @@ +import request from "@/utils/request"; +/*获取供应商信息 后端 山分 */ +export async function getSupplierList(params: any) { + /* + * http://gysxxk.cn1.utools.club/serviceEshopProviderMdm/findPageProvider +{   + "pageNum": 1, + "pageSize": 10 +} + * */ + return request('/api/api/core-service-supplierbase/outer/v1.0/serviceEshopProviderMdm/findPageProvider', { + method: 'post', + data: { + ...params + } + }) + + +} +/*获取供应商联系人信息 后端 吉分20230331版本 */ +export async function getSupplierUserByUserInfo(params: any) { + /* + *暂无url + * */ + return request('/api/core-service-ebtp-userinfo/v1/userinfo/findUserCountListBySupplierCodePage', { + method: 'post', + data: { + ...params + } + }) + + +} +/*获取供应商联系人信息 后端 山分 */ +export async function getSupplierUser(params: any) { + /* + *暂无url + * */ + return request('/api/api/core-service-supplierbase/outer/v1.0/serviceEshopProviderEmpMdm/findUserCountListBySupplierCodePage', { + method: 'post', + data: { + ...params + } + }) + + +} diff --git a/src/utils/authority.ts b/src/utils/authority.ts new file mode 100644 index 0000000..66f40ec --- /dev/null +++ b/src/utils/authority.ts @@ -0,0 +1,55 @@ +//import { reloadAuthorized } from './Authorized'; +import { getRA, getPurchaseCanOperate } from './session'; + +// use localStorage to store the authority info, which might be sent from server in actual project. +export function getAuthority(str?: string): string | string[] { + const authorityString = + typeof str === 'undefined' && sessionStorage ? sessionStorage.getItem('roleAuthority') : str; + // authorityString could be admin, "admin", ["admin"] + let authority; + try { + if (authorityString) { + authority = JSON.parse(authorityString); + } + } catch (e) { + authority = authorityString; + } + if (typeof authority === 'string') { + return [authority]; + } + // preview.pro.ant.design only do not use in your production. + // preview.pro.ant.design 专用环境变量,请不要在你的项目中使用它。 + // if (!authority && ANT_DESIGN_PRO_ONLY_DO_NOT_USE_IN_YOUR_PRODUCTION === 'site') { + // return ['admin']; + // } + return authority; +} + +// export function setAuthority(authority: string | string[]): void { +// const proAuthority = typeof authority === 'string' ? [authority] : authority; +// sessionStorage.setItem('roleAuthority', JSON.stringify(proAuthority)); +// // auto reload +// reloadAuthorized(); +// } +//全局按钮控制 登陆角色是否显示功能 不显示:return true +export function btnAuthority(allowedRoles: string[], type?: string) { + const roles = getRA();//当前登陆账号的角色数组 + let control = true; + + //根据session中的 采购经理是否可操作 属性,返回控制值 + if (getPurchaseCanOperate() == null && type != '1') { + control = false; + } + //根据传入得可操作角色 返回控制值 + if ((!control || type=='1') && allowedRoles?.length > 0 && roles != null) { + for (let index = 0; index < allowedRoles.length; index++) { + const element = allowedRoles[index]; + control = !roles.includes(element);//传入的角色有一个有权限就跳出,反false(显示) + if (!control) { + break; + } + } + } + + return control; +} diff --git a/src/utils/checkEmpty.ts b/src/utils/checkEmpty.ts new file mode 100644 index 0000000..cf2e004 --- /dev/null +++ b/src/utils/checkEmpty.ts @@ -0,0 +1,7 @@ +export default function checkUn (val: any) { + if (val == undefined || val == null || val == "" || val == [] || JSON.stringify(val) == "{}" || val == "null") { + return false; + } else { + return true; + } +} \ No newline at end of file diff --git a/src/utils/comFormItem.tsx b/src/utils/comFormItem.tsx new file mode 100644 index 0000000..4739f67 --- /dev/null +++ b/src/utils/comFormItem.tsx @@ -0,0 +1,37 @@ +import { DatePicker, Form, Input, Radio } from 'antd'; +import React from 'react'; +const FormItem = Form.Item; +const { TextArea } = Input; +//Input +export function returnInput(name: any, label: string, edit: boolean, rules?: any, width?: any) { + return ( + + + + ) +} +//TextArea +export function returnArea(name: any, edit: boolean, label?: string,) { + const wrapperCol = { offset: label == undefined ? 6 : 0, span: 14 }; + return ( + +