Browse Source

first commit

master
lucky 5 years ago
commit
4ea8249ea6
  1. 3
      .browserslistrc
  2. 8
      .editorconfig
  3. 3
      .env
  4. 10
      .env.development
  5. 10
      .env.production
  6. 45
      .eslintrc.js
  7. 23
      .gitignore
  8. 13
      .prettierrc
  9. 24
      README.md
  10. 13
      babel.config.js
  11. 1
      commitlint.config.js
  12. 13746
      package-lock.json
  13. 49
      package.json
  14. BIN
      public/favicon.ico
  15. BIN
      public/img/icons/android-chrome-192x192.png
  16. BIN
      public/img/icons/android-chrome-512x512.png
  17. BIN
      public/img/icons/android-chrome-maskable-192x192.png
  18. BIN
      public/img/icons/android-chrome-maskable-512x512.png
  19. BIN
      public/img/icons/apple-touch-icon-120x120.png
  20. BIN
      public/img/icons/apple-touch-icon-152x152.png
  21. BIN
      public/img/icons/apple-touch-icon-180x180.png
  22. BIN
      public/img/icons/apple-touch-icon-60x60.png
  23. BIN
      public/img/icons/apple-touch-icon-76x76.png
  24. BIN
      public/img/icons/apple-touch-icon.png
  25. BIN
      public/img/icons/favicon-16x16.png
  26. BIN
      public/img/icons/favicon-32x32.png
  27. BIN
      public/img/icons/msapplication-icon-144x144.png
  28. BIN
      public/img/icons/mstile-150x150.png
  29. 3
      public/img/icons/safari-pinned-tab.svg
  30. 17
      public/index.html
  31. 2
      public/robots.txt
  32. 15
      rest/http-client.env.json
  33. 56
      rest/project.http
  34. 51
      src/App.vue
  35. BIN
      src/assets/logo.png
  36. 314
      src/common/portrait.styl
  37. 225
      src/components/Activity/ActivityAdd.vue
  38. 204
      src/components/Activity/ActivityDate.vue
  39. 227
      src/components/Activity/ActivityEdit.vue
  40. 152
      src/components/Activity/ActivitySearch.vue
  41. 122
      src/components/Banner/BannerAdd.vue
  42. 151
      src/components/Banner/BannerDate.vue
  43. 124
      src/components/Banner/BannerEdit.vue
  44. 73
      src/components/Banner/BannerSearch.vue
  45. 69
      src/components/BtnCom/BtnCon.vue
  46. 213
      src/components/CVideo/VideoAdd.vue
  47. 199
      src/components/CVideo/VideoDate.vue
  48. 213
      src/components/CVideo/VideoEdit.vue
  49. 54
      src/components/CVideo/VideoSearch.vue
  50. 154
      src/components/Challenge/ChallengeAdd.vue
  51. 186
      src/components/Challenge/ChallengeDate.vue
  52. 154
      src/components/Challenge/ChallengeEdit.vue
  53. 61
      src/components/Challenge/ChallengeSearch.vue
  54. 106
      src/components/Comment/CommentDate.vue
  55. 38
      src/components/Comment/CommentSearch.vue
  56. 166
      src/components/Course/CourseAdd.vue
  57. 182
      src/components/Course/CourseDate.vue
  58. 166
      src/components/Course/CourseEdit.vue
  59. 59
      src/components/Course/CourseSearch.vue
  60. 166
      src/components/Demand/DemandDate.vue
  61. 37
      src/components/Demand/DemandSearch.vue
  62. 153
      src/components/Development/DevelopmentAdd.vue
  63. 146
      src/components/Development/DevelopmentDate.vue
  64. 153
      src/components/Development/DevelopmentEdit.vue
  65. 59
      src/components/Development/DevelopmentSearch.vue
  66. 46
      src/components/EditableCellSelect/EditableCellSelect.vue
  67. 116
      src/components/Enterprise/EnterpriseDate.vue
  68. 37
      src/components/Enterprise/EnterpriseSearch.vue
  69. 172
      src/components/Forum/ForumDate.vue
  70. 96
      src/components/Forum/ForumSearch.vue
  71. 104
      src/components/Manage/ManageAdd.vue
  72. 129
      src/components/Manage/ManageDate.vue
  73. 104
      src/components/Manage/ManageEdit.vue
  74. 59
      src/components/Manage/ManageSearch.vue
  75. 166
      src/components/Mentor/MentorAdd.vue
  76. 182
      src/components/Mentor/MentorDate.vue
  77. 166
      src/components/Mentor/MentorEdit.vue
  78. 59
      src/components/Mentor/MentorSearch.vue
  79. 426
      src/components/Page/PageAdd.vue
  80. 199
      src/components/Page/PageDate.vue
  81. 211
      src/components/Page/PageEdit.vue
  82. 70
      src/components/Page/PageSearch.vue
  83. 197
      src/components/Policy/PolicyAdd.vue
  84. 213
      src/components/Policy/PolicyDate.vue
  85. 200
      src/components/Policy/PolicyEdit.vue
  86. 70
      src/components/Policy/PolicySearch.vue
  87. 155
      src/components/RD/RDAdd.vue
  88. 157
      src/components/RD/RDDate.vue
  89. 163
      src/components/RD/RDEdit.vue
  90. 71
      src/components/RD/RDSearch.vue
  91. 157
      src/components/RDMember/RDMemberAdd.vue
  92. 176
      src/components/RDMember/RDMemberDate.vue
  93. 158
      src/components/RDMember/RDMemberEdit.vue
  94. 59
      src/components/RDMember/RDMemberSearch.vue
  95. 229
      src/components/Sharing/SharingAdd.vue
  96. 204
      src/components/Sharing/SharingDate.vue
  97. 229
      src/components/Sharing/SharingEdit.vue
  98. 87
      src/components/Sharing/SharingSearch.vue
  99. 123
      src/components/SignUp/SignUpDate.vue
  100. 38
      src/components/SignUp/SignUpSearch.vue

3
.browserslistrc

@ -0,0 +1,3 @@
> 1%
last 2 versions
not dead

8
.editorconfig

@ -0,0 +1,8 @@
[*.{js,jsx,ts,tsx,vue}]
indent_style = space
indent_size = 2
end_of_line = lf
trim_trailing_whitespace = true
insert_final_newline = true
max_line_length = 140
root = true

3
.env

@ -0,0 +1,3 @@
VUE_APP_MODE=production
VUE_APP_PREVIEW=false
VUE_APP_URL=http://www.sxwikionline.com/

10
.env.development

@ -0,0 +1,10 @@
VUE_APP_MODE=development
VUE_APP_NODE_ENV=development
VUE_APP_SCENE=greenback
VUE_APP_BASE_URL=http://www.sxwikionline.com/
VUE_APP_API_URL=http://www.sxwikionline.com/gateway
VUE_APP_PROXY_URL=/gateway
VUE_APP_PUBLIC_PATH=/greenback
VUE_APP_MSG_URL=wss://test.tall.wiki/websocket/message/v4.0/ws
VUE_APP_TITLE=绿谷在线
VUE_APP_DESCRIPTION=绿谷在线管理后台

10
.env.production

@ -0,0 +1,10 @@
VUE_APP_MODE=production
VUE_APP_NODE_ENV=production
VUE_APP_SCENE=greenback
VUE_APP_BASE_URL=http://www.sxwikionline.com/
VUE_APP_API_URL=http://www.sxwikionline.com/gateway
VUE_APP_PROXY_URL=/gateway
VUE_APP_PUBLIC_PATH=/greenback
VUE_APP_MSG_URL=wss://www.tall.wiki/websocket/message/v4.0/ws
VUE_APP_TITLE=绿谷在线
VUE_APP_DESCRIPTION=绿谷在线管理后台

45
.eslintrc.js

@ -0,0 +1,45 @@
/*
* Copyright (c) 2019.
* author: wally
* email: 18603454788@163.com
*/
module.exports = {
root: true,
env: { browser: true, node: true },
extends: ['plugin:vue/recommended', 'plugin:vue/essential'],
rules: {
'vue/html-self-closing': 'off',
'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
'no-param-reassign': ['error', { props: true, ignorePropertyModificationsFor: ['state'] }],
'max-len': ['error', { code: 140, tabWidth: 2 }],
'object-curly-newline': ['error', { multiline: true }],
'arrow-parens': ['error', 'as-needed'],
'linebreak-style': 'off',
'vue/attributes-order': 'off',
'no-param-reassign': 'off',
'vue/singleline-html-element-content-newline': 'off',
'vue/max-attributes-per-line': 'off',
'vue/multiline-html-element-content-newline': 'off',
'vue/html-indent': 'off',
},
parserOptions: { parser: 'babel-eslint' },
overrides: [
{
files: ['**/__tests__/*.{j,t}s?(x)'],
env: { jest: true },
},
],
globals: {
Vue: true,
VueRouter: true,
Vuex: true,
axios: true,
_: true,
},
};

23
.gitignore

@ -0,0 +1,23 @@
.DS_Store
node_modules
/dist
# local env files
.env.local
.env.*.local
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

13
.prettierrc

@ -0,0 +1,13 @@
{
"printWidth": 140,
"singleQuote": true,
"semi": true,
"trailingComma": "all",
"arrowParens": "avoid",
"tabWidth": 2,
"useTabs": false,
"bracketSpacing": true,
"jsxBracketSameLine": false,
"proseWrap": "always",
"endOfLine": "lf"
}

24
README.md

@ -0,0 +1,24 @@
# green-valley
## Project setup
```
yarn install
```
### Compiles and hot-reloads for development
```
yarn serve
```
### Compiles and minifies for production
```
yarn build
```
### Lints and fixes files
```
yarn lint
```
### Customize configuration
See [Configuration Reference](https://cli.vuejs.org/config/).

13
babel.config.js

@ -0,0 +1,13 @@
module.exports = {
presets: ["@vue/cli-plugin-babel/preset"],
plugins: [
[
"import",
{
libraryName: "ant-design-vue",
libraryDirectory: "es",
style: true
}
]
]
};

1
commitlint.config.js

@ -0,0 +1 @@
module.exports = {extends: ['./node_modules/vue-cli-plugin-commitlint/lib/lint']};

13746
package-lock.json

File diff suppressed because it is too large

49
package.json

@ -0,0 +1,49 @@
{
"name": "green-valley",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
"dependencies": {
"ant-design-vue": "^1.2.4",
"compression-webpack-plugin": "^6.1.1",
"core-js": "^3.6.5",
"moment": "^2.29.1",
"register-service-worker": "^1.7.1",
"stylus": "^0.54.8",
"vue": "^2.6.11",
"vue-quill-editor": "^3.0.6",
"vue-router": "^3.2.0",
"vuex": "^3.4.0"
},
"devDependencies": {
"@vue/cli-plugin-babel": "~4.5.0",
"@vue/cli-plugin-eslint": "~4.5.0",
"@vue/cli-plugin-pwa": "~4.5.0",
"@vue/cli-plugin-router": "~4.5.0",
"@vue/cli-plugin-vuex": "~4.5.0",
"@vue/cli-service": "~4.5.0",
"@vue/eslint-config-prettier": "^6.0.0",
"axios": "^0.18.0",
"babel-eslint": "^10.1.0",
"babel-plugin-import": "^1.11.0",
"css-loader": "^5.0.1",
"eslint": "^6.7.2",
"eslint-plugin-prettier": "^3.1.3",
"eslint-plugin-vue": "^6.2.2",
"less": "^2.7.3",
"less-loader": "^4.1.0",
"prettier": "^1.19.1",
"sass": "^1.26.5",
"sass-loader": "^8.0.2",
"stylus": "^0.54.5",
"stylus-loader": "^3.0.2",
"svg-sprite-loader": "^5.0.0",
"vue-cli-plugin-ant-design": "^1.0.1",
"vue-cli-plugin-axios": "^0.0.4",
"vue-template-compiler": "^2.6.11"
}
}

BIN
public/favicon.ico

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

BIN
public/img/icons/android-chrome-192x192.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

BIN
public/img/icons/android-chrome-512x512.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

BIN
public/img/icons/android-chrome-maskable-192x192.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

BIN
public/img/icons/android-chrome-maskable-512x512.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

BIN
public/img/icons/apple-touch-icon-120x120.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

BIN
public/img/icons/apple-touch-icon-152x152.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

BIN
public/img/icons/apple-touch-icon-180x180.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

BIN
public/img/icons/apple-touch-icon-60x60.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
public/img/icons/apple-touch-icon-76x76.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
public/img/icons/apple-touch-icon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

BIN
public/img/icons/favicon-16x16.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 799 B

BIN
public/img/icons/favicon-32x32.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
public/img/icons/msapplication-icon-144x144.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
public/img/icons/mstile-150x150.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

3
public/img/icons/safari-pinned-tab.svg

@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M8.00251 14.9297L0 1.07422H6.14651L8.00251 4.27503L9.84583 1.07422H16L8.00251 14.9297Z" fill="black"/>
</svg>

After

Width:  |  Height:  |  Size: 215 B

17
public/index.html

@ -0,0 +1,17 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>

2
public/robots.txt

@ -0,0 +1,2 @@
User-agent: *
Disallow:

15
rest/http-client.env.json

@ -0,0 +1,15 @@
{
"$shared": {
"version": "v1",
"identifier": "wally",
"credential": "111111"
},
"dev": {
"name": "dev",
"url": "http://192.168.0.99/gateway"
},
"local": {
"version": "v2",
"url": "http://192.168.0.99/gateway"
}
}

56
rest/project.http

@ -0,0 +1,56 @@
# @tall = {{url}}/tall/v1.0
@tall = http://www.sxwikionline.com/gateway/tall/v1.0
@greenvalley = http://www.sxwikionline.com/gateway/greenvalley
@type = content-type: application/json;charset=utf-8
### login
# @name login
POST {{tall}}/users/signin
{{type}}
{
"client": 1,
"type": 3,
"data": {
"identifier": "song",
"credential": "999999"
}
}
### send code
GET {{tall}}/users/smscode?phone=16603418748
### phone login
# @name phonelogin
POST {{tall}}/users/signin
{{type}}
{
"client": 1,
"type": 1,
"data": {
"identifier": "15235360226",
"credential": "1111"
}
}
### 根据团队id查看研发团队相关信息
POST {{greenvalley}}/researchTeam/selectTeam
{{type}}
Authorization: Bearer {{login.response.body.$.data.token}}
{
"param": {
"company": "",
"researchDirection": "",
"teamId": 0,
"teamIntroduce": "",
"teamLeaderName": "",
"teamName": ""
}
}

51
src/App.vue

@ -0,0 +1,51 @@
<template>
<a-config-provider :locale="zh_CN">
<div class="d-flex flex-row flex-nowrap" id="app">
<btn-con />
<router-view class="flex-1 bg pa-3"></router-view>
</div>
</a-config-provider>
</template>
<script>
import { mapState, mapActions, mapMutations } from 'vuex';
import zh_CN from 'ant-design-vue/lib/locale-provider/zh_CN';
import BtnCon from 'components/BtnCom/BtnCon.vue';
export default {
name: 'app',
components: { BtnCon },
data() {
return {
zh_CN,
};
},
computed: mapState(['anyringToken']),
created() {
console.log('process.env ', process.env);
const userId = '1218763410024566784';
const params = { userId };
this.getUserId(params);
},
methods: mapActions(['getUserId']),
};
</script>
<style>
html {
overflow: hidden !important;
}
html,
body,
#app {
height: 100%;
}
#app {
background: transparent;
}
</style>

BIN
src/assets/logo.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

314
src/common/portrait.styl

@ -0,0 +1,314 @@
// padding
.pa-3 {
padding: 12px;
}
.pl-1{
padding-left: 4px;
}
.pl-2{
padding-left: 8px;
}
.pl-3{
padding-left: 12px;
}
.pl-4{
padding-left: 16px;
}
.pl-5{
padding-left: 20px;
}
.px-1{
padding-left: 4px;
padding-right: 4px;
}
.px-2{
padding-left: 8px;
padding-right: 8px;
}
.px-3{
padding-left: 12px;
padding-right: 12px;
}
.px-10{
padding-left: 30px;
padding-right: 30px;
}
.pb-3 {
padding-bottom: 12px;
}
.pb-4 {
padding-bottom: 16px;
}
.pb-5 {
padding-bottom: 20px;
}
.pb-10 {
padding-bottom: 40px;
}
// margin
.ma-2 {
margin: 8px;
}
.ma-3 {
margin: 12px;
}
.mx-2{
margin-left: 8px;
margin-right: 8px;
}
.my-2{
margin-top: 8px;
margin-bottom: 8px;
}
.my-3{
margin-top: 12px;
margin-bottom: 12px;
}
.my-4{
margin-top: 16px;
margin-bottom: 16px;
}
.mt-1{
margin-top: 4px;
}
.mt-2{
margin-top: 8px;
}
.mt-3{
margin-top: 12px;
}
.mt-4{
margin-top: 16px;
}
.mb-1{
margin-bottom: 4px;
}
.mb-2{
margin-bottom: 8px;
}
.mb-3{
margin-bottom: 12px;
}
.mb-4{
margin-bottom: 16px;
}
.ml-2{
margin-left: 8px;
}
.ml-3{
margin-left: 12px;
}
.ml-4{
margin-left: 16px;
}
.ml-5{
margin-left: 20px;
}
.ml-6{
margin-left: 24px;
}
.ml-7{
margin-left: 28px;
}
.ml-8{
margin-left: 32px;
}
.mr-1{
margin-right: 4px;
}
.mr-2{
margin-right: 8px;
}
.mr-3{
margin-right: 12px;
}
.mr-4{
margin-right: 16px;
}
.mr-5{
margin-right: 20px;
}
.mr-6{
margin-right: 24px;
}
// background
.white {
background: white;
}
.green{
background: #4CAF50;
}
.white--text{
color: #fff;
width: 200px;
margin: 0 auto
}
// flex
.d-flex{
display: flex;
}
.flex-wrap{
flex-wrap: wrap;
}
.flex-nowrap{
flex-wrap: nowrap;
}
.flex-column{
flex-direction: column;
}
.flex-column-reverse{
flex-direction: column-reverse;
}
.flex-row{
flex-direction: row;
}
.flex-row-reverse{
flex-direction: row-reverse;
}
.justify-center{
justify-content: center;
}
.justify-space-between{
justify-content: space-between;
}
.align-center{
align-items: center;
}
.align-left{
align-items: start;
}
.flex-1{
display: flex;
flex: 1;
}
.flex-2{
display: flex;
flex: 2;
}
// other
.pointer{
cursor:pointer;
}
.fill-height{
height:100%;
}
// font
.font-bold{
font-weight: bold;
}
.font-bold-24{
font-size: 24px;
font-weight: bold;
}
.font-24{
font-size: 24px;
}
.font-bold-16{
font-size: 16px;
font-weight: bold;
}
.font-16{
font-size: 16px;
}
.font-bold-14{
font-size: 14px;
font-weight: bold;
}
.font-14{
font-size: 14px;
}
.icon-size{
font-size: 20px;
}
h2{
font-size: 24px;
font-weight: bold;
color: rgba(0,0,0,.85)
}
.textColor{
color: rgba(0,0,0,.65)
}
.baseColor{
color: #1890ff
}
.bg{
background: #F5F5F5
}
.fill-width{
width:100%;
}
.fill-height{
height:100%;
}

225
src/components/Activity/ActivityAdd.vue

@ -0,0 +1,225 @@
<template>
<div class="d-flex flex-wrap pb-3">
<!-- 添加 -->
<a-modal :closable="false" footer title="添加研发团队" v-model="visible" width="700px">
<a-form :form="form" @submit="handleSubmit">
<!-- 发布平台 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="发布平台"
>
<a-radio-group @change="getPlatform" v-model="platValue">
<a-radio :value="1">绿谷</a-radio>
<a-radio :value="2">维基</a-radio>
</a-radio-group>
</a-form-item>
<!-- 类型 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="类型"
>
<a-select @change="getPlatform" placeholder="类型" style="width: 200px">
<a-select-option
:key="index"
:value="category"
v-for="(category, index) in categories"
>{{ category }}</a-select-option>
</a-select>
</a-form-item>
<!-- 计划举办时间 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="计划举办时间"
>
<a-range-picker @change="onChange" format="YYYY/MM/DD HH:mm:ss" show-time />
</a-form-item>
<!-- 实际举办时间 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="计划举办时间"
>
<a-range-picker @change="onChange" format="YYYY/MM/DD HH:mm:ss" show-time />
</a-form-item>
<!-- 地点 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="地点"
>
<!-- initialValue: editItem.place, -->
<a-input
placeholder="地点"
v-decorator="[
'place',
{
rules: [
{ required: true, message: '地点不能为空' },
{ whitespace: true, message: '地点不能为空' },
{ max: 140, massage: '地点最多140个字符' },
],
},
]"
/>
</a-form-item>
<!-- 组织人 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="组织人"
>
<!-- initialValue: editItem.speaker, -->
<a-input
placeholder="组织人"
v-decorator="[
'organizer',
{
rules: [
{ required: true, message: '组织人不能为空' },
{ whitespace: true, message: '组织人不能为空' },
{ max: 140, massage: '组织人最多140个字符' },
],
},
]"
/>
</a-form-item>
<!-- 主讲人 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="主讲人"
>
<!-- initialValue: editItem.speaker, -->
<a-input
placeholder="主讲人"
v-decorator="[
'speaker',
{
rules: [
{ required: true, message: '主讲人不能为空' },
{ whitespace: true, message: '主讲人不能为空' },
{ max: 140, massage: '主讲人最多140个字符' },
],
},
]"
/>
</a-form-item>
<!-- 活动内容 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="活动内容"
>
<!-- initialValue: editItem.content, -->
<a-textarea
placeholder="活动内容"
v-decorator="[
'content',
]"
/>
</a-form-item>
<!-- 发布状态 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="发布状态"
>
<a-radio-group @change="getState" v-model="stateValue">
<a-radio :value="1">发布</a-radio>
<a-radio :value="2">不发布</a-radio>
</a-radio-group>
</a-form-item>
<a-form-item class="d-flex flex-row-reverse">
<a-button @click="$emit('closeModal')" class="mr-3">取消</a-button>
<a-button class="white--text" html-type="submit" type="primary">保存</a-button>
</a-form-item>
</a-form>
</a-modal>
</div>
</template>
<script>
import { addTeam } from 'config/api'
const formItemLayout = {
labelCol: { span: 6 },
wrapperCol: { span: 16 },
};
const tailItemLayout = { wrapperCol: { span: 16, offset: 6 } };
export default {
name: "ActivityAdd",
props: { visible: { type: Boolean, default: false } },
data() {
return {
formItemLayout,
tailItemLayout,
form: this.$form.createForm(this, { name: 'r-d-add' }),
platValue: 1,
categories: [
{id:1,name:'路演'},
{id:2,name:'沙龙'},
{id:3,name:'论坛'},
{id:4,name:'培训'},
{id:5,name:'讲座'},
{id:6,name:'创业活动'}
],
category: '',
stateValue: 1
}
},
methods: {
//
getPlatform(value) {
console.log('value: ', value);
this.platValue = value;
},
//
getCategory(value) {
console.log('value: ', value);
this.category = value;
},
//
getState(value) {
console.log('value: ', value);
this.stateValue = value;
},
//
onChange(dates, dateStrings) {
console.log('From: ', dates[0], ', to: ', dates[1]);
console.log('From: ', dateStrings[0], ', to: ', dateStrings[1]);
},
//
handleSubmit(e) {
e.preventDefault();
this.form.validateFieldsAndScroll(async (err, values) => {
if (!err) {
try {
const params = { param: values };
const res = await addTeam(params);
const { data, msg, code } = res.data;
this.$emit('closeModal');
if (code === 200) {
this.$message.success('添加成功')
// TODO:
} else {
throw msg;
}
} catch (error) {
this.$message.error(error || '添加失败');
}
}
});
},
},
};
</script>
<style scoped lang="stylus"></style>

204
src/components/Activity/ActivityDate.vue

@ -0,0 +1,204 @@
<template>
<div class="main flex-1">
<div style="width:100%" v-if="lists && lists.length > 0">
<a-table
:columns="columns"
:data-source="lists"
:loading="loading"
:row-key="record => record.id"
bordered
class="white"
>
<template slot="id" slot-scope="text, record, index">
<span>{{ index + 1 }}</span>
</template>
<template slot="type" slot-scope="text, record">
<a-tag color="blue">{{ record.type }}</a-tag>
</template>
<template slot="time" slot-scope="text, record">
<div v-if="record.realTime">{{ record.realTime }}</div>
<div v-else>{{ record.planTime }}</div>
</template>
<template slot="state" slot-scope="text, record">
<a-tag color="green">{{ record.state }}</a-tag>
</template>
<template slot="edit" slot-scope="text, record">
<a-icon @click="showEditModal(record)" class="pointer" theme="twoTone" type="edit" />
<a-popconfirm @confirm="() => onDelete(record.id)" title="确定要删除这一条?" v-if="lists.length">
<a-icon class="ml-4 pointer" theme="twoTone" two-tone-color="#ff0000" type="delete" />
</a-popconfirm>
<a-button @click="openSignUp" class="ml-4" size="small" type="primary">报名</a-button>
</template>
<div slot="expandedRowRender" slot-scope="record" style="margin: 0">
<div class="d-flex flex-nowrap justify-space-between mb-2">
<div>计划时间{{ record.planTime }}</div>
<div class="ml-8">实际时间{{ record.realTime }}</div>
<div class="ml-8">组织人{{ record.organizer }}</div>
</div>
<div>活动内容{{ record.content }}</div>
</div>
</a-table>
</div>
<a-empty v-else />
<!-- 编辑 -->
<activity-edit :editItem="editItem" :editVisible="editVisible" @closeModal="closeModal" />
</div>
</template>
<script>
import ActivityEdit from "components/Activity/ActivityEdit.vue";
// import { delTeam } from 'config/api';
const columns = [
{
title: '序号',
align: 'center',
dataIndex: 'id',
key: 'id',
scopedSlots: { customRender: 'id' },
},
{
title: '发布平台',
align: 'center',
dataIndex: 'plat',
key: 'plat',
},
{
title: '类型',
align: 'center',
dataIndex: 'type',
key: 'type',
scopedSlots: { customRender: 'type' },
},
{
title: '举办时间',
align: 'center',
dataIndex: 'time',
key: 'time',
scopedSlots: { customRender: 'time' },
},
{
title: '地点',
align: 'center',
dataIndex: 'place',
key: 'place',
scopedSlots: { customRender: 'place' },
},
{
title: '主讲人',
align: 'center',
dataIndex: 'speaker',
key: 'speaker',
},
{
title: '发布状态',
align: 'center',
dataIndex: 'state',
key: 'state',
scopedSlots: { customRender: 'state' },
},
{
title: '编辑',
align: 'center',
dataIndex: 'edit',
key: 'edit',
width: 200,
scopedSlots: { customRender: 'edit' },
},
];
const lists = [
{
id:'001',
plat:'传控科技',
type: '路演',
planTime: '2020/11/17 08:00 - 2020/11/18 19:00',
realTime:'2020/11/17 08:00 - 2020/11/18 19:00',
place:'太原',
organizer: '张三',
speaker: '李四',
state: '发布',
content:'团队简介团队简介团队简介团队简介团队简介团队简介团队简介团队简介团队简介团队简介团队简介团队简介团队简介团队简介团队简介团队简介'
},
{
id:'002',
plat:'中绿环保',
type: '路演',
planTime: '2020/11/17 08:00 - 2020/11/18 19:00',
realTime:'2020/11/17 08:00 - 2020/11/18 19:00',
place:'太原',
organizer: '张三',
speaker: '李四',
state: '不发布',
content:'团队简介团队简介团队简介团队简介团队简介团队简介团队简介团队简介团队简介团队简介团队简介团队简介团队简介团队简介团队简介团队简介'
}
];
export default {
name: "ActivityDate",
components: {
ActivityEdit,
},
data() {
this.cacheData = lists.map(item => ({ ...item }));
return {
columns,
lists,
loading: false,
editingKey: '',
height: '',
editVisible: false,
editItem: null, //
}
},
mounted() {
this.height = document.getElementsByClassName('main')[0].offsetHeight - 150;
},
methods: {
showEditModal(record){
console.log('record: ', record);
this.editItem = record;
this.editVisible = true;
},
closeModal(){
this.editVisible = false;
},
//
async onDelete(teamId) {
try {
// const params = { param: { teamId } };
// const res = await delTeam(params);
// const { data, msg, code } = res.data;
// if (code === 200) {
// this.$message.success('');
// const arr = [...this.lists];
// this.lists = arr.filter(item => item.id !== teamId);
// // TODO:
// } else {
// throw msg;
// }
} catch (error) {
this.$message.error(error || '删除失败');
}
},
//
openSignUp(){
const { query } = this.$route;
this.$router.push({ path: '/sign-up', query });
}
},
};
</script>
<style scoped lang="stylus"></style>

227
src/components/Activity/ActivityEdit.vue

@ -0,0 +1,227 @@
<template>
<div class="d-flex flex-wrap pb-3">
<!-- 编辑 -->
<a-modal :closable="false" footer title="修改研发团队" v-model="editVisible" width="700px">
<a-form :form="form" @submit="handleSubmit">
<!-- 发布平台 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="发布平台"
>
<a-radio-group @change="getPlatform" v-model="platValue">
<a-radio :value="1">绿谷</a-radio>
<a-radio :value="2">维基</a-radio>
</a-radio-group>
</a-form-item>
<!-- 类型 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="类型"
>
<a-select @change="getPlatform" placeholder="类型" style="width: 200px">
<a-select-option
:key="index"
:value="category"
v-for="(category, index) in categories"
>{{ category }}</a-select-option>
</a-select>
</a-form-item>
<!-- 计划举办时间 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="计划举办时间"
>
<a-range-picker @change="onChange" format="YYYY/MM/DD HH:mm:ss" show-time />
</a-form-item>
<!-- 实际举办时间 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="计划举办时间"
>
<a-range-picker @change="onChange" format="YYYY/MM/DD HH:mm:ss" show-time />
</a-form-item>
<!-- 地点 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="地点"
>
<!-- initialValue: editItem.place, -->
<a-input
placeholder="地点"
v-decorator="[
'place',
{
rules: [
{ required: true, message: '地点不能为空' },
{ whitespace: true, message: '地点不能为空' },
{ max: 140, massage: '地点最多140个字符' },
],
},
]"
/>
</a-form-item>
<!-- 组织人 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="组织人"
>
<!-- initialValue: editItem.speaker, -->
<a-input
placeholder="组织人"
v-decorator="[
'organizer',
{
rules: [
{ required: true, message: '组织人不能为空' },
{ whitespace: true, message: '组织人不能为空' },
{ max: 140, massage: '组织人最多140个字符' },
],
},
]"
/>
</a-form-item>
<!-- 主讲人 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="主讲人"
>
<!-- initialValue: editItem.speaker, -->
<a-input
placeholder="主讲人"
v-decorator="[
'speaker',
{
rules: [
{ required: true, message: '主讲人不能为空' },
{ whitespace: true, message: '主讲人不能为空' },
{ max: 140, massage: '主讲人最多140个字符' },
],
},
]"
/>
</a-form-item>
<!-- 活动内容 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="活动内容"
>
<!-- initialValue: editItem.content, -->
<a-textarea
placeholder="活动内容"
v-decorator="[
'content',
]"
/>
</a-form-item>
<!-- 发布状态 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="发布状态"
>
<a-radio-group @change="getState" v-model="stateValue">
<a-radio :value="1">发布</a-radio>
<a-radio :value="2">不发布</a-radio>
</a-radio-group>
</a-form-item>
<a-form-item class="d-flex flex-row-reverse">
<a-button @click="$emit('closeModal')" class="mr-3">取消</a-button>
<a-button class="white--text" html-type="submit" type="primary">保存</a-button>
</a-form-item>
</a-form>
</a-modal>
</div>
</template>
<script>
// import { upTeam } from 'config/api';
const formItemLayout = {
labelCol: { span: 6 },
wrapperCol: { span: 16 },
};
const tailItemLayout = { wrapperCol: { span: 16, offset: 6 } };
export default {
name: "ActivityEdit",
props: { editVisible: { type: Boolean, default: false },editItem: { type: Object, default: () => {} } },
data() {
return {
formItemLayout,
tailItemLayout,
form: this.$form.createForm(this, { name: 'r-d-add' }),
platValue: 1,
categories: [
{id:1,name:'路演'},
{id:2,name:'沙龙'},
{id:3,name:'论坛'},
{id:4,name:'培训'},
{id:5,name:'讲座'},
{id:6,name:'创业活动'}
],
category: '',
stateValue: 1
}
},
methods: {
//
getPlatform(value) {
console.log('value: ', value);
this.platValue = value;
},
//
getCategory(value) {
console.log('value: ', value);
this.category = value;
},
//
getState(value) {
console.log('value: ', value);
this.stateValue = value;
},
//
onChange(dates, dateStrings) {
console.log('From: ', dates[0], ', to: ', dates[1]);
console.log('From: ', dateStrings[0], ', to: ', dateStrings[1]);
},
//
handleSubmit(e) {
e.preventDefault();
this.form.validateFieldsAndScroll(async (err, values) => {
if (!err) {
try {
// const params = { param: values };
// const res = await upTeam(params);
// const { data, msg, code } = res.data;
// this.$emit('closeModal');
// if (code === 200) {
// this.$message.success('')
// // TODO:
// } else {
// throw msg;
// }
} catch (error) {
this.$message.error(error || '修改失败');
}
}
});
},
},
};
</script>
<style scoped lang="stylus"></style>

152
src/components/Activity/ActivitySearch.vue

@ -0,0 +1,152 @@
<template>
<div class="d-flex flex-wrap pb-3">
<div>
<!-- 发布平台 -->
<a-select @change="getPlatform" placeholder="发布平台" style="width: 100px">
<a-select-option :key="index" :value="plat" v-for="(plat, index) in platforms">{{ plat }}</a-select-option>
</a-select>
<!-- 类型 -->
<a-select @change="getCategory" class="ml-3" placeholder="类型" style="width: 100px">
<a-select-option
:key="index"
:value="category.name"
v-for="(category, index) in categories"
>{{ category.name }}</a-select-option>
</a-select>
<!-- 举办时间 -->
<a-range-picker
@change="onChange"
class="ml-3"
format="YYYY/MM/DD HH:mm:ss"
show-time
style="width: 200px"
/>
<!-- 地点 -->
<a-input
@change="handleChange('place',$event)"
class="ml-3"
placeholder="地点"
style="width: 100px"
v-model="place"
/>
<!-- 组织人 -->
<a-input
@change="handleChange('organizer',$event)"
class="ml-3"
placeholder="组织人"
style="width: 100px"
v-model="organizer"
/>
<!-- 主讲人 -->
<a-input
@change="handleChange('speaker',$event)"
class="ml-3"
placeholder="主讲人"
style="width: 100px"
v-model="speaker"
/>
<!-- 发布状态 -->
<a-select @change="getState" class="ml-3" placeholder="发布状态" style="width: 100px">
<a-select-option :key="index" :value="state" v-for="(state, index) in status">{{ state }}</a-select-option>
</a-select>
<a-button @click="handleTableChange" class="mx-2" type="primary">搜索</a-button>
</div>
<div class="flex-1"></div>
<a-button @click="showModal" class="editable-add-btn">增加</a-button>
<!-- 添加 -->
<activity-add :visible="visible" @closeModal="closeModal" />
</div>
</template>
<script>
import ActivityAdd from "components/Activity/ActivityAdd.vue";
// import { selLikeTeam } from 'config/api';
export default {
name: "ActivitySearch",
components: {
ActivityAdd,
},
data() {
return {
visible: false,
publishingPlatform: '',
categories: [
{id:1,name:'路演'},
{id:2,name:'沙龙'},
{id:3,name:'论坛'},
{id:4,name:'培训'},
{id:5,name:'讲座'},
{id:6,name:'创业活动'}
],
category: '',
place: '',
organizer: '',
speaker: '',
status: ['发布','不发布'],
state: '',
platforms: ['绿谷','维基'],
platform: ''
}
},
methods: {
showModal(){
this.visible = true;
},
closeModal(){
this.visible = false;
},
handleChange(type, e) {
this.type = e.target.value;
},
//
getPlatform(value) {
console.log('value: ', value);
this.platform = value;
},
//
getCategory(value) {
console.log('value: ', value);
this.category = value;
},
//
getState(value) {
console.log('value: ', value);
this.state = value;
},
//
onChange(dates, dateStrings) {
console.log('From: ', dates[0], ', to: ', dates[1]);
console.log('From: ', dateStrings[0], ', to: ', dateStrings[1]);
},
async handleTableChange() {
try {
// const params = { param: {publishingPlatform: this.publishingPlatform} };
// const res = await selLikeTeam(params);
// const { data, msg, code } = res.data;
// if (code === 200) {
// console.log('',data);
// // TODO:
// } else {
// throw msg;
// }
} catch (error) {
this.$message.error(error);
}
},
},
};
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="stylus"></style>

122
src/components/Banner/BannerAdd.vue

@ -0,0 +1,122 @@
<template>
<div class="d-flex flex-wrap pb-3">
<!-- 添加 -->
<a-modal :closable="false" footer title="添加轮播图" v-model="visible" width="700px">
<a-form :form="form" @submit="handleSubmit">
<!-- 页面路径 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="页面路径"
>
<a-input
placeholder="页面路径"
v-decorator="[
'pagePath',
{
rules: [
{ required: true, message: '页面路径不能为空' },
{ whitespace: true, message: '页面路径不能为空' },
{ max: 140, massage: '页面路径最多140个字符' },
],
},
]"
/>
</a-form-item>
<!-- 排序 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="排序"
>
<a-input
placeholder="排序"
v-decorator="[
'sort',
{
rules: [
{ required: true, message: '排序不能为空' },
{ whitespace: true, message: '排序不能为空' },
{ max: 140, massage: '排序最多140个字符' },
],
},
]"
/>
</a-form-item>
<!-- 跳转路径 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="跳转路径"
>
<a-input
placeholder="跳转路径"
v-decorator="[
'jumpPath',
{
rules: [
{ required: true, message: '跳转路径不能为空' },
{ whitespace: true, message: '跳转路径不能为空' },
{ max: 140, massage: '跳转路径最多140个字符' },
],
},
]"
/>
</a-form-item>
<a-form-item class="d-flex flex-row-reverse">
<a-button @click="$emit('closeModal')" class="mr-3">取消</a-button>
<a-button class="white--text" html-type="submit" type="primary">保存</a-button>
</a-form-item>
</a-form>
</a-modal>
</div>
</template>
<script>
// import { addTeam } from 'config/api'
const formItemLayout = {
labelCol: { span: 6 },
wrapperCol: { span: 16 },
};
const tailItemLayout = { wrapperCol: { span: 16, offset: 6 } };
export default {
name: "BannerAdd",
props: { visible: { type: Boolean, default: false } },
data() {
return {
formItemLayout,
tailItemLayout,
form: this.$form.createForm(this, { name: 'r-d-add' }),
}
},
methods: {
//
handleSubmit(e) {
e.preventDefault();
this.form.validateFieldsAndScroll(async (err, values) => {
if (!err) {
try {
// const params = { param: values };
// const res = await addTeam(params);
// const { data, msg, code } = res.data;
// this.$emit('closeModal');
// if (code === 200) {
// this.$message.success('')
// // TODO:
// } else {
// throw msg;
// }
} catch (error) {
this.$message.error(error || '添加失败');
}
}
});
},
},
};
</script>
<style scoped lang="stylus"></style>

151
src/components/Banner/BannerDate.vue

@ -0,0 +1,151 @@
<template>
<div class="main flex-1">
<div style="width:100%" v-if="lists && lists.length > 0">
<a-table
:columns="columns"
:data-source="lists"
:loading="loading"
:row-key="record => record.id"
bordered
class="white"
>
<template slot="id" slot-scope="text, record, index">
<span>{{ index + 1 }}</span>
</template>
<template slot="edit" slot-scope="text, record">
<a-icon @click="showEditModal(record)" class="pointer" theme="twoTone" type="edit" />
<a-popconfirm @confirm="() => onDelete(record.id)" title="确定要删除这一条?" v-if="lists.length">
<a-icon class="ml-4 pointer" theme="twoTone" two-tone-color="#ff0000" type="delete" />
</a-popconfirm>
<a-switch checked-children="启用" class="ml-4" default-checked un-checked-children="禁用" />
</template>
</a-table>
</div>
<a-empty v-else />
<!-- 编辑 -->
<banner-edit :editItem="editItem" :editVisible="editVisible" @closeModal="closeModal" />
</div>
</template>
<script>
import BannerEdit from "components/Banner/BannerEdit.vue";
// import { delTeam } from 'config/api';
const columns = [
{
title: '序号',
align: 'center',
dataIndex: 'id',
key: 'id',
scopedSlots: { customRender: 'id' },
},
{
title: '页面路径',
align: 'center',
dataIndex: 'pagePath',
key: 'pagePath',
scopedSlots: { customRender: 'pagePath' },
},
{
title: '排序',
align: 'center',
dataIndex: 'sort',
key: 'sort',
scopedSlots: { customRender: 'sort' },
},
{
title: '跳转路径',
align: 'center',
dataIndex: 'jumpPath',
key: 'jumpPath',
scopedSlots: { customRender: 'jumpPath' },
},
{
title: '编辑',
align: 'center',
dataIndex: 'edit',
key: 'edit',
width: 200,
scopedSlots: { customRender: 'edit' },
},
];
const lists = [
{
id:'001',
pagePath:'http://localhost:8080/',
sort:1,
jumpPath: 'https://test.tall.wiki/pt-dev/user/login?redirect=%2F',
},
{
id:'002',
pagePath:'http://localhost:8080/',
sort:2,
jumpPath: 'https://test.tall.wiki/pt-dev/user/login?redirect=%2F',
}
];
export default {
name: "BannerDate",
components: {
BannerEdit,
},
data() {
this.cacheData = lists.map(item => ({ ...item }));
return {
columns,
lists,
loading: false,
editingKey: '',
height: '',
editVisible: false,
editItem: null, //
}
},
mounted() {
this.height = document.getElementsByClassName('main')[0].offsetHeight - 150;
},
methods: {
showEditModal(record){
console.log('record: ', record);
this.editItem = record;
this.editVisible = true;
},
closeModal(){
this.editVisible = false;
},
//
async onDelete(teamId) {
try {
// const params = { param: { teamId } };
// const res = await delTeam(params);
// const { data, msg, code } = res.data;
// if (code === 200) {
// this.$message.success('');
// const arr = [...this.lists];
// this.lists = arr.filter(item => item.id !== teamId);
// // TODO:
// } else {
// throw msg;
// }
} catch (error) {
this.$message.error(error || '删除失败');
}
},
//
openSignUp(){
const { query } = this.$route;
this.$router.push({ path: '/sign-up', query });
}
},
};
</script>
<style scoped lang="stylus"></style>

124
src/components/Banner/BannerEdit.vue

@ -0,0 +1,124 @@
<template>
<div class="d-flex flex-wrap pb-3">
<!-- 编辑 -->
<a-modal :closable="false" footer title="修改轮播图" v-model="editVisible" width="700px">
<a-form :form="form" @submit="handleSubmit">
<!-- 页面路径 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="页面路径"
>
<a-input
placeholder="页面路径"
v-decorator="[
'pagePath',
{
rules: [
{ required: true, message: '页面路径不能为空' },
{ whitespace: true, message: '页面路径不能为空' },
{ max: 140, massage: '页面路径最多140个字符' },
],
},
]"
/>
</a-form-item>
<!-- 排序 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="排序"
>
<a-input
placeholder="排序"
v-decorator="[
'sort',
{
rules: [
{ required: true, message: '排序不能为空' },
{ whitespace: true, message: '排序不能为空' },
{ max: 140, massage: '排序最多140个字符' },
],
},
]"
/>
</a-form-item>
<!-- 跳转路径 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="跳转路径"
>
<a-input
placeholder="跳转路径"
v-decorator="[
'jumpPath',
{
rules: [
{ required: true, message: '跳转路径不能为空' },
{ whitespace: true, message: '跳转路径不能为空' },
{ max: 140, massage: '跳转路径最多140个字符' },
],
},
]"
/>
</a-form-item>
<a-form-item class="d-flex flex-row-reverse">
<a-button @click="$emit('closeModal')" class="mr-3">取消</a-button>
<a-button class="white--text" html-type="submit" type="primary">保存</a-button>
</a-form-item>
</a-form>
</a-modal>
</div>
</template>
<script>
// import { upTeam } from 'config/api';
const formItemLayout = {
labelCol: { span: 6 },
wrapperCol: { span: 16 },
};
const tailItemLayout = { wrapperCol: { span: 16, offset: 6 } };
export default {
name: "BannerEdit",
props: { editVisible: { type: Boolean, default: false },editItem: { type: Object, default: () => {} } },
data() {
return {
formItemLayout,
tailItemLayout,
form: this.$form.createForm(this, { name: 'r-d-add' }),
}
},
methods: {
//
handleSubmit(e) {
e.preventDefault();
this.form.validateFieldsAndScroll(async (err, values) => {
if (!err) {
try {
// const params = { param: values };
// const res = await upTeam(params);
// const { data, msg, code } = res.data;
// this.$emit('closeModal');
// if (code === 200) {
// this.$message.success('')
// // TODO:
// } else {
// throw msg;
// }
} catch (error) {
this.$message.error(error || '修改失败');
}
}
});
},
},
};
</script>
<style scoped lang="stylus"></style>

73
src/components/Banner/BannerSearch.vue

@ -0,0 +1,73 @@
<template>
<div class="d-flex flex-wrap pb-3">
<div>
<!-- 启用 -->
<a-select @change="getUse" class="ml-3" default-value="启用" style="width: 150px">
<a-select-option :key="use" :value="use" v-for="use in enable">{{ use }}</a-select-option>
</a-select>
<a-button @click="handleTableChange" class="mx-2" type="primary">搜索</a-button>
</div>
<div class="flex-1"></div>
<a-button @click="showModal" class="editable-add-btn">增加</a-button>
<!-- 添加 -->
<banner-add :visible="visible" @closeModal="closeModal" />
</div>
</template>
<script>
import BannerAdd from "components/Banner/BannerAdd.vue";
// import { selLikeTeam } from 'config/api';
export default {
name: "BannerSearch",
components: {
BannerAdd,
},
data() {
return {
visible: false,
enable: ['启用','禁用'],
use: '',
}
},
methods: {
showModal(){
this.visible = true;
},
closeModal(){
this.visible = false;
},
//
getUse(value) {
console.log('value: ', value);
this.use = value;
},
async handleTableChange() {
try {
// const params = { param: {publishingPlatform: this.publishingPlatform} };
// const res = await selLikeTeam(params);
// const { data, msg, code } = res.data;
// if (code === 200) {
// console.log('',data);
// // TODO:
// } else {
// throw msg;
// }
} catch (error) {
this.$message.error(error);
}
},
},
};
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="stylus"></style>

69
src/components/BtnCom/BtnCon.vue

@ -0,0 +1,69 @@
<template>
<div class="btn-box pa-3">
<div class="font-bold-24">行政部</div>
<div @click="jump('/page-manage')" class="btn">内容管理</div>
<div @click="jump('/industry-info')" class="btn">行业资讯</div>
<div @click="jump('/talent-recruitment')" class="btn">人才招聘</div>
<div @click="jump('/user-manage')" class="btn">用户管理</div>
<div @click="jump('/banner-manage')" class="btn">轮播图管理</div>
<div @click="jump('/communication-community')" class="btn">交流社区</div>
<div @click="jump('/event-announcement')" class="btn">活动公告</div>
<div @click="jump('/innovation-policy')" class="btn">创新政策</div>
<div class="font-bold-24">创新部</div>
<div @click="jump('/cooperation-intention')" class="btn">合作意向</div>
<div @click="jump('/demand-filling')" class="btn">需求填报</div>
<div @click="jump('/innovative-service')" class="btn">服务</div>
<div @click="jump('/innovative-lab')" class="btn">实验室</div>
<div @click="jump('/category-manage')" class="btn">分类管理</div>
<div @click="jump('/innovative-equipment')" class="btn">设备</div>
<div @click="jump('/innovative-achievements')" class="btn">成果</div>
<div class="font-bold-24">孵化部</div>
<div @click="jump('/entity-application')" class="btn">入驻实体申请</div>
<div @click="jump('/virtual-application')" class="btn">入驻虚拟申请</div>
<div @click="jump('/incubation-services')" class="btn">服务</div>
<div @click="jump('/entrepreneurial-mentor')" class="btn">需求填报</div>
<div class="font-bold-24">产业部</div>
<div @click="jump('/industrial-services')" class="btn">服务</div>
<div @click="jump('/derivative-enterprise')" class="btn">衍生企业</div>
<div @click="jump('/industry-demand-report')" class="btn">需求填报</div>
</div>
</template>
<script>
export default {
name: 'BtnCom',
data() {
return {
str: '',
showVideo: false,
};
},
methods: {
jump(url) {
this.$router.push(url);
},
},
};
</script>
<style lang="stylus" scoped>
.btn-box {
width: 10%;
border-right: 1px solid #ccc;
overflow: auto;
.btn {
background: #1890ff;
border: 1px solid #1890ff;
padding: 4px;
border-radius: 5px;
color: #fff;
cursor: pointer;
margin-bottom: 8px;
}
}
</style>

213
src/components/CVideo/VideoAdd.vue

@ -0,0 +1,213 @@
<template>
<div class="d-flex flex-wrap pb-3">
<!-- 添加 -->
<a-modal :closable="false" footer title="添加课程" v-model="visible" width="700px">
<a-form :form="form" @submit="handleSubmit">
<!-- 课程 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="课程"
>
<a-input
placeholder="课程"
v-decorator="[
'course',
{
rules: [
{ required: true, message: '课程不能为空' },
{ whitespace: true, message: '课程不能为空' },
{ max: 140, massage: '课程最多140个字符' },
],
},
]"
/>
</a-form-item>
<!-- 视频名称 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="视频名称"
>
<a-input
placeholder="视频名称"
v-decorator="[
'videoName',
{
rules: [
{ required: true, message: '视频名称不能为空' },
{ whitespace: true, message: '视频名称不能为空' },
{ max: 140, massage: '视频名称最多140个字符' },
],
},
]"
/>
</a-form-item>
<!-- 封面 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="封面"
>
<a-upload
:before-upload="beforeUpload"
:show-upload-list="false"
@change="handleChange"
action="https://www.mocky.io/v2/5cc8019d300000980a055e76"
class="avatar-uploader"
list-type="picture-card"
name="avatar"
>
<img :src="imageUrl" alt="avatar" v-if="imageUrl" />
<div v-else>
<a-icon :type="loading ? 'loading' : 'plus'" />
<div class="ant-upload-text">Upload</div>
</div>
</a-upload>
</a-form-item>
<!-- 第几集 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="第几集"
>
<a-input
placeholder="第几集"
v-decorator="[
'setNumber',
{
rules: [
{ required: true, message: '第几集不能为空' },
{ whitespace: true, message: '第几集不能为空' },
{ max: 140, massage: '第几集最多140个字符' },
],
},
]"
/>
</a-form-item>
<!-- 主讲人 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="主讲人"
>
<a-input
placeholder="主讲人"
v-decorator="[
'speaker',
{
rules: [
{ required: true, message: '主讲人不能为空' },
{ whitespace: true, message: '主讲人不能为空' },
{ max: 140, massage: '主讲人最多140个字符' },
],
},
]"
/>
</a-form-item>
<a-form-item class="d-flex flex-row-reverse">
<a-button @click="$emit('closeModal')" class="mr-3">取消</a-button>
<a-button class="white--text" html-type="submit" type="primary">保存</a-button>
</a-form-item>
</a-form>
</a-modal>
</div>
</template>
<script>
const formItemLayout = {
labelCol: { span: 6 },
wrapperCol: { span: 16 },
};
const tailItemLayout = { wrapperCol: { span: 16, offset: 6 } };
function getBase64(img, callback) {
const reader = new FileReader();
reader.addEventListener('load', () => callback(reader.result));
reader.readAsDataURL(img);
}
export default {
name: "VideoAdd",
props: { visible: { type: Boolean, default: false } },
data() {
return {
formItemLayout,
tailItemLayout,
form: this.$form.createForm(this, { name: 'video-add' }),
loading: false,
imageUrl: '',
}
},
methods: {
//
handleChange(info) {
if (info.file.status === 'uploading') {
this.loading = true;
return;
}
if (info.file.status === 'done') {
// Get this url from response in real world.
getBase64(info.file.originFileObj, imageUrl => {
this.imageUrl = imageUrl;
this.loading = false;
});
}
},
beforeUpload(file) {
const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png';
if (!isJpgOrPng) {
this.$message.error('You can only upload JPG file!');
}
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isLt2M) {
this.$message.error('Image must smaller than 2MB!');
}
return isJpgOrPng && isLt2M;
},
//
handleSubmit(e) {
e.preventDefault();
this.form.validateFieldsAndScroll(async (err, values) => {
if (!err) {
try {
console.log('values: ', values);
// const params = this.generateParams(values);
// const res = await createTask(params);
// const { data, msg, code } = res.data;
// //
// this.clearCreateTask();
// this.$emit('closeDialog');
// if (code === 200) {
// this.handleCreateSuccess(params.executorId);
// } else {
// throw msg;
// }
} catch (error) {
this.$message.error(error || '添加研发团队失败');
}
}
});
},
},
};
</script>
<style scoped lang="stylus">
.avatar-uploader > .ant-upload {
width: 128px;
height: 128px;
}
.ant-upload-select-picture-card i {
font-size: 32px;
color: #999;
}
.ant-upload-select-picture-card .ant-upload-text {
margin-top: 8px;
color: #666;
}
</style>

199
src/components/CVideo/VideoDate.vue

@ -0,0 +1,199 @@
<template>
<div class="main flex-1">
<div style="width:100%" v-if="lists && lists.length > 0">
<a-table
:columns="columns"
:data-source="lists"
:loading="loading"
:row-key="record => record.id"
bordered
class="white"
>
<template slot="id" slot-scope="text, record, index">
<span>{{ index + 1 }}</span>
</template>
<!-- 封面 -->
<template slot="cover" slot-scope="text, record">
<img :src="record.cover" class="img" />
<a-modal :imgVisible="imgVisible" @cancel="imgVisible = false" footer title="身份证明">
<img :src="record.idCardPromise" @click="imgVisible = true" style="width: 100%;" />
</a-modal>
</template>
<template slot="auditStatus" slot-scope="text, record">
<a-tag :color="record.auditStatus === '通过' ? 'green' : 'red'">{{ record.auditStatus }}</a-tag>
</template>
<template slot="edit" slot-scope="text, record">
<a-icon @click="showEditModal" class="pointer" theme="twoTone" type="edit" />
<a-popconfirm @confirm="() => onDelete(record.id)" title="确定要删除这一条?" v-if="lists.length">
<a-icon class="ml-4 pointer" theme="twoTone" two-tone-color="#ff0000" type="delete" />
</a-popconfirm>
<a-switch checked-children="上架" class="ml-4" default-checked un-checked-children="下架" />
</template>
<template slot="examine" slot-scope="text, record">
<a-button size="small" type="primary" v-if="record.auditStatus != '通过'">通过</a-button>
<a-button size="small" type="danger" v-else>不通过</a-button>
</template>
</a-table>
</div>
<a-empty v-else />
<!-- 编辑 -->
<video-edit :editVisible="editVisible" @closeModal="closeModal" />
</div>
</template>
<script>
import VideoEdit from "components/CVideo/VideoEdit.vue";
const columns = [
{
title: '序号',
align: 'center',
dataIndex: 'id',
key: 'id',
width: '7%',
scopedSlots: { customRender: 'id' },
},
{
title: '课程',
align: 'center',
dataIndex: 'course',
key: 'course',
},
{
title: '视频名称',
align: 'center',
dataIndex: 'videoName',
key: 'videoName',
},
{
title: '封面',
align: 'center',
dataIndex: 'cover',
key: 'cover',
scopedSlots: { customRender: 'cover' },
},
{
title: '第几集',
align: 'center',
dataIndex: 'setNumber',
key: 'setNumber',
scopedSlots: { customRender: 'setNumber' },
},
{
title: '主讲人',
align: 'center',
dataIndex: 'speaker',
key: 'speaker',
scopedSlots: { customRender: 'speaker' },
},
{
title: '审核状态',
align: 'center',
dataIndex: 'auditStatus',
key: 'auditStatus',
scopedSlots: { customRender: 'auditStatus' },
},
{
title: '编辑',
align: 'center',
dataIndex: 'edit',
key: 'edit',
width: 200,
scopedSlots: { customRender: 'edit' },
},
{
title: '审核',
align: 'center',
dataIndex: 'examine',
key: 'examine',
scopedSlots: { customRender: 'examine' },
},
];
const lists = [
{
id:'001',
course:'传控科技',
videoName: '传控科技宣传片',
cover:'assets/logo.png',
setNumber: 5,
speaker: '张三',
auditStatus: '通过',
},
{
id:'002',
course:'中绿环保',
videoName: '传控科技宣传片',
cover:'assets/logo.png',
setNumber: 6,
speaker: '张三',
auditStatus: '未通过',
}
];
export default {
name: "VideoDate",
components: {
VideoEdit,
},
data() {
this.cacheData = lists.map(item => ({ ...item }));
return {
columns,
lists,
loading: false,
height: '',
editVisible: false,
imgVisible: false,
}
},
mounted() {
this.height = document.getElementsByClassName('main')[0].offsetHeight - 150;
},
methods: {
showEditModal(){
this.editVisible = true;
},
closeModal(){
this.editVisible = false;
},
//
async onDelete(teamId) {
try {
const params = { param: { teamId } };
// const res = await delTeam(params);
// const { data, msg, code } = res.data;
// if (code === 200) {
// this.$message.success('');
// const arr = [...this.lists];
// this.lists = arr.filter(item => item.id !== teamId);
// // TODO:
// } else {
// throw msg;
// }
} catch (error) {
this.$message.error(error || '删除失败');
}
},
},
};
</script>
<style lang="stylus" scoped>
.main .img {
width: 100%;
}
.main .big_img {
width: 200px;
}
</style>

213
src/components/CVideo/VideoEdit.vue

@ -0,0 +1,213 @@
<template>
<div class="d-flex flex-wrap pb-3">
<!-- 编辑 -->
<a-modal :closable="false" footer title="修改课程" v-model="editVisible" width="700px">
<a-form :form="form" @submit="handleSubmit">
<!-- 课程 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="课程"
>
<a-input
placeholder="课程"
v-decorator="[
'course',
{
rules: [
{ required: true, message: '课程不能为空' },
{ whitespace: true, message: '课程不能为空' },
{ max: 140, massage: '课程最多140个字符' },
],
},
]"
/>
</a-form-item>
<!-- 视频名称 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="视频名称"
>
<a-input
placeholder="视频名称"
v-decorator="[
'videoName',
{
rules: [
{ required: true, message: '视频名称不能为空' },
{ whitespace: true, message: '视频名称不能为空' },
{ max: 140, massage: '视频名称最多140个字符' },
],
},
]"
/>
</a-form-item>
<!-- 封面 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="封面"
>
<a-upload
:before-upload="beforeUpload"
:show-upload-list="false"
@change="handleChange"
action="https://www.mocky.io/v2/5cc8019d300000980a055e76"
class="avatar-uploader"
list-type="picture-card"
name="avatar"
>
<img :src="imageUrl" alt="avatar" v-if="imageUrl" />
<div v-else>
<a-icon :type="loading ? 'loading' : 'plus'" />
<div class="ant-upload-text">Upload</div>
</div>
</a-upload>
</a-form-item>
<!-- 第几集 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="第几集"
>
<a-input
placeholder="第几集"
v-decorator="[
'setNumber',
{
rules: [
{ required: true, message: '第几集不能为空' },
{ whitespace: true, message: '第几集不能为空' },
{ max: 140, massage: '第几集最多140个字符' },
],
},
]"
/>
</a-form-item>
<!-- 主讲人 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="主讲人"
>
<a-input
placeholder="主讲人"
v-decorator="[
'speaker',
{
rules: [
{ required: true, message: '主讲人不能为空' },
{ whitespace: true, message: '主讲人不能为空' },
{ max: 140, massage: '主讲人最多140个字符' },
],
},
]"
/>
</a-form-item>
<a-form-item class="d-flex flex-row-reverse">
<a-button @click="$emit('closeModal')" class="mr-3">取消</a-button>
<a-button class="white--text" html-type="submit" type="primary">保存</a-button>
</a-form-item>
</a-form>
</a-modal>
</div>
</template>
<script>
const formItemLayout = {
labelCol: { span: 6 },
wrapperCol: { span: 16 },
};
const tailItemLayout = { wrapperCol: { span: 16, offset: 6 } };
function getBase64(img, callback) {
const reader = new FileReader();
reader.addEventListener('load', () => callback(reader.result));
reader.readAsDataURL(img);
}
export default {
name: "VideoEdit",
props: { editVisible: { type: Boolean, default: false } },
data() {
return {
formItemLayout,
tailItemLayout,
form: this.$form.createForm(this, { name: 'video-edit' }),
loading: false,
imageUrl: '',
}
},
methods: {
//
handleChange(info) {
if (info.file.status === 'uploading') {
this.loading = true;
return;
}
if (info.file.status === 'done') {
// Get this url from response in real world.
getBase64(info.file.originFileObj, imageUrl => {
this.imageUrl = imageUrl;
this.loading = false;
});
}
},
beforeUpload(file) {
const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png';
if (!isJpgOrPng) {
this.$message.error('You can only upload JPG file!');
}
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isLt2M) {
this.$message.error('Image must smaller than 2MB!');
}
return isJpgOrPng && isLt2M;
},
//
handleSubmit(e) {
e.preventDefault();
this.form.validateFieldsAndScroll(async (err, values) => {
if (!err) {
try {
console.log('values: ', values);
// const params = this.generateParams(values);
// const res = await createTask(params);
// const { data, msg, code } = res.data;
// //
// this.clearCreateTask();
// this.$emit('closeDialog');
// if (code === 200) {
// this.handleCreateSuccess(params.executorId);
// } else {
// throw msg;
// }
} catch (error) {
this.$message.error(error || '添加研发团队失败');
}
}
});
},
},
};
</script>
<style scoped lang="stylus">
.avatar-uploader > .ant-upload {
width: 128px;
height: 128px;
}
.ant-upload-select-picture-card i {
font-size: 32px;
color: #999;
}
.ant-upload-select-picture-card .ant-upload-text {
margin-top: 8px;
color: #666;
}
</style>

54
src/components/CVideo/VideoSearch.vue

@ -0,0 +1,54 @@
<template>
<div class="d-flex flex-wrap pb-3">
<!-- 课程 -->
<div>
<a-input @change="handleChangeCourse" placeholder="课程" style="width: 150px" v-model="course" />
<a-button @click="handleTableChange" class="ml-3" type="primary">搜索</a-button>
</div>
<div class="flex-1"></div>
<a-button @click="showModal" class="editable-add-btn">增加</a-button>
<!-- 添加 -->
<video-add :visible="visible" @closeModal="closeModal" />
</div>
</template>
<script>
import VideoAdd from "components/CVideo/VideoAdd.vue";
export default {
name: "VideoSearch",
components: {
VideoAdd,
},
data() {
return {
visible: false,
course: '',
}
},
methods: {
showModal(){
this.visible = true;
},
closeModal(){
this.visible = false;
},
handleChangeCourse(value) {
console.log('value: ', value);
this.course = value;
},
handleTableChange() {
console.log('搜索');
},
},
};
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="stylus"></style>

154
src/components/Challenge/ChallengeAdd.vue

@ -0,0 +1,154 @@
<template>
<div class="d-flex flex-wrap pb-3">
<!-- 添加 -->
<a-modal :closable="false" footer title="添加创新挑战" v-model="visible" width="700px">
<a-form :form="form" @submit="handleSubmit">
<!-- 来源 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="来源"
>
<a-radio-group @change="getSource" v-model="source">
<a-radio :value="1">平台</a-radio>
<a-radio :value="2">用户</a-radio>
</a-radio-group>
</a-form-item>
<!-- 标题 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="标题"
>
<a-input
placeholder="标题"
v-decorator="[
'superiorType',
{
rules: [
{ required: true, message: '标题不能为空' },
{ whitespace: true, message: '标题不能为空' },
{ max: 140, massage: '标题最多140个字符' },
],
},
]"
/>
</a-form-item>
<!-- 内容 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="内容"
>
<a-textarea
placeholder="内容"
v-decorator="[
'content',
]"
/>
</a-form-item>
<!-- 发布时间 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="发布时间"
>
<a-date-picker
@change="onChange"
format="YYYY/MM/DD HH:mm:ss"
show-time
style="width:100%"
/>
</a-form-item>
<!-- 发布人姓名 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="发布人姓名"
>
<a-input
placeholder="发布人姓名"
v-decorator="[
'publisher',
{
rules: [
{ required: true, message: '发布人姓名不能为空' },
{ whitespace: true, message: '发布人姓名不能为空' },
{ max: 140, massage: '发布人姓名最多140个字符' },
],
},
]"
/>
</a-form-item>
<a-form-item class="d-flex flex-row-reverse">
<a-button @click="$emit('closeModal')" class="mr-3">取消</a-button>
<a-button class="white--text" html-type="submit" type="primary">保存</a-button>
</a-form-item>
</a-form>
</a-modal>
</div>
</template>
<script>
const formItemLayout = {
labelCol: { span: 6 },
wrapperCol: { span: 16 },
};
const tailItemLayout = { wrapperCol: { span: 16, offset: 6 } };
export default {
name: "ChallengeAdd",
props: { visible: { type: Boolean, default: false } },
data() {
return {
formItemLayout,
tailItemLayout,
form: this.$form.createForm(this, { name: 'challenge-add' }),
source: 1,
releaseTime: '', //
}
},
methods: {
//
getSource(value){
this.source = value
},
//
onChange(dates, dateStrings) {
console.log('From: ', dates[0], ', to: ', dates[1]);
console.log('From: ', dateStrings[0], ', to: ', dateStrings[1]);
},
//
handleSubmit(e) {
e.preventDefault();
this.form.validateFieldsAndScroll(async (err, values) => {
if (!err) {
try {
console.log('values: ', values);
// const params = this.generateParams(values);
// const res = await createTask(params);
// const { data, msg, code } = res.data;
// //
// this.clearCreateTask();
// this.$emit('closeDialog');
// if (code === 200) {
// this.handleCreateSuccess(params.executorId);
// } else {
// throw msg;
// }
} catch (error) {
this.$message.error(error || '添加研发团队失败');
}
}
});
},
},
};
</script>
<style scoped lang="stylus"></style>

186
src/components/Challenge/ChallengeDate.vue

@ -0,0 +1,186 @@
<template>
<div class="main flex-1">
<div style="width:100%" v-if="lists && lists.length > 0">
<a-table
:columns="columns"
:data-source="lists"
:loading="loading"
:row-key="record => record.id"
bordered
class="white"
>
<template slot="id" slot-scope="text, record, index">
<span>{{ index + 1 }}</span>
</template>
<template slot="auditStatus" slot-scope="text, record">
<a-tag :color="record.auditStatus === '通过' ? 'green' : 'red'">{{ record.auditStatus }}</a-tag>
</template>
<template slot="edit" slot-scope="text, record">
<a-icon @click="showEditModal" class="pointer" theme="twoTone" type="edit" />
<a-popconfirm @confirm="() => onDelete(record.id)" title="确定要删除这一条?" v-if="lists.length">
<a-icon class="ml-4 pointer" theme="twoTone" two-tone-color="#ff0000" type="delete" />
</a-popconfirm>
</template>
<template slot="examine" slot-scope="text, record">
<a-button size="small" type="primary" v-if="record.auditStatus != '通过'">通过</a-button>
<a-button size="small" type="danger" v-else>不通过</a-button>
</template>
<div slot="expandedRowRender" slot-scope="record" style="margin: 0">
<div class="mb-2">内容{{ record.content }}</div>
<div>发布时间{{ record.content }}</div>
</div>
</a-table>
</div>
<a-empty v-else />
<!-- 编辑 -->
<challenge-edit :editVisible="editVisible" @closeModal="closeModal" />
</div>
</template>
<script>
import ChallengeEdit from "components/Challenge/ChallengeEdit.vue";
const columns = [
{
title: '序号',
align: 'center',
dataIndex: 'id',
key: 'id',
width: '7%',
scopedSlots: { customRender: 'id' },
},
{
title: '来源',
align: 'center',
dataIndex: 'source',
key: 'source',
},
{
title: '标题',
align: 'center',
dataIndex: 'title',
key: 'title',
},
// {
// title: '',
// align: 'center',
// dataIndex: 'releaseTime',
// key: 'releaseTime',
// scopedSlots: { customRender: 'releaseTime' },
// },
{
title: '发布人姓名',
align: 'center',
dataIndex: 'publisher',
key: 'publisher',
},
{
title: '审核状态',
align: 'center',
dataIndex: 'auditStatus',
key: 'auditStatus',
scopedSlots: { customRender: 'auditStatus' },
},
{
title: '审核人',
align: 'center',
dataIndex: 'checker',
key: 'checker',
},
{
title: '编辑',
align: 'center',
dataIndex: 'edit',
key: 'edit',
scopedSlots: { customRender: 'edit' },
},
{
title: '审核',
align: 'center',
dataIndex: 'examine',
key: 'examine',
scopedSlots: { customRender: 'examine' },
},
];
const lists = [
{
id:'001',
source:'平台',
title: '博士',
content: '内容内容内容内容内容',
releaseTime: '2020/11/18 15:00',
publisher: '张三',
auditStatus: '通过',
checker: '李四',
},
{
id:'002',
source:'用户',
title: '博士',
content: '内容内容内容内容内容',
releaseTime: '2020/11/18 15:00',
publisher: '张三',
auditStatus: '未通过',
checker: '李四',
}
];
export default {
name: "ChallengeDate",
components: {
ChallengeEdit,
},
data() {
this.cacheData = lists.map(item => ({ ...item }));
return {
columns,
lists,
loading: false,
editingKey: '',
height: '',
editVisible: false
}
},
mounted() {
this.height = document.getElementsByClassName('main')[0].offsetHeight - 150;
},
methods: {
showEditModal(){
this.editVisible = true;
},
closeModal(){
this.editVisible = false;
},
//
async onDelete(teamId) {
try {
const params = { param: { teamId } };
// const res = await delTeam(params);
// const { data, msg, code } = res.data;
// if (code === 200) {
// this.$message.success('');
// const arr = [...this.lists];
// this.lists = arr.filter(item => item.id !== teamId);
// // TODO:
// } else {
// throw msg;
// }
} catch (error) {
this.$message.error(error || '删除失败');
}
},
},
};
</script>
<style scoped lang="stylus"></style>

154
src/components/Challenge/ChallengeEdit.vue

@ -0,0 +1,154 @@
<template>
<div class="d-flex flex-wrap pb-3">
<!-- 编辑 -->
<a-modal :closable="false" footer title="修改创新挑战" v-model="editVisible" width="700px">
<a-form :form="form" @submit="handleSubmit">
<!-- 来源 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="来源"
>
<a-radio-group @change="getSource" v-model="source">
<a-radio :value="1">平台</a-radio>
<a-radio :value="2">用户</a-radio>
</a-radio-group>
</a-form-item>
<!-- 标题 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="标题"
>
<a-input
placeholder="标题"
v-decorator="[
'superiorType',
{
rules: [
{ required: true, message: '标题不能为空' },
{ whitespace: true, message: '标题不能为空' },
{ max: 140, massage: '标题最多140个字符' },
],
},
]"
/>
</a-form-item>
<!-- 内容 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="内容"
>
<a-textarea
placeholder="内容"
v-decorator="[
'content',
]"
/>
</a-form-item>
<!-- 发布时间 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="发布时间"
>
<a-date-picker
@change="onChange"
format="YYYY/MM/DD HH:mm:ss"
show-time
style="width:100%"
/>
</a-form-item>
<!-- 发布人姓名 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="发布人姓名"
>
<a-input
placeholder="发布人姓名"
v-decorator="[
'publisher',
{
rules: [
{ required: true, message: '发布人姓名不能为空' },
{ whitespace: true, message: '发布人姓名不能为空' },
{ max: 140, massage: '发布人姓名最多140个字符' },
],
},
]"
/>
</a-form-item>
<a-form-item class="d-flex flex-row-reverse">
<a-button @click="$emit('closeModal')" class="mr-3">取消</a-button>
<a-button class="white--text" html-type="submit" type="primary">保存</a-button>
</a-form-item>
</a-form>
</a-modal>
</div>
</template>
<script>
const formItemLayout = {
labelCol: { span: 6 },
wrapperCol: { span: 16 },
};
const tailItemLayout = { wrapperCol: { span: 16, offset: 6 } };
export default {
name: "ChallengeEdit",
props: { editVisible: { type: Boolean, default: false } },
data() {
return {
formItemLayout,
tailItemLayout,
form: this.$form.createForm(this, { name: 'challeng-edit' }),
source: 1,
releaseTime: '', //
}
},
methods: {
//
getSource(value){
this.source = value
},
//
onChange(dates, dateStrings) {
console.log('From: ', dates[0], ', to: ', dates[1]);
console.log('From: ', dateStrings[0], ', to: ', dateStrings[1]);
},
//
handleSubmit(e) {
e.preventDefault();
this.form.validateFieldsAndScroll(async (err, values) => {
if (!err) {
try {
console.log('values: ', values);
// const params = this.generateParams(values);
// const res = await createTask(params);
// const { data, msg, code } = res.data;
// //
// this.clearCreateTask();
// this.$emit('closeDialog');
// if (code === 200) {
// this.handleCreateSuccess(params.executorId);
// } else {
// throw msg;
// }
} catch (error) {
this.$message.error(error || '添加研发团队失败');
}
}
});
},
},
};
</script>
<style scoped lang="stylus"></style>

61
src/components/Challenge/ChallengeSearch.vue

@ -0,0 +1,61 @@
<template>
<div class="d-flex flex-wrap pb-3">
<div>
<!-- 来源 -->
<a-input @change="handleChangeSource" placeholder="来源" style="width: 150px" v-model="source" />
<a-button @click="handleTableChange" class="mx-2" type="primary">搜索</a-button>
</div>
<div class="flex-1"></div>
<a-button @click="openUnveilingList" class="editable-add-btn">揭榜</a-button>
<a-button @click="showModal" class="ml-3 editable-add-btn">增加</a-button>
<!-- 添加 -->
<challenge-add :visible="visible" @closeModal="closeModal" />
</div>
</template>
<script>
import ChallengeAdd from "components/Challenge/ChallengeAdd.vue";
export default {
name: "ChallengeSearch",
components: {
ChallengeAdd,
},
data() {
return {
visible: false,
source: '',
}
},
methods: {
showModal(){
this.visible = true;
},
closeModal(){
this.visible = false;
},
handleChangeSource(value) {
console.log('value: ', value);
this.source = value;
},
//
openUnveilingList(){
const { query } = this.$route;
this.$router.push({ path: '/unveiling-list', query });
},
handleTableChange() {
console.log('搜索');
},
},
};
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="stylus"></style>

106
src/components/Comment/CommentDate.vue

@ -0,0 +1,106 @@
<template>
<div class="main flex-1">
<div style="width:100%" v-if="lists && lists.length > 0">
<a-table
:columns="columns"
:data-source="lists"
:loading="loading"
:row-key="record => record.id"
bordered
class="white"
>
<template slot="id" slot-scope="text, record, index">
<span>{{ index + 1 }}</span>
</template>
<div slot="expandedRowRender" slot-scope="record" style="margin: 0">
<div>评论内容{{ record.reviewersContent }}</div>
<div>被评论人内容{{ record.commentContent }}</div>
</div>
</a-table>
</div>
<a-empty v-else />
</div>
</template>
<script>
const columns = [
{
title: '序号',
align: 'center',
dataIndex: 'id',
key: 'id',
width: '7%',
scopedSlots: { customRender: 'id' },
},
{
title: '评论人',
align: 'center',
dataIndex: 'reviewers',
key: 'reviewers',
},
{
title: '内容',
align: 'center',
dataIndex: 'reviewersContent',
key: 'reviewersContent',
ellipsis: true,
},
{
title: '评论时间',
align: 'center',
dataIndex: 'reviewersTime',
key: 'reviewersTime',
scopedSlots: { customRender: 'reviewersTime' },
},
{
title: '被评论人',
align: 'center',
dataIndex: 'commentedBy',
key: 'commentedBy',
},
];
const lists = [
{
id:'001',
reviewers:'张三',
reviewersContent:'张三评论内容',
reviewersTime: '2020/11/18 18:00',
commentedBy:'传控科技',
commentContent:'被评论人内容',
},
{
id:'002',
reviewers:'赵柳',
reviewersContent:'赵柳评论内容',
reviewersTime: '2020/11/18 18:00',
commentedBy:'中绿环保',
commentContent:'被评论人内容',
}
];
export default {
name: "CommentDate",
data() {
return {
columns,
lists,
loading: false,
editingKey: '',
height: '',
editVisible: false
}
},
mounted() {
this.height = document.getElementsByClassName('main')[0].offsetHeight - 150;
},
methods: {
},
};
</script>
<style scoped lang="stylus"></style>

38
src/components/Comment/CommentSearch.vue

@ -0,0 +1,38 @@
<template>
<div class="d-flex flex-wrap pb-3">
<div>
<!-- 评论人 -->
<a-input
@change="handleChangeReviewers"
placeholder="评论人"
style="width: 150px"
v-model="reviewers"
/>
<a-button @click="handleTableChange" class="mx-2" type="primary">搜索</a-button>
</div>
</div>
</template>
<script>
export default {
name: "CommentSearch",
data() {
return {
reviewers: '',
}
},
methods: {
handleChangeReviewers(value) {
console.log('value: ', value);
this.reviewers = value;
},
handleTableChange() {
console.log('搜索');
},
},
};
</script>
<style scoped lang="stylus"></style>

166
src/components/Course/CourseAdd.vue

@ -0,0 +1,166 @@
<template>
<div class="d-flex flex-wrap pb-3">
<!-- 添加 -->
<a-modal :closable="false" footer title="添加课程" v-model="visible" width="700px">
<a-form :form="form" @submit="handleSubmit">
<!-- 课程名称 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="课程名称"
>
<a-input
placeholder="课程名称"
v-decorator="[
'courseName',
{
rules: [
{ required: true, message: '课程名称不能为空' },
{ whitespace: true, message: '课程名称不能为空' },
{ max: 140, massage: '课程名称最多140个字符' },
],
},
]"
/>
</a-form-item>
<!-- 课程简介 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="课程简介"
>
<a-textarea
placeholder="课程简介"
v-decorator="[
'courseProfile',
]"
/>
</a-form-item>
<!-- 介绍图片 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="介绍图片"
>
<a-upload
:before-upload="beforeUpload"
:show-upload-list="false"
@change="handleChange"
action="https://www.mocky.io/v2/5cc8019d300000980a055e76"
class="avatar-uploader"
list-type="picture-card"
name="avatar"
>
<img :src="imageUrl" alt="avatar" v-if="imageUrl" />
<div v-else>
<a-icon :type="loading ? 'loading' : 'plus'" />
<div class="ant-upload-text">Upload</div>
</div>
</a-upload>
</a-form-item>
<a-form-item class="d-flex flex-row-reverse">
<a-button @click="$emit('closeModal')" class="mr-3">取消</a-button>
<a-button class="white--text" html-type="submit" type="primary">保存</a-button>
</a-form-item>
</a-form>
</a-modal>
</div>
</template>
<script>
const formItemLayout = {
labelCol: { span: 6 },
wrapperCol: { span: 16 },
};
const tailItemLayout = { wrapperCol: { span: 16, offset: 6 } };
function getBase64(img, callback) {
const reader = new FileReader();
reader.addEventListener('load', () => callback(reader.result));
reader.readAsDataURL(img);
}
export default {
name: "CourseAdd",
props: { visible: { type: Boolean, default: false } },
data() {
return {
formItemLayout,
tailItemLayout,
form: this.$form.createForm(this, { name: 'course-add' }),
loading: false,
imageUrl: '',
}
},
methods: {
//
handleChange(info) {
if (info.file.status === 'uploading') {
this.loading = true;
return;
}
if (info.file.status === 'done') {
// Get this url from response in real world.
getBase64(info.file.originFileObj, imageUrl => {
this.imageUrl = imageUrl;
this.loading = false;
});
}
},
beforeUpload(file) {
const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png';
if (!isJpgOrPng) {
this.$message.error('You can only upload JPG file!');
}
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isLt2M) {
this.$message.error('Image must smaller than 2MB!');
}
return isJpgOrPng && isLt2M;
},
//
handleSubmit(e) {
e.preventDefault();
this.form.validateFieldsAndScroll(async (err, values) => {
if (!err) {
try {
console.log('values: ', values);
// const params = this.generateParams(values);
// const res = await createTask(params);
// const { data, msg, code } = res.data;
// //
// this.clearCreateTask();
// this.$emit('closeDialog');
// if (code === 200) {
// this.handleCreateSuccess(params.executorId);
// } else {
// throw msg;
// }
} catch (error) {
this.$message.error(error || '添加研发团队失败');
}
}
});
},
},
};
</script>
<style scoped lang="stylus">
.avatar-uploader > .ant-upload {
width: 128px;
height: 128px;
}
.ant-upload-select-picture-card i {
font-size: 32px;
color: #999;
}
.ant-upload-select-picture-card .ant-upload-text {
margin-top: 8px;
color: #666;
}
</style>

182
src/components/Course/CourseDate.vue

@ -0,0 +1,182 @@
<template>
<div class="main flex-1">
<div style="width:100%" v-if="lists && lists.length > 0">
<a-table
:columns="columns"
:data-source="lists"
:loading="loading"
:row-key="record => record.id"
bordered
class="white"
>
<template slot="id" slot-scope="text, record, index">
<span>{{ index + 1 }}</span>
</template>
<!-- 头像 -->
<template slot="introductionPicture" slot-scope="text, record">
<img :src="record.introductionPicture" class="img" />
<a-modal :imgVisible="imgVisible" @cancel="imgVisible = false" footer title="身份证明">
<img :src="record.idCardPromise" @click="imgVisible = true" style="width: 100%;" />
</a-modal>
</template>
<template slot="auditStatus" slot-scope="text, record">
<a-tag :color="record.auditStatus === '通过' ? 'green' : 'red'">{{ record.auditStatus }}</a-tag>
</template>
<template slot="edit" slot-scope="text, record">
<a-icon @click="showEditModal" class="pointer" theme="twoTone" type="edit" />
<a-popconfirm @confirm="() => onDelete(record.id)" title="确定要删除这一条?" v-if="lists.length">
<a-icon class="ml-4 pointer" theme="twoTone" two-tone-color="#ff0000" type="delete" />
</a-popconfirm>
</template>
<template slot="examine" slot-scope="text, record">
<a-button size="small" type="primary" v-if="record.auditStatus != '通过'">通过</a-button>
<a-button size="small" type="danger" v-else>不通过</a-button>
</template>
<div
class="d-flex flex-nowrap justify-space-between"
slot="expandedRowRender"
slot-scope="record"
style="margin: 0"
>
<div>课程简介{{ record.courseProfile }}</div>
</div>
</a-table>
</div>
<a-empty v-else />
<!-- 编辑 -->
<course-edit :editVisible="editVisible" @closeModal="closeModal" />
</div>
</template>
<script>
import CourseEdit from "components/Course/CourseEdit.vue";
const columns = [
{
title: '序号',
align: 'center',
dataIndex: 'id',
key: 'id',
width: '7%',
scopedSlots: { customRender: 'id' },
},
{
title: '课程名称',
align: 'center',
dataIndex: 'courseName',
key: 'courseName',
},
{
title: '介绍图片',
align: 'center',
dataIndex: 'introductionPicture',
key: 'introductionPicture',
scopedSlots: { customRender: 'introductionPicture' },
},
{
title: '审核状态',
align: 'center',
dataIndex: 'auditStatus',
key: 'auditStatus',
scopedSlots: { customRender: 'auditStatus' },
},
{
title: '编辑',
align: 'center',
dataIndex: 'edit',
key: 'edit',
scopedSlots: { customRender: 'edit' },
},
{
title: '审核',
align: 'center',
dataIndex: 'examine',
key: 'examine',
scopedSlots: { customRender: 'examine' },
},
];
const lists = [
{
id:'001',
courseName:'传控科技',
courseProfile:'传控科技简介',
introductionPicture:'assets/logo.png',
auditStatus: '通过',
},
{
id:'002',
courseName:'中绿环保',
courseProfile:'中绿环保简介',
introductionPicture:'assets/logo.png',
auditStatus: '未通过',
}
];
export default {
name: "CourseDate",
components: {
CourseEdit,
},
data() {
this.cacheData = lists.map(item => ({ ...item }));
return {
columns,
lists,
loading: false,
height: '',
editVisible: false,
imgVisible: false,
}
},
mounted() {
this.height = document.getElementsByClassName('main')[0].offsetHeight - 150;
},
methods: {
showEditModal(){
this.editVisible = true;
},
closeModal(){
this.editVisible = false;
},
//
async onDelete(teamId) {
try {
const params = { param: { teamId } };
// const res = await delTeam(params);
// const { data, msg, code } = res.data;
// if (code === 200) {
// this.$message.success('');
// const arr = [...this.lists];
// this.lists = arr.filter(item => item.id !== teamId);
// // TODO:
// } else {
// throw msg;
// }
} catch (error) {
this.$message.error(error || '删除失败');
}
},
},
};
</script>
<style lang="stylus" scoped>
.main .img {
width: 100%;
}
.main .big_img {
width: 200px;
}
</style>

166
src/components/Course/CourseEdit.vue

@ -0,0 +1,166 @@
<template>
<div class="d-flex flex-wrap pb-3">
<!-- 编辑 -->
<a-modal :closable="false" footer title="修改课程" v-model="editVisible" width="700px">
<a-form :form="form" @submit="handleSubmit">
<!-- 课程名称 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="课程名称"
>
<a-input
placeholder="课程名称"
v-decorator="[
'courseName',
{
rules: [
{ required: true, message: '课程名称不能为空' },
{ whitespace: true, message: '课程名称不能为空' },
{ max: 140, massage: '课程名称最多140个字符' },
],
},
]"
/>
</a-form-item>
<!-- 课程简介 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="课程简介"
>
<a-textarea
placeholder="课程简介"
v-decorator="[
'courseProfile',
]"
/>
</a-form-item>
<!-- 介绍图片 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="介绍图片"
>
<a-upload
:before-upload="beforeUpload"
:show-upload-list="false"
@change="handleChange"
action="https://www.mocky.io/v2/5cc8019d300000980a055e76"
class="avatar-uploader"
list-type="picture-card"
name="avatar"
>
<img :src="imageUrl" alt="avatar" v-if="imageUrl" />
<div v-else>
<a-icon :type="loading ? 'loading' : 'plus'" />
<div class="ant-upload-text">Upload</div>
</div>
</a-upload>
</a-form-item>
<a-form-item class="d-flex flex-row-reverse">
<a-button @click="$emit('closeModal')" class="mr-3">取消</a-button>
<a-button class="white--text" html-type="submit" type="primary">保存</a-button>
</a-form-item>
</a-form>
</a-modal>
</div>
</template>
<script>
const formItemLayout = {
labelCol: { span: 6 },
wrapperCol: { span: 16 },
};
const tailItemLayout = { wrapperCol: { span: 16, offset: 6 } };
function getBase64(img, callback) {
const reader = new FileReader();
reader.addEventListener('load', () => callback(reader.result));
reader.readAsDataURL(img);
}
export default {
name: "CourseEdit",
props: { editVisible: { type: Boolean, default: false } },
data() {
return {
formItemLayout,
tailItemLayout,
form: this.$form.createForm(this, { name: 'course-edit' }),
loading: false,
imageUrl: '',
}
},
methods: {
//
handleChange(info) {
if (info.file.status === 'uploading') {
this.loading = true;
return;
}
if (info.file.status === 'done') {
// Get this url from response in real world.
getBase64(info.file.originFileObj, imageUrl => {
this.imageUrl = imageUrl;
this.loading = false;
});
}
},
beforeUpload(file) {
const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png';
if (!isJpgOrPng) {
this.$message.error('You can only upload JPG file!');
}
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isLt2M) {
this.$message.error('Image must smaller than 2MB!');
}
return isJpgOrPng && isLt2M;
},
//
handleSubmit(e) {
e.preventDefault();
this.form.validateFieldsAndScroll(async (err, values) => {
if (!err) {
try {
console.log('values: ', values);
// const params = this.generateParams(values);
// const res = await createTask(params);
// const { data, msg, code } = res.data;
// //
// this.clearCreateTask();
// this.$emit('closeDialog');
// if (code === 200) {
// this.handleCreateSuccess(params.executorId);
// } else {
// throw msg;
// }
} catch (error) {
this.$message.error(error || '添加研发团队失败');
}
}
});
},
},
};
</script>
<style scoped lang="stylus">
.avatar-uploader > .ant-upload {
width: 128px;
height: 128px;
}
.ant-upload-select-picture-card i {
font-size: 32px;
color: #999;
}
.ant-upload-select-picture-card .ant-upload-text {
margin-top: 8px;
color: #666;
}
</style>

59
src/components/Course/CourseSearch.vue

@ -0,0 +1,59 @@
<template>
<div class="d-flex flex-wrap pb-3">
<!-- 课程名称 -->
<div>
<a-input
@change="handleChangeName"
placeholder="课程名称"
style="width: 150px"
v-model="courseName"
/>
<a-button @click="handleTableChange" class="ml-3" type="primary">搜索</a-button>
</div>
<div class="flex-1"></div>
<a-button @click="showModal" class="editable-add-btn">增加</a-button>
<!-- 添加 -->
<course-add :visible="visible" @closeModal="closeModal" />
</div>
</template>
<script>
import CourseAdd from "components/Course/CourseAdd.vue";
export default {
name: "CourseSearch",
components: {
CourseAdd,
},
data() {
return {
visible: false,
courseName: '',
}
},
methods: {
showModal(){
this.visible = true;
},
closeModal(){
this.visible = false;
},
handleChangeName(value) {
console.log('value: ', value);
this.courseName = value;
},
handleTableChange() {
console.log('搜索');
},
},
};
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="stylus"></style>

166
src/components/Demand/DemandDate.vue

@ -0,0 +1,166 @@
<template>
<div class="main flex-1">
<div style="width:100%" v-if="lists && lists.length > 0">
<a-table
:columns="columns"
:data-source="lists"
:loading="loading"
:row-key="record => record.id"
bordered
class="white"
>
<template slot="id" slot-scope="text, record, index">
<span>{{ index + 1 }}</span>
</template>
<!-- 需求类型 -->
<template slot="demandType" slot-scope="text, record">
<a-tag color="green">{{ record.demandType }}</a-tag>
</template>
<!-- 提交时间 -->
<template slot="submissionTime" slot-scope="text, record">{{ record.submissionTime }}</template>
<!-- 处理状态 -->
<template slot="processingStatus" slot-scope="text, record, index">
<div class="editable-cell d-flex flex-nowrap">
<a-badge status="success" />
<editable-cell-select
:arr="status"
:text="record.processingStatus"
@change="onCellChange(index, 'processingStatus', $event)"
/>
</div>
</template>
<!-- 挑战 -->
<template slot="edit">
<a-button class="ml-3" size="small" type="primary">一键挑战</a-button>
</template>
</a-table>
</div>
<a-empty v-else />
</div>
</template>
<script>
import EditableCellSelect from "components/EditableCellSelect/EditableCellSelect.vue";
const columns = [
{
title: '序号',
align: 'center',
dataIndex: 'id',
key: 'id',
width: '7%',
scopedSlots: { customRender: 'id' },
},
{
title: '企业名称',
align: 'center',
dataIndex: 'name',
key: 'name',
},
{
title: '联系人',
align: 'center',
dataIndex: 'contacts',
key: 'contacts',
},
{
title: '联系方式',
align: 'center',
dataIndex: 'phone',
key: 'phone',
},
{
title: '需求类型',
align: 'center',
dataIndex: 'demandType',
key: 'demandType',
scopedSlots: { customRender: 'demandType' },
},
{
title: '需求描述',
align: 'center',
dataIndex: 'requirementDescription',
key: 'requirementDescription',
},
{
title: '提交时间',
align: 'center',
dataIndex: 'submissionTime',
key: 'submissionTime',
scopedSlots: { customRender: 'submissionTime' },
},
{
title: '处理状态',
align: 'center',
dataIndex: 'processingStatus',
key: 'processingStatus',
scopedSlots: { customRender: 'processingStatus' },
},
{
title: '挑战',
align: 'center',
dataIndex: 'edit',
key: 'edit',
scopedSlots: { customRender: 'edit' },
},
];
export default {
name: "DemandDate",
components: {
EditableCellSelect,
},
data() {
return {
columns,
loading: false,
height: '',
lists:[
{
id:'001',
name:'传控科技',
contacts: 'zhou',
phone:'15212352621',
demandType:'技术',
requirementDescription:'张三',
submissionTime: '2020-11-17 18:00',
processingStatus:'处理中'
},
{
id:'002',
name:'中绿环保',
contacts: 'lili',
phone:'15254256202',
demandType:'技术',
requirementDescription:'李四',
submissionTime: '2020-11-17 8:00',
processingStatus:'处理中'
}
],
status:[{id:1,name:'待处理'},{id:2,name:'处理中'},{id:3,name:'已处理'}],
editable: false,
}
},
mounted() {
this.height = document.getElementsByClassName('main')[0].offsetHeight - 150;
},
methods: {
onCellChange(key, dataIndex, value) {
console.log('key, dataIndex, value: ', key, dataIndex, value);
const dataSource = [...this.dataSource];
const target = dataSource.find(item => item.key === key);
if (target) {
target[dataIndex] = value;
this.dataSource = dataSource;
}
},
},
};
</script>
<style scoped lang="stylus"></style>

37
src/components/Demand/DemandSearch.vue

@ -0,0 +1,37 @@
<template>
<div class="d-flex flex-wrap pb-3">
<!-- 企业名称 -->
<a-input
@change="handleChangeName"
placeholder="企业名称"
style="width: 150px"
v-model="companyName"
/>
<a-button @click="handleTableChange" class="mx-2" icon="search" type="primary">搜索</a-button>
</div>
</template>
<script>
export default {
name: "DemandSearch",
data() {
return {
companyName: ''
}
},
methods: {
handleChangeName(value) {
console.log('value: ', value);
this.companyName = value;
},
handleTableChange() {
console.log('搜索');
},
},
};
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="stylus"></style>

153
src/components/Development/DevelopmentAdd.vue

@ -0,0 +1,153 @@
<template>
<div class="d-flex flex-wrap pb-3">
<!-- 添加 -->
<a-modal :closable="false" footer title="添加研发团队" v-model="visible" width="700px">
<a-form :form="form" @submit="handleSubmit">
<!-- 名录 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="名录"
>
<a-input
placeholder="名录"
v-decorator="[
'directory',
{
rules: [
{ required: true, message: '名录不能为空' },
{ whitespace: true, message: '名录不能为空' },
{ max: 140, massage: '名录最多140个字符' },
],
},
]"
/>
</a-form-item>
<!-- 介绍图片 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="介绍图片"
>
<a-upload
:before-upload="beforeUpload"
:show-upload-list="false"
@change="handleChange"
action="https://www.mocky.io/v2/5cc8019d300000980a055e76"
class="avatar-uploader"
list-type="picture-card"
name="avatar"
>
<img :src="imageUrl" alt="avatar" v-if="imageUrl" />
<div v-else>
<a-icon :type="loading ? 'loading' : 'plus'" />
<div class="ant-upload-text">Upload</div>
</div>
</a-upload>
</a-form-item>
<a-form-item class="d-flex flex-row-reverse">
<a-button @click="$emit('closeModal')" class="mr-3">取消</a-button>
<a-button class="white--text" html-type="submit" type="primary">保存</a-button>
</a-form-item>
</a-form>
</a-modal>
</div>
</template>
<script>
const formItemLayout = {
labelCol: { span: 6 },
wrapperCol: { span: 16 },
};
const tailItemLayout = { wrapperCol: { span: 16, offset: 6 } };
function getBase64(img, callback) {
const reader = new FileReader();
reader.addEventListener('load', () => callback(reader.result));
reader.readAsDataURL(img);
}
export default {
name: "DevelopmentAdd",
props: { visible: { type: Boolean, default: false } },
data() {
return {
formItemLayout,
tailItemLayout,
form: this.$form.createForm(this, { name: 'development-add' }),
loading: false,
imageUrl: '',
}
},
methods: {
//
handleChange(info) {
if (info.file.status === 'uploading') {
this.loading = true;
return;
}
if (info.file.status === 'done') {
// Get this url from response in real world.
getBase64(info.file.originFileObj, imageUrl => {
this.imageUrl = imageUrl;
this.loading = false;
});
}
},
beforeUpload(file) {
const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png';
if (!isJpgOrPng) {
this.$message.error('You can only upload JPG file!');
}
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isLt2M) {
this.$message.error('Image must smaller than 2MB!');
}
return isJpgOrPng && isLt2M;
},
//
handleSubmit(e) {
e.preventDefault();
this.form.validateFieldsAndScroll(async (err, values) => {
if (!err) {
try {
console.log('values: ', values);
// const params = this.generateParams(values);
// const res = await createTask(params);
// const { data, msg, code } = res.data;
// //
// this.clearCreateTask();
// this.$emit('closeDialog');
// if (code === 200) {
// this.handleCreateSuccess(params.executorId);
// } else {
// throw msg;
// }
} catch (error) {
this.$message.error(error || '添加研发团队失败');
}
}
});
},
},
};
</script>
<style scoped lang="stylus">
.avatar-uploader > .ant-upload {
width: 128px;
height: 128px;
}
.ant-upload-select-picture-card i {
font-size: 32px;
color: #999;
}
.ant-upload-select-picture-card .ant-upload-text {
margin-top: 8px;
color: #666;
}
</style>

146
src/components/Development/DevelopmentDate.vue

@ -0,0 +1,146 @@
<template>
<div class="main flex-1">
<div style="width:100%" v-if="lists && lists.length > 0">
<a-table
:columns="columns"
:data-source="lists"
:loading="loading"
:row-key="record => record.id"
bordered
class="white"
>
<template slot="id" slot-scope="text, record, index">
<span>{{ index + 1 }}</span>
</template>
<!-- 说明图片 -->
<template slot="introductionPicture" slot-scope="text, record">
<img :src="record.introductionPicture" class="img" />
<a-modal :imgVisible="imgVisible" @cancel="imgVisible = false" footer title="身份证明">
<img :src="record.idCardPromise" @click="imgVisible = true" style="width: 100%;" />
</a-modal>
</template>
<template slot="edit" slot-scope="text, record">
<a-icon @click="showEditModal" class="pointer" theme="twoTone" type="edit" />
<a-popconfirm @confirm="() => onDelete(record.id)" title="确定要删除这一条?" v-if="lists.length">
<a-icon class="ml-4 pointer" theme="twoTone" two-tone-color="#ff0000" type="delete" />
</a-popconfirm>
</template>
</a-table>
</div>
<a-empty v-else />
<!-- 编辑 -->
<development-edit :editVisible="editVisible" @closeModal="closeModal" />
</div>
</template>
<script>
import DevelopmentEdit from "components/Development/DevelopmentEdit.vue";
const columns = [
{
title: '序号',
align: 'center',
dataIndex: 'id',
key: 'id',
width: '7%',
scopedSlots: { customRender: 'id' },
},
{
title: '名录',
align: 'center',
dataIndex: 'directory',
key: 'directory',
},
{
title: '介绍图片',
align: 'center',
dataIndex: 'introductionPicture',
key: 'introductionPicture',
scopedSlots: { customRender: 'introductionPicture' },
},
{
title: '编辑',
align: 'center',
dataIndex: 'edit',
key: 'edit',
scopedSlots: { customRender: 'edit' },
},
];
const lists = [
{
id:'001',
directory:'传控科技',
introductionPicture:'assets/logo.png',
},
{
id:'002',
directory:'中绿环保',
introductionPicture:'assets/logo.png',
}
];
export default {
name: "DevelopmentDate",
components: {
DevelopmentEdit,
},
data() {
this.cacheData = lists.map(item => ({ ...item }));
return {
columns,
lists,
loading: false,
height: '',
editVisible: false,
imgVisible: false,
}
},
mounted() {
this.height = document.getElementsByClassName('main')[0].offsetHeight - 150;
},
methods: {
showEditModal(){
this.editVisible = true;
},
closeModal(){
this.editVisible = false;
},
//
async onDelete(teamId) {
try {
const params = { param: { teamId } };
// const res = await delTeam(params);
// const { data, msg, code } = res.data;
// if (code === 200) {
// this.$message.success('');
// const arr = [...this.lists];
// this.lists = arr.filter(item => item.id !== teamId);
// // TODO:
// } else {
// throw msg;
// }
} catch (error) {
this.$message.error(error || '删除失败');
}
},
},
};
</script>
<style lang="stylus" scoped>
.main .img {
width: 100%;
}
.main .big_img {
width: 200px;
}
</style>

153
src/components/Development/DevelopmentEdit.vue

@ -0,0 +1,153 @@
<template>
<div class="d-flex flex-wrap pb-3">
<!-- 编辑 -->
<a-modal :closable="false" footer title="修改研发团队" v-model="editVisible" width="700px">
<a-form :form="form" @submit="handleSubmit">
<!-- 名录 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="名录"
>
<a-input
placeholder="名录"
v-decorator="[
'directory',
{
rules: [
{ required: true, message: '名录不能为空' },
{ whitespace: true, message: '名录不能为空' },
{ max: 140, massage: '名录最多140个字符' },
],
},
]"
/>
</a-form-item>
<!-- 介绍图片 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="介绍图片"
>
<a-upload
:before-upload="beforeUpload"
:show-upload-list="false"
@change="handleChange"
action="https://www.mocky.io/v2/5cc8019d300000980a055e76"
class="avatar-uploader"
list-type="picture-card"
name="avatar"
>
<img :src="imageUrl" alt="avatar" v-if="imageUrl" />
<div v-else>
<a-icon :type="loading ? 'loading' : 'plus'" />
<div class="ant-upload-text">Upload</div>
</div>
</a-upload>
</a-form-item>
<a-form-item class="d-flex flex-row-reverse">
<a-button @click="$emit('closeModal')" class="mr-3">取消</a-button>
<a-button class="white--text" html-type="submit" type="primary">保存</a-button>
</a-form-item>
</a-form>
</a-modal>
</div>
</template>
<script>
const formItemLayout = {
labelCol: { span: 6 },
wrapperCol: { span: 16 },
};
const tailItemLayout = { wrapperCol: { span: 16, offset: 6 } };
function getBase64(img, callback) {
const reader = new FileReader();
reader.addEventListener('load', () => callback(reader.result));
reader.readAsDataURL(img);
}
export default {
name: "DevelopmentEdit",
props: { editVisible: { type: Boolean, default: false } },
data() {
return {
formItemLayout,
tailItemLayout,
form: this.$form.createForm(this, { name: 'development-add' }),
loading: false,
imageUrl: '',
}
},
methods: {
//
handleChange(info) {
if (info.file.status === 'uploading') {
this.loading = true;
return;
}
if (info.file.status === 'done') {
// Get this url from response in real world.
getBase64(info.file.originFileObj, imageUrl => {
this.imageUrl = imageUrl;
this.loading = false;
});
}
},
beforeUpload(file) {
const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png';
if (!isJpgOrPng) {
this.$message.error('You can only upload JPG file!');
}
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isLt2M) {
this.$message.error('Image must smaller than 2MB!');
}
return isJpgOrPng && isLt2M;
},
//
handleSubmit(e) {
e.preventDefault();
this.form.validateFieldsAndScroll(async (err, values) => {
if (!err) {
try {
console.log('values: ', values);
// const params = this.generateParams(values);
// const res = await createTask(params);
// const { data, msg, code } = res.data;
// //
// this.clearCreateTask();
// this.$emit('closeDialog');
// if (code === 200) {
// this.handleCreateSuccess(params.executorId);
// } else {
// throw msg;
// }
} catch (error) {
this.$message.error(error || '添加研发团队失败');
}
}
});
},
},
};
</script>
<style scoped lang="stylus">
.avatar-uploader > .ant-upload {
width: 128px;
height: 128px;
}
.ant-upload-select-picture-card i {
font-size: 32px;
color: #999;
}
.ant-upload-select-picture-card .ant-upload-text {
margin-top: 8px;
color: #666;
}
</style>

59
src/components/Development/DevelopmentSearch.vue

@ -0,0 +1,59 @@
<template>
<div class="d-flex flex-wrap pb-3">
<!-- 中文名称 -->
<div>
<a-input
@change="handleChangeDirectory"
placeholder="名录"
style="width: 150px"
v-model="directory"
/>
<a-button @click="handleTableChange" class="ml-3" type="primary">搜索</a-button>
</div>
<div class="flex-1"></div>
<a-button @click="showModal" class="editable-add-btn">增加</a-button>
<!-- 添加 -->
<development-add :visible="visible" @closeModal="closeModal" />
</div>
</template>
<script>
import DevelopmentAdd from "components/Development/DevelopmentAdd.vue";
export default {
name: "DevelopmentSearch",
components: {
DevelopmentAdd,
},
data() {
return {
visible: false,
directory: '',
}
},
methods: {
showModal(){
this.visible = true;
},
closeModal(){
this.visible = false;
},
handleChangeDirectory(value) {
console.log('value: ', value);
this.directory = value;
},
handleTableChange() {
console.log('搜索');
},
},
};
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="stylus"></style>

46
src/components/EditableCellSelect/EditableCellSelect.vue

@ -0,0 +1,46 @@
<template>
<div class="editable-cell">
<div class="editable-cell-input-wrapper d-flex flex-nowrap justify-center" v-if="editable">
<a-select :default-value="value" @change="handleChange" @pressEnter="check">
<a-select-option :key="item.id" :value="item.name" v-for="item in arr">{{ item.name }}</a-select-option>
</a-select>
<a-icon @click="check" class="editable-cell-icon-check ml-3" type="check" />
</div>
<div class="editable-cell-text-wrapper" v-else>
{{ value || ' ' }}
<a-icon @click="edit" class="editable-cell-icon" type="edit" />
</div>
</div>
</template>
<script>
export default {
props: { text: { type: String, default: '' }, arr: { type: Array, default: () => [] } },
data() {
return {
value: this.text,
editable: false,
};
},
watch: {
text(value) {
if (value) {
this.value = value;
}
},
},
methods: {
handleChange(value) {
console.log('value: ', value);
this.value = value;
},
check() {
this.editable = false;
this.$emit('change', this.value);
},
edit() {
this.editable = true;
},
},
};
</script>

116
src/components/Enterprise/EnterpriseDate.vue

@ -0,0 +1,116 @@
<template>
<div class="main flex-1">
<div style="width:100%" v-if="lists && lists.length > 0">
<a-table
:columns="columns"
:data-source="lists"
:loading="loading"
:row-key="record => record.id"
bordered
class="white"
>
<template slot="id" slot-scope="text, record, index">
<span>{{ index + 1 }}</span>
</template>
<template slot="auditStatus" slot-scope="text, record">
<a-tag
:color="record.auditStatus === 1 ? 'blue' : 'red'"
>{{ record.auditStatus === 1 ? '通过' : '不通过' }}</a-tag>
</template>
<template slot="edit" slot-scope="text, record">
<a-button size="small" type="primary" v-if="record.auditStatus != 1">通过</a-button>
<a-button size="small" type="danger" v-else>不通过</a-button>
</template>
</a-table>
</div>
<a-empty v-else />
</div>
</template>
<script>
const columns = [
{
title: '序号',
align: 'center',
dataIndex: 'id',
key: 'id',
width: '7%',
scopedSlots: { customRender: 'id' },
},
{
title: '企业名称',
align: 'center',
dataIndex: 'name',
key: 'name',
},
{
title: '联系人',
align: 'center',
dataIndex: 'contacts',
key: 'contacts',
},
{
title: '联系方式',
align: 'center',
dataIndex: 'phone',
key: 'phone',
},
{
title: '审核状态',
align: 'center',
dataIndex: 'auditStatus',
key: 'auditStatus',
scopedSlots: { customRender: 'auditStatus' },
},
{
title: '审核人',
align: 'center',
dataIndex: 'reviewer',
key: 'reviewer',
},
{
title: '编辑',
align: 'center',
dataIndex: 'edit',
key: 'edit',
scopedSlots: { customRender: 'edit' },
},
];
export default {
name: "EnterpriseDate",
data() {
return {
columns,
loading: false,
height: '',
lists:[
{
id:'001',
name:'传控科技',
contacts: 'zhou',
phone:'15212352621',
auditStatus:1,
reviewer:'张三'
},
{
id:'002',
name:'中绿环保',
contacts: 'lili',
phone:'15254256202',
auditStatus:0,
reviewer:'李四'
}
]
}
},
mounted() {
this.height = document.getElementsByClassName('main')[0].offsetHeight - 150;
},
};
</script>
<style scoped lang="stylus"></style>

37
src/components/Enterprise/EnterpriseSearch.vue

@ -0,0 +1,37 @@
<template>
<div class="d-flex flex-wrap pb-3">
<!-- 企业名称 -->
<a-input
@change="handleChangeName"
placeholder="企业名称"
style="width: 150px"
v-model="companyName"
/>
<a-button @click="handleTableChange" class="mx-2" icon="search" type="primary">搜索</a-button>
</div>
</template>
<script>
export default {
name: "HelloWorld",
data() {
return {
companyName: ''
}
},
methods: {
handleChangeName(value) {
console.log('value: ', value);
this.companyName = value;
},
handleTableChange() {
console.log('搜索');
},
},
};
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="stylus"></style>

172
src/components/Forum/ForumDate.vue

@ -0,0 +1,172 @@
<template>
<div class="main flex-1">
<div style="width:100%" v-if="lists && lists.length > 0">
<a-table
:columns="columns"
:data-source="lists"
:loading="loading"
:row-key="record => record.id"
bordered
class="white"
>
<template slot="id" slot-scope="text, record, index">
<span>{{ index + 1 }}</span>
</template>
<!-- 置顶 -->
<template slot="topping" slot-scope="text, record">
<a-switch checked-children="" class="ml-4" default-checked un-checked-children="" />
</template>
<!-- 审核状态 -->
<template slot="auditStatus" slot-scope="text, record">
<a-tag :color="record.auditStatus === '通过' ? 'green' : 'red'">{{ record.auditStatus }}</a-tag>
</template>
<template slot="examine" slot-scope="text, record">
<a-button size="small" type="primary" v-if="record.auditStatus != '通过'">通过</a-button>
<a-button size="small" type="danger" v-else>不通过</a-button>
</template>
</a-table>
</div>
<a-empty v-else />
</div>
</template>
<script>
const columns = [
{
title: '序号',
align: 'center',
dataIndex: 'id',
key: 'id',
width: '7%',
scopedSlots: { customRender: 'id' },
},
{
title: '标题',
align: 'center',
dataIndex: 'title',
key: 'title',
},
{
title: '发帖人',
align: 'center',
dataIndex: 'postedBy',
key: 'postedBy',
},
{
title: '板块',
align: 'center',
dataIndex: 'plate',
key: 'plate',
},
{
title: '置顶',
align: 'center',
dataIndex: 'topping',
key: 'topping',
scopedSlots: { customRender: 'topping' },
},
{
title: '审核状态',
align: 'center',
dataIndex: 'auditStatus',
key: 'auditStatus',
scopedSlots: { customRender: 'auditStatus' },
},
{
title: '发布时间',
align: 'center',
dataIndex: 'releaseTime',
key: 'releaseTime',
scopedSlots: { customRender: 'releaseTime' },
},
{
title: '审核',
align: 'center',
dataIndex: 'examine',
key: 'examine',
scopedSlots: { customRender: 'examine' },
},
];
const lists = [
{
id:'001',
title:'传控科技',
postedBy: '张三',
plate:'一',
topping: 5,
auditStatus: '通过',
releaseTime: '2020/11/18 18:00',
},
{
id:'002',
title:'中绿环保',
postedBy: '张三',
plate:'二',
topping: 6,
auditStatus: '未通过',
releaseTime: '2020/11/18 18:00',
}
];
export default {
name: "ForumDate",
data() {
this.cacheData = lists.map(item => ({ ...item }));
return {
columns,
lists,
loading: false,
height: '',
editVisible: false,
imgVisible: false,
}
},
mounted() {
this.height = document.getElementsByClassName('main')[0].offsetHeight - 150;
},
methods: {
showEditModal(){
this.editVisible = true;
},
closeModal(){
this.editVisible = false;
},
//
async onDelete(teamId) {
try {
const params = { param: { teamId } };
// const res = await delTeam(params);
// const { data, msg, code } = res.data;
// if (code === 200) {
// this.$message.success('');
// const arr = [...this.lists];
// this.lists = arr.filter(item => item.id !== teamId);
// // TODO:
// } else {
// throw msg;
// }
} catch (error) {
this.$message.error(error || '删除失败');
}
},
},
};
</script>
<style lang="stylus" scoped>
.main .img {
width: 100%;
}
.main .big_img {
width: 200px;
}
</style>

96
src/components/Forum/ForumSearch.vue

@ -0,0 +1,96 @@
<template>
<div class="d-flex flex-wrap pb-3">
<div>
<!-- 板块 -->
<a-input
@change="handleChange('plate',$event)"
placeholder="板块"
style="width: 150px"
v-model="plate"
/>
<!-- 标题 -->
<a-input
@change="handleChange('title',$event)"
class="ml-3"
placeholder="标题"
style="width: 150px"
v-model="title"
/>
<!-- 置顶 -->
<a-select
@change="handleChangeSelect('topping',$event)"
class="ml-3"
default-value="置顶"
style="width: 150px"
>
<a-select-option
:key="index"
:value="topping"
v-for="(topping, index) in items"
>{{ topping }}</a-select-option>
</a-select>
<!-- 审核 -->
<a-select
@change="handleChangeSelect('state',$event)"
class="ml-3"
default-value="审核通过"
style="width: 150px"
>
<a-select-option
:key="state.id"
:value="state.value"
v-for="state in status"
>{{ state.value }}</a-select-option>
</a-select>
<!-- 发布时间 -->
<a-range-picker @change="onChange" class="ml-3" format="YYYY/MM/DD HH:mm:ss" show-time />
<a-button @click="handleSearch" class="ml-3" type="primary">搜索</a-button>
</div>
</div>
</template>
<script>
export default {
name: "ForumSearch",
data() {
return {
plate: '',
title: '',
items: ['置顶','不置顶'],
topping: '',
status: [
{ id:1, value:'审核通过' },
{ id:2, value:'审核未通过' }
],
state: '',
}
},
methods: {
handleChange(type, e) {
this[type] = e.target.value;
},
handleChangeSelect(type, value) {
this[type] = value;
},
//
onChange(dates, dateStrings) {
console.log('From: ', dates[0], ', to: ', dates[1]);
console.log('From: ', dateStrings[0], ', to: ', dateStrings[1]);
},
//
handleSearch(){
console.log('搜索');
console.log('plate',this.plate);
console.log('title',this.title);
console.log('topping',this.topping);
console.log('state',this.state);
}
},
};
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="stylus"></style>

104
src/components/Manage/ManageAdd.vue

@ -0,0 +1,104 @@
<template>
<div class="d-flex flex-wrap pb-3">
<!-- 添加 -->
<a-modal :closable="false" footer title="添加研发团队" v-model="visible" width="700px">
<a-form :form="form" @submit="handleSubmit">
<!-- 类型 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="类型"
>
<a-input
placeholder="类型"
v-decorator="[
'type',
{
rules: [
{ required: true, message: '类型不能为空' },
{ whitespace: true, message: '类型不能为空' },
{ max: 140, massage: '类型最多140个字符' },
],
},
]"
/>
</a-form-item>
<!-- 上级类型 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="上级类型"
>
<a-input
placeholder="上级类型"
v-decorator="[
'superiorType',
{
rules: [
{ required: true, message: '上级类型不能为空' },
{ whitespace: true, message: '上级类型不能为空' },
{ max: 140, massage: '上级类型最多140个字符' },
],
},
]"
/>
</a-form-item>
<a-form-item class="d-flex flex-row-reverse">
<a-button @click="$emit('closeModal')" class="mr-3">取消</a-button>
<a-button class="white--text" html-type="submit" type="primary">保存</a-button>
</a-form-item>
</a-form>
</a-modal>
</div>
</template>
<script>
const formItemLayout = {
labelCol: { span: 6 },
wrapperCol: { span: 16 },
};
const tailItemLayout = { wrapperCol: { span: 16, offset: 6 } };
export default {
name: "ManageAdd",
props: { visible: { type: Boolean, default: false } },
data() {
return {
formItemLayout,
tailItemLayout,
form: this.$form.createForm(this, { name: 'manage-add' }),
}
},
methods: {
//
handleSubmit(e) {
e.preventDefault();
this.form.validateFieldsAndScroll(async (err, values) => {
if (!err) {
try {
console.log('values: ', values);
// const params = this.generateParams(values);
// const res = await createTask(params);
// const { data, msg, code } = res.data;
// //
// this.clearCreateTask();
// this.$emit('closeDialog');
// if (code === 200) {
// this.handleCreateSuccess(params.executorId);
// } else {
// throw msg;
// }
} catch (error) {
this.$message.error(error || '添加研发团队失败');
}
}
});
},
},
};
</script>
<style scoped lang="stylus"></style>

129
src/components/Manage/ManageDate.vue

@ -0,0 +1,129 @@
<template>
<div class="main flex-1">
<div style="width:100%" v-if="lists && lists.length > 0">
<a-table
:columns="columns"
:data-source="lists"
:loading="loading"
:row-key="record => record.id"
bordered
class="white"
>
<template slot="id" slot-scope="text, record, index">
<span>{{ index + 1 }}</span>
</template>
<template slot="edit" slot-scope="text, record">
<a-icon @click="showEditModal" class="pointer" theme="twoTone" type="edit" />
<a-popconfirm @confirm="() => onDelete(record.id)" title="确定要删除这一条?" v-if="lists.length">
<a-icon class="ml-4 pointer" theme="twoTone" two-tone-color="#ff0000" type="delete" />
</a-popconfirm>
</template>
</a-table>
</div>
<a-empty v-else />
<!-- 编辑 -->
<manage-edit :editVisible="editVisible" @closeModal="closeModal" />
</div>
</template>
<script>
import ManageEdit from "components/Manage/ManageEdit.vue";
const columns = [
{
title: '序号',
align: 'center',
dataIndex: 'id',
key: 'id',
width: '7%',
scopedSlots: { customRender: 'id' },
},
{
title: '类型',
align: 'center',
dataIndex: 'type',
key: 'type',
},
{
title: '上级类型',
align: 'center',
dataIndex: 'superiorType',
key: 'superiorType',
},
{
title: '编辑',
align: 'center',
dataIndex: 'edit',
key: 'edit',
scopedSlots: { customRender: 'edit' },
},
];
const lists = [
{
id:'001',
type:'传控科技',
superiorType: '博士',
},
{
id:'002',
type:'中绿环保',
superiorType: '博士',
}
];
export default {
name: "ManageDate",
components: {
ManageEdit,
},
data() {
this.cacheData = lists.map(item => ({ ...item }));
return {
columns,
lists,
loading: false,
editingKey: '',
height: '',
editVisible: false
}
},
mounted() {
this.height = document.getElementsByClassName('main')[0].offsetHeight - 150;
},
methods: {
showEditModal(){
this.editVisible = true;
},
closeModal(){
this.editVisible = false;
},
//
async onDelete(teamId) {
try {
const params = { param: { teamId } };
// const res = await delTeam(params);
// const { data, msg, code } = res.data;
// if (code === 200) {
// this.$message.success('');
// const arr = [...this.lists];
// this.lists = arr.filter(item => item.id !== teamId);
// // TODO:
// } else {
// throw msg;
// }
} catch (error) {
this.$message.error(error || '删除失败');
}
},
},
};
</script>
<style scoped lang="stylus"></style>

104
src/components/Manage/ManageEdit.vue

@ -0,0 +1,104 @@
<template>
<div class="d-flex flex-wrap pb-3">
<!-- 编辑 -->
<a-modal :closable="false" footer title="修改研发团队" v-model="editVisible" width="700px">
<a-form :form="form" @submit="handleSubmit">
<!-- 类型 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="类型"
>
<a-input
placeholder="类型"
v-decorator="[
'type',
{
rules: [
{ required: true, message: '类型不能为空' },
{ whitespace: true, message: '类型不能为空' },
{ max: 140, massage: '类型最多140个字符' },
],
},
]"
/>
</a-form-item>
<!-- 上级类型 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="上级类型"
>
<a-input
placeholder="上级类型"
v-decorator="[
'superiorType',
{
rules: [
{ required: true, message: '上级类型不能为空' },
{ whitespace: true, message: '上级类型不能为空' },
{ max: 140, massage: '上级类型最多140个字符' },
],
},
]"
/>
</a-form-item>
<a-form-item class="d-flex flex-row-reverse">
<a-button @click="$emit('closeModal')" class="mr-3">取消</a-button>
<a-button class="white--text" html-type="submit" type="primary">保存</a-button>
</a-form-item>
</a-form>
</a-modal>
</div>
</template>
<script>
const formItemLayout = {
labelCol: { span: 6 },
wrapperCol: { span: 16 },
};
const tailItemLayout = { wrapperCol: { span: 16, offset: 6 } };
export default {
name: "ManageEdit",
props: { editVisible: { type: Boolean, default: false } },
data() {
return {
formItemLayout,
tailItemLayout,
form: this.$form.createForm(this, { name: 'manage-add' }),
}
},
methods: {
//
handleSubmit(e) {
e.preventDefault();
this.form.validateFieldsAndScroll(async (err, values) => {
if (!err) {
try {
console.log('values: ', values);
// const params = this.generateParams(values);
// const res = await createTask(params);
// const { data, msg, code } = res.data;
// //
// this.clearCreateTask();
// this.$emit('closeDialog');
// if (code === 200) {
// this.handleCreateSuccess(params.executorId);
// } else {
// throw msg;
// }
} catch (error) {
this.$message.error(error || '添加研发团队失败');
}
}
});
},
},
};
</script>
<style scoped lang="stylus"></style>

59
src/components/Manage/ManageSearch.vue

@ -0,0 +1,59 @@
<template>
<div class="d-flex flex-wrap pb-3">
<!-- 团队名称 -->
<div>
<a-input
@change="handleChangeName"
placeholder="团队名称"
style="width: 150px"
v-model="teamName"
/>
<a-button @click="handleTableChange" class="mx-2" type="primary">搜索</a-button>
</div>
<div class="flex-1"></div>
<a-button @click="showModal" class="editable-add-btn">增加</a-button>
<!-- 添加 -->
<manage-add :visible="visible" @closeModal="closeModal" />
</div>
</template>
<script>
import ManageAdd from "components/Manage/ManageAdd.vue";
export default {
name: "ManageSearch",
components: {
ManageAdd,
},
data() {
return {
visible: false,
teamName: '',
}
},
methods: {
showModal(){
this.visible = true;
},
closeModal(){
this.visible = false;
},
handleChangeName(value) {
console.log('value: ', value);
this.teamName = value;
},
handleTableChange() {
console.log('搜索');
},
},
};
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="stylus"></style>

166
src/components/Mentor/MentorAdd.vue

@ -0,0 +1,166 @@
<template>
<div class="d-flex flex-wrap pb-3">
<!-- 添加 -->
<a-modal :closable="false" footer title="添加创业导师" v-model="visible" width="700px">
<a-form :form="form" @submit="handleSubmit">
<!-- 导师名称 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="导师名称"
>
<a-input
placeholder="导师名称"
v-decorator="[
'tutorName',
{
rules: [
{ required: true, message: '导师名称不能为空' },
{ whitespace: true, message: '导师名称不能为空' },
{ max: 140, massage: '导师名称最多140个字符' },
],
},
]"
/>
</a-form-item>
<!-- 导师简介 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="导师简介"
>
<a-textarea
placeholder="导师简介"
v-decorator="[
'tutorProfile',
]"
/>
</a-form-item>
<!-- 头像 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="头像"
>
<a-upload
:before-upload="beforeUpload"
:show-upload-list="false"
@change="handleChange"
action="https://www.mocky.io/v2/5cc8019d300000980a055e76"
class="avatar-uploader"
list-type="picture-card"
name="avatar"
>
<img :src="imageUrl" alt="avatar" v-if="imageUrl" />
<div v-else>
<a-icon :type="loading ? 'loading' : 'plus'" />
<div class="ant-upload-text">Upload</div>
</div>
</a-upload>
</a-form-item>
<a-form-item class="d-flex flex-row-reverse">
<a-button @click="$emit('closeModal')" class="mr-3">取消</a-button>
<a-button class="white--text" html-type="submit" type="primary">保存</a-button>
</a-form-item>
</a-form>
</a-modal>
</div>
</template>
<script>
const formItemLayout = {
labelCol: { span: 6 },
wrapperCol: { span: 16 },
};
const tailItemLayout = { wrapperCol: { span: 16, offset: 6 } };
function getBase64(img, callback) {
const reader = new FileReader();
reader.addEventListener('load', () => callback(reader.result));
reader.readAsDataURL(img);
}
export default {
name: "MentorAdd",
props: { visible: { type: Boolean, default: false } },
data() {
return {
formItemLayout,
tailItemLayout,
form: this.$form.createForm(this, { name: 'mentor-add' }),
loading: false,
imageUrl: '',
}
},
methods: {
//
handleChange(info) {
if (info.file.status === 'uploading') {
this.loading = true;
return;
}
if (info.file.status === 'done') {
// Get this url from response in real world.
getBase64(info.file.originFileObj, imageUrl => {
this.imageUrl = imageUrl;
this.loading = false;
});
}
},
beforeUpload(file) {
const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png';
if (!isJpgOrPng) {
this.$message.error('You can only upload JPG file!');
}
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isLt2M) {
this.$message.error('Image must smaller than 2MB!');
}
return isJpgOrPng && isLt2M;
},
//
handleSubmit(e) {
e.preventDefault();
this.form.validateFieldsAndScroll(async (err, values) => {
if (!err) {
try {
console.log('values: ', values);
// const params = this.generateParams(values);
// const res = await createTask(params);
// const { data, msg, code } = res.data;
// //
// this.clearCreateTask();
// this.$emit('closeDialog');
// if (code === 200) {
// this.handleCreateSuccess(params.executorId);
// } else {
// throw msg;
// }
} catch (error) {
this.$message.error(error || '添加研发团队失败');
}
}
});
},
},
};
</script>
<style scoped lang="stylus">
.avatar-uploader > .ant-upload {
width: 128px;
height: 128px;
}
.ant-upload-select-picture-card i {
font-size: 32px;
color: #999;
}
.ant-upload-select-picture-card .ant-upload-text {
margin-top: 8px;
color: #666;
}
</style>

182
src/components/Mentor/MentorDate.vue

@ -0,0 +1,182 @@
<template>
<div class="main flex-1">
<div style="width:100%" v-if="lists && lists.length > 0">
<a-table
:columns="columns"
:data-source="lists"
:loading="loading"
:row-key="record => record.id"
bordered
class="white"
>
<template slot="id" slot-scope="text, record, index">
<span>{{ index + 1 }}</span>
</template>
<!-- 头像 -->
<template slot="headPortrait" slot-scope="text, record">
<img :src="record.headPortrait" class="img" />
<a-modal :imgVisible="imgVisible" @cancel="imgVisible = false" footer title="身份证明">
<img :src="record.idCardPromise" @click="imgVisible = true" style="width: 100%;" />
</a-modal>
</template>
<template slot="auditStatus" slot-scope="text, record">
<a-tag :color="record.auditStatus === '通过' ? 'green' : 'red'">{{ record.auditStatus }}</a-tag>
</template>
<template slot="edit" slot-scope="text, record">
<a-icon @click="showEditModal" class="pointer" theme="twoTone" type="edit" />
<a-popconfirm @confirm="() => onDelete(record.id)" title="确定要删除这一条?" v-if="lists.length">
<a-icon class="ml-4 pointer" theme="twoTone" two-tone-color="#ff0000" type="delete" />
</a-popconfirm>
</template>
<template slot="examine" slot-scope="text, record">
<a-button size="small" type="primary" v-if="record.auditStatus != '通过'">通过</a-button>
<a-button size="small" type="danger" v-else>不通过</a-button>
</template>
<div
class="d-flex flex-nowrap justify-space-between"
slot="expandedRowRender"
slot-scope="record"
style="margin: 0"
>
<div>导师简介{{ record.tutorProfile }}</div>
</div>
</a-table>
</div>
<a-empty v-else />
<!-- 编辑 -->
<mentor-edit :editVisible="editVisible" @closeModal="closeModal" />
</div>
</template>
<script>
import MentorEdit from "components/Mentor/MentorEdit.vue";
const columns = [
{
title: '序号',
align: 'center',
dataIndex: 'id',
key: 'id',
width: '7%',
scopedSlots: { customRender: 'id' },
},
{
title: '导师名称',
align: 'center',
dataIndex: 'tutorName',
key: 'tutorName',
},
{
title: '头像',
align: 'center',
dataIndex: 'headPortrait',
key: 'headPortrait',
scopedSlots: { customRender: 'headPortrait' },
},
{
title: '审核状态',
align: 'center',
dataIndex: 'auditStatus',
key: 'auditStatus',
scopedSlots: { customRender: 'auditStatus' },
},
{
title: '编辑',
align: 'center',
dataIndex: 'edit',
key: 'edit',
scopedSlots: { customRender: 'edit' },
},
{
title: '审核',
align: 'center',
dataIndex: 'examine',
key: 'examine',
scopedSlots: { customRender: 'examine' },
},
];
const lists = [
{
id:'001',
tutorName:'传控科技',
tutorProfile:'传控科技简介',
headPortrait:'assets/logo.png',
auditStatus: '通过',
},
{
id:'002',
tutorName:'中绿环保',
tutorProfile:'中绿环保简介',
headPortrait:'assets/logo.png',
auditStatus: '未通过',
}
];
export default {
name: "MentorDate",
components: {
MentorEdit,
},
data() {
this.cacheData = lists.map(item => ({ ...item }));
return {
columns,
lists,
loading: false,
height: '',
editVisible: false,
imgVisible: false,
}
},
mounted() {
this.height = document.getElementsByClassName('main')[0].offsetHeight - 150;
},
methods: {
showEditModal(){
this.editVisible = true;
},
closeModal(){
this.editVisible = false;
},
//
async onDelete(teamId) {
try {
const params = { param: { teamId } };
// const res = await delTeam(params);
// const { data, msg, code } = res.data;
// if (code === 200) {
// this.$message.success('');
// const arr = [...this.lists];
// this.lists = arr.filter(item => item.id !== teamId);
// // TODO:
// } else {
// throw msg;
// }
} catch (error) {
this.$message.error(error || '删除失败');
}
},
},
};
</script>
<style lang="stylus" scoped>
.main .img {
width: 100%;
}
.main .big_img {
width: 200px;
}
</style>

166
src/components/Mentor/MentorEdit.vue

@ -0,0 +1,166 @@
<template>
<div class="d-flex flex-wrap pb-3">
<!-- 编辑 -->
<a-modal :closable="false" footer title="修改创业导师" v-model="editVisible" width="700px">
<a-form :form="form" @submit="handleSubmit">
<!-- 导师名称 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="导师名称"
>
<a-input
placeholder="导师名称"
v-decorator="[
'tutorName',
{
rules: [
{ required: true, message: '导师名称不能为空' },
{ whitespace: true, message: '导师名称不能为空' },
{ max: 140, massage: '导师名称最多140个字符' },
],
},
]"
/>
</a-form-item>
<!-- 导师简介 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="导师简介"
>
<a-textarea
placeholder="导师简介"
v-decorator="[
'tutorProfile',
]"
/>
</a-form-item>
<!-- 头像 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="头像"
>
<a-upload
:before-upload="beforeUpload"
:show-upload-list="false"
@change="handleChange"
action="https://www.mocky.io/v2/5cc8019d300000980a055e76"
class="avatar-uploader"
list-type="picture-card"
name="avatar"
>
<img :src="imageUrl" alt="avatar" v-if="imageUrl" />
<div v-else>
<a-icon :type="loading ? 'loading' : 'plus'" />
<div class="ant-upload-text">Upload</div>
</div>
</a-upload>
</a-form-item>
<a-form-item class="d-flex flex-row-reverse">
<a-button @click="$emit('closeModal')" class="mr-3">取消</a-button>
<a-button class="white--text" html-type="submit" type="primary">保存</a-button>
</a-form-item>
</a-form>
</a-modal>
</div>
</template>
<script>
const formItemLayout = {
labelCol: { span: 6 },
wrapperCol: { span: 16 },
};
const tailItemLayout = { wrapperCol: { span: 16, offset: 6 } };
function getBase64(img, callback) {
const reader = new FileReader();
reader.addEventListener('load', () => callback(reader.result));
reader.readAsDataURL(img);
}
export default {
name: "MentorEdit",
props: { editVisible: { type: Boolean, default: false } },
data() {
return {
formItemLayout,
tailItemLayout,
form: this.$form.createForm(this, { name: 'mentor-edit' }),
loading: false,
imageUrl: '',
}
},
methods: {
//
handleChange(info) {
if (info.file.status === 'uploading') {
this.loading = true;
return;
}
if (info.file.status === 'done') {
// Get this url from response in real world.
getBase64(info.file.originFileObj, imageUrl => {
this.imageUrl = imageUrl;
this.loading = false;
});
}
},
beforeUpload(file) {
const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png';
if (!isJpgOrPng) {
this.$message.error('You can only upload JPG file!');
}
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isLt2M) {
this.$message.error('Image must smaller than 2MB!');
}
return isJpgOrPng && isLt2M;
},
//
handleSubmit(e) {
e.preventDefault();
this.form.validateFieldsAndScroll(async (err, values) => {
if (!err) {
try {
console.log('values: ', values);
// const params = this.generateParams(values);
// const res = await createTask(params);
// const { data, msg, code } = res.data;
// //
// this.clearCreateTask();
// this.$emit('closeDialog');
// if (code === 200) {
// this.handleCreateSuccess(params.executorId);
// } else {
// throw msg;
// }
} catch (error) {
this.$message.error(error || '添加研发团队失败');
}
}
});
},
},
};
</script>
<style scoped lang="stylus">
.avatar-uploader > .ant-upload {
width: 128px;
height: 128px;
}
.ant-upload-select-picture-card i {
font-size: 32px;
color: #999;
}
.ant-upload-select-picture-card .ant-upload-text {
margin-top: 8px;
color: #666;
}
</style>

59
src/components/Mentor/MentorSearch.vue

@ -0,0 +1,59 @@
<template>
<div class="d-flex flex-wrap pb-3">
<!-- 导师名称 -->
<div>
<a-input
@change="handleChangeName"
placeholder="导师名称"
style="width: 150px"
v-model="tutorName"
/>
<a-button @click="handleTableChange" class="ml-3" type="primary">搜索</a-button>
</div>
<div class="flex-1"></div>
<a-button @click="showModal" class="editable-add-btn">增加</a-button>
<!-- 添加 -->
<mentor-add :visible="visible" @closeModal="closeModal" />
</div>
</template>
<script>
import MentorAdd from "components/Mentor/MentorAdd.vue";
export default {
name: "MentorSearch",
components: {
MentorAdd,
},
data() {
return {
visible: false,
tutorName: '',
}
},
methods: {
showModal(){
this.visible = true;
},
closeModal(){
this.visible = false;
},
handleChangeName(value) {
console.log('value: ', value);
this.tutorName = value;
},
handleTableChange() {
console.log('搜索');
},
},
};
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="stylus"></style>

426
src/components/Page/PageAdd.vue

@ -0,0 +1,426 @@
<template>
<div class="d-flex flex-wrap pb-3">
<!-- 添加 -->
<a-modal :closable="false" footer title="添加页面" v-model="visible" width="700px">
<a-form :form="form" @submit="handleSubmit">
<!-- 标题code -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="标题"
>
<a-cascader
:options="titles"
@change="onChange"
placeholder="标题"
v-decorator="['titleCode',{
rules: [
{ required: true, message: '标题不能为空' },
],
}]"
/>
<!-- <a-input
placeholder="标题"
v-decorator="[
'titleCode',
{
rules: [
{ required: true, message: '标题不能为空' },
{ whitespace: true, message: '标题不能为空' },
{ max: 140, massage: '标题最多140个字符' },
],
},
]"
/>-->
</a-form-item>
<!-- 查询模块 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="查询模块"
>
<a-select
placeholder="查询模块"
v-decorator="['queryModule',{
rules: [
{ required: true, message: '查询模块不能为空' },
],
}]"
>
<a-select-option
:key="index"
:value="item.id"
v-for="(item, index) in modules"
>{{ item.text }}</a-select-option>
</a-select>
</a-form-item>
<!-- 展示类型 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="展示类型"
>
<a-select
@select="changeType"
placeholder="展示类型"
v-decorator="['style',{
rules: [
{ required: true, message: '查询模块不能为空' },
],
}]"
>
<a-select-option :key="type.id" :value="type.id" v-for="type in types">{{ type.text }}</a-select-option>
</a-select>
</a-form-item>
<!-- 第几行 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="第几行"
>
<a-input
placeholder="第几行"
v-decorator="[
'sort',
{
rules: [
{ required: true, message: '第几行不能为空' },
{ whitespace: true, message: '第几行不能为空' },
{ max: 140, massage: '第几行最多140个字符' },
],
},
]"
/>
</a-form-item>
<!-- 宽度 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="宽度"
>
<a-input
placeholder="宽度"
v-decorator="[
'width',
{
rules: [
{ required: true, message: '宽度不能为空' },
{ whitespace: true, message: '宽度不能为空' },
{ max: 140, massage: '宽度最多140个字符' },
],
},
]"
/>
</a-form-item>
<!-- 共几列 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="共几列"
>
<a-input
placeholder="共几列"
v-decorator="[
'colTotal',
{
rules: [
{ required: true, message: '共几列不能为空' },
{ whitespace: true, message: '共几列不能为空' },
{ max: 140, massage: '共几列最多140个字符' },
],
},
]"
/>
</a-form-item>
<!-- 第几列 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="第几列"
>
<a-input
placeholder="第几列"
v-decorator="[
'col',
{
rules: [
{ required: true, message: '第几列不能为空' },
{ whitespace: true, message: '第几列不能为空' },
{ max: 140, massage: '第几列最多140个字符' },
],
},
]"
/>
</a-form-item>
<!-- 查询方式 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="查询方式"
>
<a-radio-group
v-decorator="[
'queryMethod',
{
rules: [
{ required: true, message: '查询方式不能为空' },
],
},
]"
>
<a-radio :value="1">配置内容</a-radio>
<a-radio :value="2">指定内容</a-radio>
</a-radio-group>
</a-form-item>
<!-- 内容 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="内容"
>
<a-textarea placeholder="内容" v-if="type != 1" v-model="content" />
<quill-editor :options="editorOption" placeholder="请在此输入文本..." v-else v-model="content"></quill-editor>
</a-form-item>
<a-form-item class="d-flex flex-row-reverse">
<a-button @click="$emit('closeModal')" class="mr-3">取消</a-button>
<a-button class="white--text" html-type="submit" type="primary">保存</a-button>
</a-form-item>
</a-form>
</a-modal>
</div>
</template>
<script>
import { addPage } from 'config/api';
import { quillEditor } from 'vue-quill-editor';
const formItemLayout = {
labelCol: { span: 6 },
wrapperCol: { span: 16 },
};
const tailItemLayout = { wrapperCol: { span: 16, offset: 6 } };
export default {
name: 'PageAdd',
props: { visible: { type: Boolean, default: false } },
components: {
quillEditor, //
},
data() {
return {
formItemLayout,
tailItemLayout,
form: this.$form.createForm(this, { name: 'page-add' }),
titles: [
{
value: '关于我们',
label: '关于我们',
children: [
{
value: '公司介绍',
label: '公司介绍',
},
{
value: '组织机构',
label: '组织机构',
},
{
value: '合作伙伴',
label: '合作伙伴',
},
{
value: '衍生企业',
label: '衍生企业',
},
],
},
{
value: '创新政策',
label: '创新政策',
},
{
value: '创新平台',
label: '创新平台',
children: [
{
value: '协同创新中心',
label: '协同创新中心',
},
{
value: '组织机构',
label: '组织机构',
},
{
value: '创新服务平台',
label: '创新服务平台',
},
{
value: '科技创新服务',
label: '科技创新服务',
},
],
},
{
value: '孵化平台',
label: '孵化平台',
children: [
{
value: '众创空间',
label: '众创空间',
},
{
value: '公共实验室',
label: '公共实验室',
},
{
value: '中试基地',
label: '中试基地',
},
{
value: '创业导师',
label: '创业导师',
},
{
value: '合作伙伴',
label: '合作伙伴',
},
{
value: '创业服务',
label: '创业服务',
},
{
value: '产品展示',
label: '产品展示',
},
],
},
{
value: '产业平台',
label: '产业平台',
children: [
{
value: '产业创新联盟',
label: '产业创新联盟',
},
{
value: '产业服务',
label: '产业服务',
},
{
value: '衍生企业',
label: '衍生企业',
},
],
},
{
value: '知识平台',
label: '知识平台',
},
{
value: '活动公告',
label: '活动公告',
},
{
value: '创新挑战',
label: '创新挑战',
children: [
{
value: '需求征集',
label: '需求征集',
},
{
value: '项目发布',
label: '项目发布',
},
{
value: '结果公告',
label: '结果公告',
},
],
},
{
value: '交流社区',
label: '交流社区',
},
{
value: '联系我们',
label: '联系我们',
},
],
modules: [
{ id: 0, text: '介绍' },
{ id: 1, text: '政策' },
{ id: 2, text: '新闻列表' },
{ id: 3, text: '交流社区' },
],
types: [
{ id: 0, text: '一级标题' },
{ id: 1, text: '富文本' },
{ id: 2, text: '按钮' },
{ id: 3, text: '动态图文简介' },
{ id: 4, text: '静态图文简介' },
{ id: 5, text: '大按钮' },
{ id: 6, text: '联系我们' },
],
type: '',
editorOption: {
placeholder: '请在此输入文本...',
modules: {
toolbar: [
['bold', 'italic', 'underline', 'strike'], // toggled buttons
[{ header: 1 }, { header: 2 }],
[{ list: 'ordered' }, { list: 'bullet' }],
[{ indent: '-1' }, { indent: '+1' }],
['image'],
],
},
},
content: '',
};
},
methods: {
onChange(value) {
console.log(value);
},
changeType(value) {
this.type = value;
},
//
handleSubmit(e) {
e.preventDefault();
this.form.validateFieldsAndScroll(async (err, values) => {
if (!err) {
try {
if (values.titleCode.length > 1) {
values.titleCode = `${values.titleCode[0]}-${values.titleCode[1]}`;
} else {
values.titleCode = `${values.titleCode[0]}`;
}
const param = values;
param.content = this.content;
const params = { param };
console.log('params: ', params);
const res = await addPage(params);
const { data, msg, code } = res.data;
this.$emit('closeModal');
if (code === 200) {
this.$message.success('添加成功');
// TODO:
} else {
throw msg;
}
} catch (error) {
this.$message.error(error || '添加失败');
}
}
});
},
},
};
</script>
<style scoped lang="stylus"></style>

199
src/components/Page/PageDate.vue

@ -0,0 +1,199 @@
<template>
<div class="main flex-1">
<div style="width:100%" v-if="lists && lists.length > 0">
<a-table
:columns="columns"
:data-source="lists"
:loading="loading"
:row-key="record => record.id"
:scroll="{ y: height }"
bordered
class="white"
>
<template slot="id" slot-scope="text, record, index">
<span>{{ index + 1 }}</span>
</template>
<!-- 模块 -->
<template slot="queryModule" slot-scope="text, record">
<span>{{ record.queryModule === 0 ? '专家' : record.queryModule === 1 ? '政策' : '其他' }}</span>
</template>
<!-- 展示类型 -->
<template slot="style" slot-scope="text, record">
<span>
{{ record.style === 0 ? '一级标题' :
record.style === 1 ? '二级标题' :
record.style === 2 ? '正文' :
record.style === 3 ? '列表' :
record.style === 4 ? '图片' :
record.style === 5 ? '图片滚动' :
record.style === 6 ? '多列排列' :
'富文本' }}
</span>
</template>
<!-- 查询方式 -->
<template slot="queryMethod" slot-scope="text, record">
<span>{{ record.queryMethod === 0 ? '配置内容' : '接口查询' }}</span>
</template>
<template slot="edit" slot-scope="text, record">
<a-icon @click="showEditModal(record)" class="pointer" theme="twoTone" type="edit" />
<a-popconfirm @confirm="() => onDelete(record.id)" title="确定要删除这一条?" v-if="lists.length">
<a-icon class="ml-4 pointer" theme="twoTone" two-tone-color="#ff0000" type="delete" />
</a-popconfirm>
</template>
<div
class="d-flex flex-nowrap justify-space-between"
slot="expandedRowRender"
slot-scope="record"
style="margin: 0"
>
<div>内容{{ record.content }}</div>
</div>
</a-table>
</div>
<a-empty v-else />
<!-- 编辑 -->
<page-edit :editItem="editItem" :editVisible="editVisible" @closeModal="closeModal" />
</div>
</template>
<script>
import PageEdit from 'components/Page/PageEdit.vue';
// import { delTeam } from 'config/api';
const columns = [
{
title: '序号',
align: 'center',
dataIndex: 'id',
key: 'id',
scopedSlots: { customRender: 'id' },
},
{
title: '模块',
align: 'center',
dataIndex: 'queryModule',
key: 'queryModule',
},
{
title: '展示类型',
align: 'center',
dataIndex: 'style',
key: 'style',
scopedSlots: { customRender: 'style' },
},
{
title: '第几行',
align: 'center',
dataIndex: 'sort',
key: 'sort',
},
{
title: '宽度',
align: 'center',
dataIndex: 'width',
key: 'width',
},
{
title: '共几列',
align: 'center',
dataIndex: 'colTotal',
key: 'colTotal',
},
{
title: '第几列',
align: 'center',
dataIndex: 'col',
key: 'col',
},
{
title: '查询方式',
align: 'center',
dataIndex: 'queryMethod',
key: 'queryMethod',
scopedSlots: { customRender: 'queryMethod' },
},
{
title: '编辑',
align: 'center',
dataIndex: 'edit',
key: 'edit',
scopedSlots: { customRender: 'edit' },
},
];
export default {
name: 'PageDate',
components: {
PageEdit,
},
props: { lists: { type: Array, default: () => [] } },
data() {
this.cacheData = this.lists.map(item => ({ ...item }));
return {
columns,
loading: false,
editingKey: '',
height: '',
editVisible: false,
editItem: null, //
};
},
mounted() {
let th = 250;
let wh = window.innerHeight;
this.height = wh - th;
window.onresize = () => {
return (() => {
wh = window.innerHeight;
this.height = wh - th;
})();
};
},
methods: {
showEditModal(record) {
console.log('record: ', record);
this.editItem = record;
this.editVisible = true;
},
closeModal() {
this.editVisible = false;
},
//
async onDelete(teamId) {
try {
// const params = { param: { teamId } };
// const res = await delTeam(params);
// const { data, msg, code } = res.data;
// if (code === 200) {
// this.$message.success('');
// const arr = [...this.lists];
// this.lists = arr.filter(item => item.id !== teamId);
// // TODO:
// } else {
// throw msg;
// }
} catch (error) {
this.$message.error(error || '删除失败');
}
},
//
openSignUp() {
const { query } = this.$route;
this.$router.push({ path: '/sign-up', query });
},
},
};
</script>
<style scoped lang="stylus"></style>

211
src/components/Page/PageEdit.vue

@ -0,0 +1,211 @@
<template>
<div class="d-flex flex-wrap pb-3">
<!-- 编辑 -->
<a-modal :closable="false" footer title="修改页面" v-model="editVisible" width="700px">
<a-form :form="form" @submit="handleSubmit">
<!-- 模块 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="模块"
>
<a-input
placeholder="模块"
v-decorator="[
'pagePath',
{
rules: [
{ required: true, message: '模块不能为空' },
{ whitespace: true, message: '模块不能为空' },
{ max: 140, massage: '模块最多140个字符' },
],
},
]"
/>
</a-form-item>
<!-- 展示类型 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="展示类型"
>
<a-select @change="getType" placeholder="展示类型" style="width: 200px">
<a-select-option :key="index" :value="type" v-for="(type, index) in types">{{ type }}</a-select-option>
</a-select>
</a-form-item>
<!-- 第几行 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="第几行"
>
<a-input
placeholder="第几行"
v-decorator="[
'whichLine',
{
rules: [
{ required: true, message: '第几行不能为空' },
{ whitespace: true, message: '第几行不能为空' },
{ max: 140, massage: '第几行最多140个字符' },
],
},
]"
/>
</a-form-item>
<!-- 宽度 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="宽度"
>
<a-input
placeholder="宽度"
v-decorator="[
'whichLine',
{
rules: [
{ required: true, message: '宽度不能为空' },
{ whitespace: true, message: '宽度不能为空' },
{ max: 140, massage: '宽度最多140个字符' },
],
},
]"
/>
</a-form-item>
<!-- 共几列 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="共几列"
>
<a-input
placeholder="共几列"
v-decorator="[
'totalColumns',
{
rules: [
{ required: true, message: '共几列不能为空' },
{ whitespace: true, message: '共几列不能为空' },
{ max: 140, massage: '共几列最多140个字符' },
],
},
]"
/>
</a-form-item>
<!-- 第几列 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="第几列"
>
<a-input
placeholder="第几列"
v-decorator="[
'whichColumns',
{
rules: [
{ required: true, message: '第几列不能为空' },
{ whitespace: true, message: '第几列不能为空' },
{ max: 140, massage: '第几列最多140个字符' },
],
},
]"
/>
</a-form-item>
<!-- 查询方式 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="查询方式"
>
<a-radio-group @change="getQueryMethod" v-model="value">
<a-radio :value="1">配置内容</a-radio>
<a-radio :value="2">指定内容</a-radio>
</a-radio-group>
</a-form-item>
<!-- 内容 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="内容"
>
<a-textarea
placeholder="内容"
v-decorator="[
'content',
]"
/>
</a-form-item>
<a-form-item class="d-flex flex-row-reverse">
<a-button @click="$emit('closeModal')" class="mr-3">取消</a-button>
<a-button class="white--text" html-type="submit" type="primary">保存</a-button>
</a-form-item>
</a-form>
</a-modal>
</div>
</template>
<script>
// import { upTeam } from 'config/api';
const formItemLayout = {
labelCol: { span: 6 },
wrapperCol: { span: 16 },
};
const tailItemLayout = { wrapperCol: { span: 16, offset: 6 } };
export default {
name: "PageEdit",
props: { editVisible: { type: Boolean, default: false },editItem: { type: Object, default: () => {} } },
data() {
return {
formItemLayout,
tailItemLayout,
form: this.$form.createForm(this, { name: 'r-d-add' }),
types: ['单选框','多选框','富文本框'],
type: '',
value: 1
}
},
methods: {
//
getType(value){
this.type = value;
},
//
getQueryMethod(value){
this.queryMethod = value;
},
//
handleSubmit(e) {
e.preventDefault();
this.form.validateFieldsAndScroll(async (err, values) => {
if (!err) {
try {
// const params = { param: values };
// const res = await upTeam(params);
// const { data, msg, code } = res.data;
// this.$emit('closeModal');
// if (code === 200) {
// this.$message.success('')
// // TODO:
// } else {
// throw msg;
// }
} catch (error) {
this.$message.error(error || '修改失败');
}
}
});
},
},
};
</script>
<style scoped lang="stylus"></style>

70
src/components/Page/PageSearch.vue

@ -0,0 +1,70 @@
<template>
<div class="d-flex flex-wrap pb-3">
<div>
<!-- 模块 -->
<a-select @change="handleChangeModular" placeholder="查询模块" style="width:200px">
<a-select-option
:key="index"
:value="item.id"
v-for="(item, index) in modules"
>{{ item.text }}</a-select-option>
</a-select>
<a-button @click="handleTableChange" class="mx-2" type="primary">搜索</a-button>
</div>
<div class="flex-1"></div>
<a-button @click="showModal" class="editable-add-btn">增加</a-button>
<!-- 添加 -->
<page-add :visible="visible" @closeModal="closeModal" />
</div>
</template>
<script>
import PageAdd from 'components/Page/PageAdd.vue';
// import { selLikeTeam } from 'config/api';
export default {
name: 'PageSearch',
components: {
PageAdd,
},
data() {
return {
visible: false,
modular: '',
modules: [
{ id: 0, text: '介绍' },
{ id: 1, text: '政策' },
{ id: 2, text: '交流社区' },
],
};
},
methods: {
showModal() {
this.visible = true;
},
closeModal() {
this.visible = false;
},
//
handleChangeModular(value) {
console.log('value: ', value);
this.modular = value;
this.handleTableChange(value);
},
handleTableChange(modular) {
this.$emit('getPageList', modular);
},
},
};
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="stylus"></style>

197
src/components/Policy/PolicyAdd.vue

@ -0,0 +1,197 @@
<template>
<div class="d-flex flex-wrap pb-3">
<!-- 添加 -->
<a-modal :closable="false" footer title="添加创新政策" v-model="visible" width="700px">
<a-form :form="form" @submit="handleSubmit">
<!-- 标题 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="标题"
>
<a-input
placeholder="标题"
v-decorator="[
'title',
{
rules: [
{ required: true, message: '标题不能为空' },
{ whitespace: true, message: '标题不能为空' },
{ max: 140, massage: '标题最多140个字符' },
],
},
]"
/>
</a-form-item>
<!-- 发布部门 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="发布部门"
>
<a-input
placeholder="发布部门"
v-decorator="[
'department',
{
rules: [
{ required: true, message: '发布部门不能为空' },
{ whitespace: true, message: '发布部门不能为空' },
{ max: 140, massage: '发布部门最多140个字符' },
],
},
]"
/>
</a-form-item>
<!-- 发布时间 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="发布时间"
>
<a-date-picker
@change="onChange"
format="YYYY/MM/DD HH:mm:ss"
show-time
style="width:100%"
/>
</a-form-item>
<!-- 截止时间 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="截止时间"
>
<a-date-picker
@change="onChange"
format="YYYY/MM/DD HH:mm:ss"
show-time
style="width:100%"
/>
</a-form-item>
<!-- 政策类型 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="政策类型"
>
<a-select @change="getType" placeholder="政策类型" style="width: 200px">
<a-select-option
:key="index"
:value="policyType"
v-for="(policyType, index) in types"
>{{ policyType }}</a-select-option>
</a-select>
</a-form-item>
<!-- 标签 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="标签"
>
<a-input
placeholder="标签"
v-decorator="[
'tag',
{
rules: [
{ required: true, message: '标签不能为空' },
{ whitespace: true, message: '标签不能为空' },
{ max: 6, massage: '标签最多6个字符' },
],
},
]"
/>
</a-form-item>
<!-- 原文链接 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="原文链接"
>
<a-input
placeholder="原文链接"
v-decorator="[
'link',
{
rules: [
{ required: true, message: '原文链接不能为空' },
{ whitespace: true, message: '原文链接不能为空' },
{ max: 140, massage: '原文链接最多140个字符' },
],
},
]"
/>
</a-form-item>
<a-form-item class="d-flex flex-row-reverse">
<a-button @click="$emit('closeModal')" class="mr-3">取消</a-button>
<a-button class="white--text" html-type="submit" type="primary">保存</a-button>
</a-form-item>
</a-form>
</a-modal>
</div>
</template>
<script>
// import { addTeam } from 'config/api'
const formItemLayout = {
labelCol: { span: 6 },
wrapperCol: { span: 16 },
};
const tailItemLayout = { wrapperCol: { span: 16, offset: 6 } };
export default {
name: "PolicyAdd",
props: { visible: { type: Boolean, default: false } },
data() {
return {
formItemLayout,
tailItemLayout,
form: this.$form.createForm(this, { name: 'r-d-add' }),
releaseTime: '',
deadline: '',
types: ['单选框','多选框','富文本框'],
policyType: '',
value: 1
}
},
methods: {
//
getType(value){
this.policyType = value;
},
//
onChange(dates, dateStrings) {
console.log('From: ', dates[0], ', to: ', dates[1]);
console.log('From: ', dateStrings[0], ', to: ', dateStrings[1]);
},
//
handleSubmit(e) {
e.preventDefault();
this.form.validateFieldsAndScroll(async (err, values) => {
if (!err) {
try {
// const params = { param: values };
// const res = await addTeam(params);
// const { data, msg, code } = res.data;
// this.$emit('closeModal');
// if (code === 200) {
// this.$message.success('')
// // TODO:
// } else {
// throw msg;
// }
} catch (error) {
this.$message.error(error || '添加失败');
}
}
});
},
},
};
</script>
<style scoped lang="stylus"></style>

213
src/components/Policy/PolicyDate.vue

@ -0,0 +1,213 @@
<template>
<div class="main flex-1">
<div style="width:100%" v-if="lists && lists.length > 0">
<div class="mb-4">
<a-button :disabled="!hasSelected" :loading="loading" @click="start" type="primary">审核通过</a-button>
<span class="ml-2">
<template v-if="hasSelected">{{ `选中 ${selectedRowKeys.length} ` }}</template>
</span>
</div>
<a-table
:columns="columns"
:data-source="lists"
:loading="loading"
:row-key="record => record.id"
:row-selection="{ selectedRowKeys: selectedRowKeys, onChange: onSelectChange }"
bordered
class="white"
>
<template slot="id" slot-scope="text, record, index">
<span>{{ index + 1 }}</span>
</template>
<template slot="tag" slot-scope="text, record">
<a-tag color="blue">{{ record.tag }}</a-tag>
</template>
<template slot="auditStatus" slot-scope="text, record">
<a-tag :color="record.auditStatus === '通过' ? 'green' : 'red'">{{ record.auditStatus }}</a-tag>
</template>
<template slot="edit" slot-scope="text, record">
<a-icon @click="showEditModal(record)" class="pointer" theme="twoTone" type="edit" />
<a-popconfirm @confirm="() => onDelete(record.id)" title="确定要删除这一条?" v-if="lists.length">
<a-icon class="ml-4 pointer" theme="twoTone" two-tone-color="#ff0000" type="delete" />
</a-popconfirm>
</template>
<div slot="expandedRowRender" slot-scope="record" style="margin: 0">
<div class="d-flex flex-nowrap mb-2">
<div>发布时间{{ record.releaseTime }}</div>
<div class="ml-8">截止时间{{ record.deadline }}</div>
</div>
<div>原文链接{{ record.content }}</div>
</div>
</a-table>
</div>
<a-empty v-else />
<!-- 编辑 -->
<policy-edit :editItem="editItem" :editVisible="editVisible" @closeModal="closeModal" />
</div>
</template>
<script>
import PolicyEdit from "components/Policy/PolicyEdit.vue";
// import { delTeam } from 'config/api';
const columns = [
{
title: '序号',
align: 'center',
dataIndex: 'id',
key: 'id',
scopedSlots: { customRender: 'id' },
},
{
title: '标题',
align: 'center',
dataIndex: 'title',
key: 'title',
},
{
title: '发布部门',
align: 'center',
dataIndex: 'department',
key: 'department',
},
{
title: '政策类型',
align: 'center',
dataIndex: 'policyType',
key: 'policyType',
},
{
title: '标签',
align: 'center',
dataIndex: 'tag',
key: 'tag',
scopedSlots: { customRender: 'tag' },
},
{
title: '审核状态',
align: 'center',
dataIndex: 'auditStatus',
key: 'auditStatus',
scopedSlots: { customRender: 'auditStatus' },
},
{
title: '编辑',
align: 'center',
dataIndex: 'edit',
key: 'edit',
scopedSlots: { customRender: 'edit' },
},
];
const lists = [
{
id:'001',
title:'标题一',
department:'部门一',
releaseTime: '2020/11/18 08:00',
deadline: '2020/11/18 18:00',
policyType: '新闻',
tag: '新闻',
auditStatus: '通过',
link: 'http://localhost:8080/',
},
{
id:'002',
title:'标题二',
department:'部门二',
releaseTime: '2020/11/18 08:00',
deadline: '2020/11/18 18:00',
policyType: '政治',
tag: '政治',
auditStatus: '未通过',
link: 'http://localhost:8080/'
}
];
export default {
name: "PolicyDate",
components: {
PolicyEdit,
},
data() {
this.cacheData = lists.map(item => ({ ...item }));
return {
columns,
lists,
loading: false,
selectedRowKeys: [],
editingKey: '',
height: '',
editVisible: false,
editItem: null, //
}
},
computed: {
hasSelected() {
return this.selectedRowKeys.length > 0;
},
},
mounted() {
this.height = document.getElementsByClassName('main')[0].offsetHeight - 150;
},
methods: {
start() {
this.loading = true;
// ajax request after empty completing
setTimeout(() => {
this.loading = false;
this.selectedRowKeys = [];
}, 1000);
},
onSelectChange(selectedRowKeys) {
console.log('selectedRowKeys changed: ', selectedRowKeys);
this.selectedRowKeys = selectedRowKeys;
},
showEditModal(record){
console.log('record: ', record);
this.editItem = record;
this.editVisible = true;
},
closeModal(){
this.editVisible = false;
},
//
async onDelete(teamId) {
try {
// const params = { param: { teamId } };
// const res = await delTeam(params);
// const { data, msg, code } = res.data;
// if (code === 200) {
// this.$message.success('');
// const arr = [...this.lists];
// this.lists = arr.filter(item => item.id !== teamId);
// // TODO:
// } else {
// throw msg;
// }
} catch (error) {
this.$message.error(error || '删除失败');
}
},
//
openSignUp(){
const { query } = this.$route;
this.$router.push({ path: '/sign-up', query });
}
},
};
</script>
<style scoped lang="stylus"></style>

200
src/components/Policy/PolicyEdit.vue

@ -0,0 +1,200 @@
<template>
<div class="d-flex flex-wrap pb-3">
<!-- 编辑 -->
<a-modal :closable="false" footer title="修改创新挑战" v-model="editVisible" width="700px">
<a-form :form="form" @submit="handleSubmit">
<!-- 标题 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="标题"
>
<a-input
placeholder="标题"
v-decorator="[
'title',
{
rules: [
{ required: true, message: '标题不能为空' },
{ whitespace: true, message: '标题不能为空' },
{ max: 140, massage: '标题最多140个字符' },
],
},
]"
/>
</a-form-item>
<!-- 发布部门 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="发布部门"
>
<a-input
placeholder="发布部门"
v-decorator="[
'department',
{
rules: [
{ required: true, message: '发布部门不能为空' },
{ whitespace: true, message: '发布部门不能为空' },
{ max: 140, massage: '发布部门最多140个字符' },
],
},
]"
/>
</a-form-item>
<!-- 发布时间 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="发布时间"
>
<a-date-picker
@change="onChange"
format="YYYY/MM/DD HH:mm:ss"
show-time
style="width:100%"
/>
</a-form-item>
<!-- 截止时间 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="截止时间"
>
<a-date-picker
@change="onChange"
format="YYYY/MM/DD HH:mm:ss"
show-time
style="width:100%"
/>
</a-form-item>
<!-- 政策类型 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="政策类型"
>
<a-select @change="getType" placeholder="政策类型" style="width: 200px">
<a-select-option
:key="index"
:value="policyType"
v-for="(policyType, index) in types"
>{{ policyType }}</a-select-option>
</a-select>
</a-form-item>
<!-- 标签 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="标签"
>
<a-input
placeholder="标签"
v-decorator="[
'tag',
{
rules: [
{ required: true, message: '标签不能为空' },
{ whitespace: true, message: '标签不能为空' },
{ max: 6, massage: '标签最多6个字符' },
],
},
]"
/>
</a-form-item>
<!-- 原文链接 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="原文链接"
>
<a-input
placeholder="原文链接"
v-decorator="[
'link',
{
rules: [
{ required: true, message: '原文链接不能为空' },
{ whitespace: true, message: '原文链接不能为空' },
{ max: 140, massage: '原文链接最多140个字符' },
],
},
]"
/>
</a-form-item>
<a-form-item class="d-flex flex-row-reverse">
<a-button @click="$emit('closeModal')" class="mr-3">取消</a-button>
<a-button class="white--text" html-type="submit" type="primary">保存</a-button>
</a-form-item>
</a-form>
</a-modal>
</div>
</template>
<script>
// import { upTeam } from 'config/api';
const formItemLayout = {
labelCol: { span: 6 },
wrapperCol: { span: 16 },
};
const tailItemLayout = { wrapperCol: { span: 16, offset: 6 } };
export default {
name: "PolicyEdit",
props: { editVisible: { type: Boolean, default: false },editItem: { type: Object, default: () => {} } },
data() {
return {
formItemLayout,
tailItemLayout,
form: this.$form.createForm(this, { name: 'r-d-add' }),
releaseTime: '',
deadline: '',
types: ['单选框','多选框','富文本框'],
policyType: '',
value: 1
}
},
methods: {
//
getType(value){
this.policyType = value;
},
//
onChange(dates, dateStrings) {
console.log('From: ', dates[0], ', to: ', dates[1]);
console.log('From: ', dateStrings[0], ', to: ', dateStrings[1]);
},
//
handleSubmit(e) {
e.preventDefault();
this.form.validateFieldsAndScroll(async (err, values) => {
if (!err) {
try {
// const params = { param: values };
// const res = await upTeam(params);
// const { data, msg, code } = res.data;
// this.$emit('closeModal');
// if (code === 200) {
// this.$message.success('')
// // TODO:
// } else {
// throw msg;
// }
} catch (error) {
this.$message.error(error || '修改失败');
}
}
});
},
},
};
</script>
<style scoped lang="stylus"></style>

70
src/components/Policy/PolicySearch.vue

@ -0,0 +1,70 @@
<template>
<div class="d-flex flex-wrap pb-3">
<div>
<!-- 标题 -->
<a-input @change="handleChangeTitle" placeholder="标题" style="width: 150px" v-model="title" />
<a-button @click="handleTableChange" class="mx-2" type="primary">搜索</a-button>
</div>
<div class="flex-1"></div>
<a-button @click="showModal" class="editable-add-btn">增加</a-button>
<!-- 添加 -->
<policy-add :visible="visible" @closeModal="closeModal" />
</div>
</template>
<script>
import PolicyAdd from "components/Policy/PolicyAdd.vue";
// import { selLikeTeam } from 'config/api';
export default {
name: "PolicySearch",
components: {
PolicyAdd,
},
data() {
return {
visible: false,
title: '',
}
},
methods: {
showModal(){
this.visible = true;
},
closeModal(){
this.visible = false;
},
//
handleChangeTitle(value) {
console.log('value: ', value);
this.title = value;
},
async handleTableChange() {
try {
// const params = { param: {publishingPlatform: this.publishingPlatform} };
// const res = await selLikeTeam(params);
// const { data, msg, code } = res.data;
// if (code === 200) {
// console.log('',data);
// // TODO:
// } else {
// throw msg;
// }
} catch (error) {
this.$message.error(error);
}
},
},
};
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="stylus"></style>

155
src/components/RD/RDAdd.vue

@ -0,0 +1,155 @@
<template>
<div class="d-flex flex-wrap pb-3">
<!-- 添加 -->
<a-modal :closable="false" footer title="添加研发团队" v-model="visible" width="700px">
<a-form :form="form" @submit="handleSubmit">
<!-- 团队名称 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="团队名称"
>
<a-input
placeholder="团队名称"
v-decorator="[
'enterpriseName',
{
rules: [
{ required: true, message: '团队名称不能为空' },
{ whitespace: true, message: '团队名称不能为空' },
{ max: 140, massage: '团队名称最多140个字符' },
],
},
]"
/>
</a-form-item>
<!-- 团队带头人 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="团队带头人"
>
<a-input
placeholder="团队带头人"
v-decorator="[
'name',
{
rules: [
{ required: true, message: '团队带头人不能为空' },
{ whitespace: true, message: '团队带头人不能为空' },
{ max: 140, massage: '团队带头人最多140个字符' },
],
},
]"
/>
</a-form-item>
<!-- 依托单位 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="依托单位"
>
<a-input
placeholder="依托单位"
v-decorator="[
'supportUnit',
{
rules: [
{ required: true, message: '依托单位不能为空' },
{ whitespace: true, message: '依托单位不能为空' },
{ max: 140, massage: '依托单位最多140个字符' },
],
},
]"
/>
</a-form-item>
<!-- 研究方向 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="研究方向"
>
<a-input
placeholder="研究方向"
v-decorator="[
'researchDirection',
{
rules: [
{ required: true, message: '研究方向不能为空' },
{ whitespace: true, message: '研究方向不能为空' },
{ max: 140, massage: '研究方向最多140个字符' },
],
},
]"
/>
</a-form-item>
<!-- 团队简介 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="团队简介"
>
<a-textarea
placeholder="团队简介"
v-decorator="[
'shortDesc',
]"
/>
</a-form-item>
<a-form-item class="d-flex flex-row-reverse">
<a-button @click="$emit('closeModal')" class="mr-3">取消</a-button>
<a-button class="white--text" html-type="submit" type="primary">保存</a-button>
</a-form-item>
</a-form>
</a-modal>
</div>
</template>
<script>
import { addTeam } from 'config/api'
const formItemLayout = {
labelCol: { span: 6 },
wrapperCol: { span: 16 },
};
const tailItemLayout = { wrapperCol: { span: 16, offset: 6 } };
export default {
name: "RDAdd",
props: { visible: { type: Boolean, default: false } },
data() {
return {
formItemLayout,
tailItemLayout,
form: this.$form.createForm(this, { name: 'r-d-add' }),
}
},
methods: {
//
handleSubmit(e) {
e.preventDefault();
this.form.validateFieldsAndScroll(async (err, values) => {
if (!err) {
try {
const params = { param: values };
const res = await addTeam(params);
const { data, msg, code } = res.data;
this.$emit('closeModal');
if (code === 200) {
this.$message.success('添加成功')
// TODO:
} else {
throw msg;
}
} catch (error) {
this.$message.error(error || '添加失败');
}
}
});
},
},
};
</script>
<style scoped lang="stylus"></style>

157
src/components/RD/RDDate.vue

@ -0,0 +1,157 @@
<template>
<div class="main flex-1">
<div style="width:100%" v-if="lists && lists.length > 0">
<a-table
:columns="columns"
:data-source="lists"
:loading="loading"
:row-key="record => record.id"
:scroll="{ y: height }"
bordered
class="white"
>
<template slot="id" slot-scope="text, record, index">
<span>{{ index + 1 }}</span>
</template>
<template slot="teamNumber">
<a-button @click="openTeamMember" size="small" type="primary">团队成员</a-button>
</template>
<template slot="edit" slot-scope="text, record">
<a-icon @click="showEditModal(record)" class="pointer" theme="twoTone" type="edit" />
<a-popconfirm @confirm="() => onDelete(record.id)" title="确定要删除这一条?" v-if="lists.length">
<a-icon class="ml-4 pointer" theme="twoTone" two-tone-color="#ff0000" type="delete" />
</a-popconfirm>
</template>
<p
slot="expandedRowRender"
slot-scope="record"
style="margin: 0"
>团队简介{{ record.shortDesc }}</p>
</a-table>
</div>
<a-empty v-else />
<!-- 编辑 -->
<r-d-edit :editItem="editItem" :editVisible="editVisible" @closeModal="closeModal" />
</div>
</template>
<script>
import RDEdit from "components/RD/RDEdit.vue";
import { delTeam } from 'config/api';
const columns = [
{
title: '序号',
align: 'center',
dataIndex: 'id',
key: 'id',
width: '7%',
scopedSlots: { customRender: 'id' },
},
{
title: '团队名称',
align: 'center',
dataIndex: 'enterpriseName',
key: 'enterpriseName',
},
{
title: '团队带头人',
align: 'center',
dataIndex: 'name',
key: 'name',
},
{
title: '依托单位',
align: 'center',
dataIndex: 'supportUnit',
key: 'supportUnit',
},
{
title: '研究方向',
align: 'center',
dataIndex: 'researchDirection',
key: 'researchDirection',
},
{
title: '团队成员',
align: 'center',
dataIndex: 'teamNumber',
key: 'teamNumber',
scopedSlots: { customRender: 'teamNumber' },
},
{
title: '编辑',
align: 'center',
dataIndex: 'edit',
key: 'edit',
scopedSlots: { customRender: 'edit' },
},
];
export default {
name: "EnterpriseDate",
components: {
RDEdit,
},
props: { lists: { type: Array, default: () => [] } },
data() {
this.cacheData = this.lists.map(item => ({ ...item }));
return {
columns,
loading: false,
editingKey: '',
height: '',
fullHeight: '',
editVisible: false,
editItem: null, //
}
},
mounted() {
this.height = document.getElementsByClassName('main')[0].offsetHeight - 100;
},
methods: {
showEditModal(record){
console.log('record: ', record);
this.editItem = record;
this.editVisible = true;
},
closeModal(){
this.editVisible = false;
},
//
async onDelete(teamId) {
try {
const params = { param: { teamId } };
const res = await delTeam(params);
const { data, msg, code } = res.data;
if (code === 200) {
this.$message.success('删除成功');
const arr = [...this.lists];
this.lists = arr.filter(item => item.id !== teamId);
// TODO:
} else {
throw msg;
}
} catch (error) {
this.$message.error(error || '删除失败');
}
},
//
openTeamMember(){
const { query } = this.$route;
this.$router.push({ path: '/RD-team-member', query });
}
},
};
</script>
<style scoped lang="stylus"></style>

163
src/components/RD/RDEdit.vue

@ -0,0 +1,163 @@
<template>
<div class="d-flex flex-wrap pb-3">
<!-- 编辑 -->
<a-modal :closable="false" footer title="修改研发团队" v-model="editVisible" width="700px">
<a-form :form="form" @submit="handleSubmit">
<!-- 团队名称 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="团队名称"
>
<!-- initialValue: editTask.name, -->
<a-input
placeholder="团队名称"
v-decorator="[
'enterpriseName',
{
initialValue: editItem ? editItem.enterpriseName : '',
rules: [
{ required: true, message: '团队名称不能为空' },
{ whitespace: true, message: '团队名称不能为空' },
{ max: 140, massage: '团队名称最多140个字符' },
],
},
]"
/>
</a-form-item>
<!-- 团队带头人 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="团队带头人"
>
<a-input
placeholder="团队带头人"
v-decorator="[
'name',
{
initialValue: editItem ? editItem.name : '',
rules: [
{ required: true, message: '团队带头人不能为空' },
{ whitespace: true, message: '团队带头人不能为空' },
{ max: 140, massage: '团队带头人最多140个字符' },
],
},
]"
/>
</a-form-item>
<!-- 依托单位 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="依托单位"
>
<a-input
placeholder="依托单位"
v-decorator="[
'supportUnit',
{
initialValue: editItem ? editItem.supportUnit : '',
rules: [
{ required: true, message: '依托单位不能为空' },
{ whitespace: true, message: '依托单位不能为空' },
{ max: 140, massage: '依托单位最多140个字符' },
],
},
]"
/>
</a-form-item>
<!-- 研究方向 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="研究方向"
>
<a-input
placeholder="研究方向"
v-decorator="[
'researchDirection',
{
initialValue: editItem ? editItem.researchDirection : '',
rules: [
{ required: true, message: '研究方向不能为空' },
{ whitespace: true, message: '研究方向不能为空' },
{ max: 140, massage: '研究方向最多140个字符' },
],
},
]"
/>
</a-form-item>
<!-- 团队简介 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="团队简介"
>
<a-textarea
placeholder="团队简介"
v-decorator="[
'shortDesc',
{initialValue: editItem ? editItem.shortDesc : '',}
]"
/>
</a-form-item>
<a-form-item class="d-flex flex-row-reverse">
<a-button @click="$emit('closeModal')" class="mr-3">取消</a-button>
<a-button class="white--text" html-type="submit" type="primary">保存</a-button>
</a-form-item>
</a-form>
</a-modal>
</div>
</template>
<script>
import { upTeam } from 'config/api';
const formItemLayout = {
labelCol: { span: 6 },
wrapperCol: { span: 16 },
};
const tailItemLayout = { wrapperCol: { span: 16, offset: 6 } };
export default {
name: "RDEdit",
props: { editVisible: { type: Boolean, default: false },editItem: { type: Object, default: null } },
data() {
return {
formItemLayout,
tailItemLayout,
form: this.$form.createForm(this, { name: 'r-d-add' }),
}
},
methods: {
//
handleSubmit(e) {
e.preventDefault();
this.form.validateFieldsAndScroll(async (err, values) => {
if (!err) {
try {
const params = { param: values };
const res = await upTeam(params);
const { data, msg, code } = res.data;
this.$emit('closeModal');
// if (code === 200) {
// this.$message.success('')
// // TODO:
// } else {
// throw msg;
// }
} catch (error) {
this.$message.error(error || '修改失败');
}
}
});
},
},
};
</script>
<style scoped lang="stylus"></style>

71
src/components/RD/RDSearch.vue

@ -0,0 +1,71 @@
<template>
<div class="d-flex flex-wrap pb-3">
<!-- 团队名称 -->
<div>
<a-input
@change="handleChangeName"
placeholder="团队名称"
style="width: 150px"
v-model="teamName"
/>
<a-button @click="handleTableChange" class="mx-2" type="primary">搜索</a-button>
</div>
<div class="flex-1"></div>
<a-button @click="showModal" class="editable-add-btn">增加</a-button>
<!-- 添加 -->
<r-d-add :visible="visible" @closeModal="closeModal" />
</div>
</template>
<script>
import RDAdd from "components/RD/RDAdd.vue";
import { selLikeTeam } from 'config/api';
export default {
name: "RDSearch",
components: {
RDAdd,
},
data() {
return {
visible: false,
teamName: '',
}
},
methods: {
showModal(){
this.visible = true;
},
closeModal(){
this.visible = false;
},
handleChangeName(e) {
this.teamName = e.target.value;
},
async handleTableChange() {
try {
const params = { param: {teamName: this.teamName} };
const res = await selLikeTeam(params);
const { data, msg, code } = res.data;
if (code === 200) {
console.log('搜索结果',data);
// TODO:
} else {
throw msg;
}
} catch (error) {
this.$message.error(error);
}
},
},
};
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="stylus"></style>

157
src/components/RDMember/RDMemberAdd.vue

@ -0,0 +1,157 @@
<template>
<div class="d-flex flex-wrap pb-3">
<!-- 添加 -->
<a-modal :closable="false" footer title="添加研发团队" v-model="visible" width="700px">
<a-form :form="form" @submit="handleSubmit">
<!-- 团队名称 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="团队名称"
>
<a-input
placeholder="团队名称"
v-decorator="[
'name',
{
rules: [
{ required: true, message: '团队名称不能为空' },
{ whitespace: true, message: '团队名称不能为空' },
{ max: 140, massage: '团队名称最多140个字符' },
],
},
]"
/>
</a-form-item>
<!-- 团队带头人 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="团队带头人"
>
<a-input
placeholder="团队带头人"
v-decorator="[
'contacts',
{
rules: [
{ required: true, message: '团队带头人不能为空' },
{ whitespace: true, message: '团队带头人不能为空' },
{ max: 140, massage: '团队带头人最多140个字符' },
],
},
]"
/>
</a-form-item>
<!-- 依托单位 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="依托单位"
>
<a-input
placeholder="依托单位"
v-decorator="[
'company',
{
rules: [
{ required: true, message: '依托单位不能为空' },
{ whitespace: true, message: '依托单位不能为空' },
{ max: 140, massage: '依托单位最多140个字符' },
],
},
]"
/>
</a-form-item>
<!-- 研究方向 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="研究方向"
>
<a-input
placeholder="研究方向"
v-decorator="[
'researchDirection',
{
rules: [
{ required: true, message: '研究方向不能为空' },
{ whitespace: true, message: '研究方向不能为空' },
{ max: 140, massage: '研究方向最多140个字符' },
],
},
]"
/>
</a-form-item>
<!-- 团队简介 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="团队简介"
>
<a-textarea
placeholder="团队简介"
v-decorator="[
'teamIntroduce',
]"
/>
</a-form-item>
<a-form-item class="d-flex flex-row-reverse">
<a-button @click="$emit('closeModal')" class="mr-3">取消</a-button>
<a-button class="white--text" html-type="submit" type="primary">保存</a-button>
</a-form-item>
</a-form>
</a-modal>
</div>
</template>
<script>
const formItemLayout = {
labelCol: { span: 6 },
wrapperCol: { span: 16 },
};
const tailItemLayout = { wrapperCol: { span: 16, offset: 6 } };
export default {
name: "RDMemberAdd",
props: { visible: { type: Boolean, default: false } },
data() {
return {
formItemLayout,
tailItemLayout,
form: this.$form.createForm(this, { name: 'r-d-member-add' }),
}
},
methods: {
//
handleSubmit(e) {
e.preventDefault();
this.form.validateFieldsAndScroll(async (err, values) => {
if (!err) {
try {
console.log('values: ', values);
// const params = this.generateParams(values);
// const res = await createTask(params);
// const { data, msg, code } = res.data;
// //
// this.clearCreateTask();
// this.$emit('closeDialog');
// if (code === 200) {
// this.handleCreateSuccess(params.executorId);
// } else {
// throw msg;
// }
} catch (error) {
this.$message.error(error || '添加研发团队失败');
}
}
});
},
},
};
</script>
<style scoped lang="stylus"></style>

176
src/components/RDMember/RDMemberDate.vue

@ -0,0 +1,176 @@
<template>
<div class="main flex-1">
<div style="width:100%" v-if="lists && lists.length > 0">
<a-table
:columns="columns"
:data-source="lists"
:loading="loading"
:row-key="record => record.id"
bordered
class="white"
>
<template slot="id" slot-scope="text, record, index">
<span>{{ index + 1 }}</span>
</template>
<template slot="edit" slot-scope="text, record">
<a-icon @click="showEditModal" class="pointer" theme="twoTone" type="edit" />
<a-popconfirm @confirm="() => onDelete(record.id)" title="确定要删除这一条?" v-if="lists.length">
<a-icon class="ml-4 pointer" theme="twoTone" two-tone-color="#ff0000" type="delete" />
</a-popconfirm>
</template>
</a-table>
</div>
<a-empty v-else />
<!-- 编辑 -->
<r-d-member-edit :editVisible="editVisible" @closeModal="closeModal" />
</div>
</template>
<script>
import RDMemberEdit from "components/RDMember/RDMemberEdit.vue";
const columns = [
{
title: '序号',
align: 'center',
dataIndex: 'id',
key: 'id',
width: '7%',
scopedSlots: { customRender: 'id' },
},
{
title: '姓名',
align: 'center',
dataIndex: 'name',
key: 'name',
scopedSlots: { customRender: 'name' },
},
{
title: '性别',
align: 'center',
dataIndex: 'sex',
key: 'sex',
scopedSlots: { customRender: 'sex' },
},
{
title: '所在单位',
align: 'center',
dataIndex: 'supportUnit',
key: 'supportUnit',
scopedSlots: { customRender: 'supportUnit' },
},
{
title: '出生年月',
align: 'center',
dataIndex: 'birth',
key: 'birth',
scopedSlots: { customRender: 'birth' },
},
{
title: '学历/学位',
align: 'center',
dataIndex: 'education',
key: 'education',
scopedSlots: { customRender: 'education' },
},
{
title: '职称/职务',
align: 'center',
dataIndex: 'jobTitle',
key: 'jobTitle',
scopedSlots: { customRender: 'jobTitle' },
},
{
title: '研究方向',
align: 'center',
dataIndex: 'researchDirection',
key: 'researchDirection',
scopedSlots: { customRender: 'researchDirection' },
},
{
title: '编辑',
align: 'center',
dataIndex: 'edit',
key: 'edit',
scopedSlots: { customRender: 'edit' },
},
];
// const lists = [
// {
// id:'001',
// name:'',
// sex: '',
// supportUnit:'',
// birth:'1990-01-01',
// education: '',
// jobTitle: '',
// researchDirection: '',
// },
// {
// id:'002',
// name:'',
// sex: '',
// supportUnit:'绿',
// birth:'1995-01-01',
// education: '',
// jobTitle: '',
// researchDirection: '',
// }
// ];
export default {
name: "RDMemberDate",
components: {
RDMemberEdit,
},
props: { lists: { type: Array, default: () => {} } },
data() {
return {
columns,
loading: false,
editingKey: '',
height: '',
editVisible: false
}
},
mounted() {
console.log('lists',this.lists);
this.height = document.getElementsByClassName('main')[0].offsetHeight - 150;
},
methods: {
showEditModal(){
this.editVisible = true;
},
closeModal(){
this.editVisible = false;
},
//
async onDelete(teamId) {
try {
const params = { param: { teamId } };
// const res = await delTeam(params);
// const { data, msg, code } = res.data;
// if (code === 200) {
// this.$message.success('');
// const arr = [...this.lists];
// this.lists = arr.filter(item => item.id !== teamId);
// // TODO:
// } else {
// throw msg;
// }
} catch (error) {
this.$message.error(error || '删除失败');
}
},
},
};
</script>
<style scoped lang="stylus"></style>

158
src/components/RDMember/RDMemberEdit.vue

@ -0,0 +1,158 @@
<template>
<div class="d-flex flex-wrap pb-3">
<!-- 编辑 -->
<a-modal :closable="false" footer title="修改研发团队" v-model="editVisible" width="700px">
<a-form :form="form" @submit="handleSubmit">
<!-- 团队名称 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="团队名称"
>
<!-- initialValue: editTask.name, -->
<a-input
placeholder="团队名称"
v-decorator="[
'name',
{
rules: [
{ required: true, message: '团队名称不能为空' },
{ whitespace: true, message: '团队名称不能为空' },
{ max: 140, massage: '团队名称最多140个字符' },
],
},
]"
/>
</a-form-item>
<!-- 团队带头人 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="团队带头人"
>
<a-input
placeholder="团队带头人"
v-decorator="[
'contacts',
{
rules: [
{ required: true, message: '团队带头人不能为空' },
{ whitespace: true, message: '团队带头人不能为空' },
{ max: 140, massage: '团队带头人最多140个字符' },
],
},
]"
/>
</a-form-item>
<!-- 依托单位 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="依托单位"
>
<a-input
placeholder="依托单位"
v-decorator="[
'company',
{
rules: [
{ required: true, message: '依托单位不能为空' },
{ whitespace: true, message: '依托单位不能为空' },
{ max: 140, massage: '依托单位最多140个字符' },
],
},
]"
/>
</a-form-item>
<!-- 研究方向 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="研究方向"
>
<a-input
placeholder="研究方向"
v-decorator="[
'researchDirection',
{
rules: [
{ required: true, message: '研究方向不能为空' },
{ whitespace: true, message: '研究方向不能为空' },
{ max: 140, massage: '研究方向最多140个字符' },
],
},
]"
/>
</a-form-item>
<!-- 团队简介 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="团队简介"
>
<a-textarea
placeholder="团队简介"
v-decorator="[
'teamIntroduce',
]"
/>
</a-form-item>
<a-form-item class="d-flex flex-row-reverse">
<a-button @click="$emit('closeModal')" class="mr-3">取消</a-button>
<a-button class="white--text" html-type="submit" type="primary">保存</a-button>
</a-form-item>
</a-form>
</a-modal>
</div>
</template>
<script>
const formItemLayout = {
labelCol: { span: 6 },
wrapperCol: { span: 16 },
};
const tailItemLayout = { wrapperCol: { span: 16, offset: 6 } };
export default {
name: "RDMemberEdit",
props: { editVisible: { type: Boolean, default: false } },
data() {
return {
formItemLayout,
tailItemLayout,
form: this.$form.createForm(this, { name: 'r-d-member-add' }),
}
},
methods: {
//
handleSubmit(e) {
e.preventDefault();
this.form.validateFieldsAndScroll(async (err, values) => {
if (!err) {
try {
console.log('values: ', values);
// const params = this.generateParams(values);
// const res = await createTask(params);
// const { data, msg, code } = res.data;
// //
// this.clearCreateTask();
// this.$emit('closeDialog');
// if (code === 200) {
// this.handleCreateSuccess(params.executorId);
// } else {
// throw msg;
// }
} catch (error) {
this.$message.error(error || '添加研发团队失败');
}
}
});
},
},
};
</script>
<style scoped lang="stylus"></style>

59
src/components/RDMember/RDMemberSearch.vue

@ -0,0 +1,59 @@
<template>
<div class="d-flex flex-wrap pb-3">
<!-- 团队名称 -->
<div>
<a-input
@change="handleChangeName"
placeholder="团队名称"
style="width: 150px"
v-model="teamName"
/>
<a-button @click="handleTableChange" class="mx-2" type="primary">搜索</a-button>
</div>
<div class="flex-1"></div>
<a-button @click="showModal" class="editable-add-btn">增加</a-button>
<!-- 添加 -->
<r-d-member-add :visible="visible" @closeModal="closeModal" />
</div>
</template>
<script>
import RDMemberAdd from "components/RDMember/RDMemberAdd.vue";
export default {
name: "RDMemberSearch",
components: {
RDMemberAdd,
},
data() {
return {
visible: false,
teamName: '',
}
},
methods: {
showModal(){
this.visible = true;
},
closeModal(){
this.visible = false;
},
handleChangeName(value) {
console.log('value: ', value);
this.teamName = value;
},
handleTableChange() {
console.log('搜索');
},
},
};
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="stylus"></style>

229
src/components/Sharing/SharingAdd.vue

@ -0,0 +1,229 @@
<template>
<div class="d-flex flex-wrap pb-3">
<!-- 添加 -->
<a-modal :closable="false" footer title="添加" v-model="visible" width="700px">
<a-form :form="form" @submit="handleSubmit">
<!-- 中文名称 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="中文名称"
>
<a-input
placeholder="中文名称"
v-decorator="[
'chineseName',
{
rules: [
{ required: true, message: '团队名称不能为空' },
{ whitespace: true, message: '团队名称不能为空' },
{ max: 140, massage: '团队名称最多140个字符' },
],
},
]"
/>
</a-form-item>
<!-- 英文名称 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="英文名称"
>
<a-input
placeholder="英文名称"
v-decorator="[
'englishName',
{
rules: [
{ required: true, message: '英文名称不能为空' },
{ whitespace: true, message: '英文名称不能为空' },
{ max: 140, massage: '英文名称最多140个字符' },
],
},
]"
/>
</a-form-item>
<!-- 主要性能指标及功能用途 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="主要性能指标及功能用途"
>
<a-input
placeholder="主要性能指标及功能用途"
v-decorator="[
'performance',
{
rules: [
{ required: true, message: '主要性能指标及功能用途不能为空' },
{ whitespace: true, message: '主要性能指标及功能用途不能为空' },
{ max: 140, massage: '主要性能指标及功能用途最多140个字符' },
],
},
]"
/>
</a-form-item>
<!-- 说明图片 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="说明图片"
>
<a-upload
:before-upload="beforeUpload"
:show-upload-list="false"
@change="handleChange"
action="https://www.mocky.io/v2/5cc8019d300000980a055e76"
class="avatar-uploader"
list-type="picture-card"
name="avatar"
>
<img :src="imageUrl" alt="avatar" v-if="imageUrl" />
<div v-else>
<a-icon :type="loading ? 'loading' : 'plus'" />
<div class="ant-upload-text">Upload</div>
</div>
</a-upload>
</a-form-item>
<!-- 设备所属 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="设备所属"
>
<a-input
placeholder="设备所属"
v-decorator="[
'equipmentOwnership',
]"
/>
</a-form-item>
<!-- 分类 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="分类"
>
<a-select class="ml-3" placeholder="分类" style="width: 200px">
<a-select-option
:key="index"
:value="category.name"
v-for="(category, index) in categories"
>{{ category.name }}</a-select-option>
</a-select>
</a-form-item>
<!-- 备注 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="备注"
>
<a-textarea placeholder="备注" v-decorator="['remark']" />
</a-form-item>
<a-form-item class="d-flex flex-row-reverse">
<a-button @click="$emit('closeModal')" class="mr-3">取消</a-button>
<a-button class="white--text" html-type="submit" type="primary">保存</a-button>
</a-form-item>
</a-form>
</a-modal>
</div>
</template>
<script>
const formItemLayout = {
labelCol: { span: 8 },
wrapperCol: { span: 14 },
};
const tailItemLayout = { wrapperCol: { span: 16, offset: 6 } };
function getBase64(img, callback) {
const reader = new FileReader();
reader.addEventListener('load', () => callback(reader.result));
reader.readAsDataURL(img);
}
export default {
name: "SharingAdd",
props: { visible: { type: Boolean, default: false } },
data() {
return {
formItemLayout,
tailItemLayout,
form: this.$form.createForm(this, { name: 'sharing-add' }),
categories: [{id:1,name:'软件'},{id:2,name:'硬件'}],
loading: false,
imageUrl: ''
}
},
methods: {
//
handleChange(info) {
if (info.file.status === 'uploading') {
this.loading = true;
return;
}
if (info.file.status === 'done') {
// Get this url from response in real world.
getBase64(info.file.originFileObj, imageUrl => {
this.imageUrl = imageUrl;
this.loading = false;
});
}
},
beforeUpload(file) {
const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png';
if (!isJpgOrPng) {
this.$message.error('You can only upload JPG file!');
}
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isLt2M) {
this.$message.error('Image must smaller than 2MB!');
}
return isJpgOrPng && isLt2M;
},
//
handleSubmit(e) {
e.preventDefault();
this.form.validateFieldsAndScroll(async (err, values) => {
if (!err) {
try {
console.log('values: ', values);
// const params = this.generateParams(values);
// const res = await createTask(params);
// const { data, msg, code } = res.data;
// //
// this.clearCreateTask();
// this.$emit('closeDialog');
// if (code === 200) {
// this.handleCreateSuccess(params.executorId);
// } else {
// throw msg;
// }
} catch (error) {
this.$message.error(error || '添加研发团队失败');
}
}
});
},
},
};
</script>
<style scoped lang="stylus">
.avatar-uploader > .ant-upload {
width: 128px;
height: 128px;
}
.ant-upload-select-picture-card i {
font-size: 32px;
color: #999;
}
.ant-upload-select-picture-card .ant-upload-text {
margin-top: 8px;
color: #666;
}
</style>

204
src/components/Sharing/SharingDate.vue

@ -0,0 +1,204 @@
<template>
<div class="main flex-1">
<div style="width:100%" v-if="lists && lists.length > 0">
<a-table
:columns="columns"
:data-source="lists"
:loading="loading"
:row-key="record => record.id"
bordered
class="white"
>
<template slot="id" slot-scope="text, record, index">
<span>{{ index + 1 }}</span>
</template>
<!-- 说明图片 -->
<template slot="researchDirection" slot-scope="text, record">
<img :src="record.researchDirection" class="img" />
<a-modal :imgVisible="imgVisible" @cancel="imgVisible = false" footer title="身份证明">
<img :src="record.idCardPromise" @click="imgVisible = true" style="width: 100%;" />
</a-modal>
</template>
<!-- 分类管理 -->
<template slot="categoryManage" slot-scope="text, record">
<a-button @click="openCategoryManage" size="small" type="primary">仪器分类管理</a-button>
</template>
<template slot="edit" slot-scope="text, record">
<a-icon @click="showEditModal" class="pointer" theme="twoTone" type="edit" />
<a-popconfirm @confirm="() => onDelete(record.id)" title="确定要删除这一条?" v-if="lists.length">
<a-icon class="ml-4 pointer" theme="twoTone" two-tone-color="#ff0000" type="delete" />
</a-popconfirm>
</template>
<div
class="d-flex flex-nowrap justify-space-between"
slot="expandedRowRender"
slot-scope="record"
style="margin: 0"
>
<div>设备所属{{ record.equipmentOwnership }}</div>
<div class="ml-3">分类{{ record.category }}</div>
<div class="ml-3">备注{{ record.remark }}</div>
</div>
</a-table>
</div>
<a-empty v-else />
<!-- 编辑 -->
<sharing-edit :editVisible="editVisible" @closeModal="closeModal" />
</div>
</template>
<script>
import SharingEdit from "components/Sharing/SharingEdit.vue";
const columns = [
{
title: '序号',
align: 'center',
dataIndex: 'id',
key: 'id',
width: '7%',
scopedSlots: { customRender: 'id' },
},
{
title: '中文名称',
align: 'center',
dataIndex: 'chineseName',
key: 'chineseName',
},
{
title: '英文名称',
align: 'center',
dataIndex: 'englishName',
key: 'englishName',
},
{
title: '主要性能指标及功能用途',
align: 'center',
dataIndex: 'performance',
key: 'performance',
},
{
title: '说明图片',
align: 'center',
dataIndex: 'researchDirection',
key: 'researchDirection',
scopedSlots: { customRender: 'researchDirection' },
},
{
title: '分类管理',
align: 'center',
dataIndex: 'categoryManage',
key: 'categoryManage',
scopedSlots: { customRender: 'categoryManage' },
},
{
title: '编辑',
align: 'center',
dataIndex: 'edit',
key: 'edit',
scopedSlots: { customRender: 'edit' },
},
];
const lists = [
{
id:'001',
chineseName:'传控科技',
englishName: 'zhou',
performance:'传控科技',
researchDirection:'assets/logo.png',
equipmentOwnership: '软件',
category:'A',
remark: '无'
},
{
id:'002',
chineseName:'中绿环保',
englishName: 'lili',
performance:'中绿环保',
researchDirection:'assets/logo.png',
equipmentOwnership:'软件',
category:'B',
remark: '无'
}
];
export default {
name: "SharingDate",
components: {
SharingEdit,
},
data() {
this.cacheData = lists.map(item => ({ ...item }));
return {
columns,
lists,
loading: false,
editingKey: '',
height: '',
editVisible: false,
imgVisible: false,
}
},
mounted() {
this.height = document.getElementsByClassName('main')[0].offsetHeight - 150;
},
methods: {
showEditModal(){
this.editVisible = true;
},
closeModal(){
this.editVisible = false;
},
//
openTeamMember(){
const { query } = this.$route;
this.$router.push({ path: '/RD-team-member', query });
},
//
openCategoryManage(){
const { query } = this.$route;
this.$router.push({ path: '/category-manage', query });
},
//
async onDelete(teamId) {
try {
const params = { param: { teamId } };
// const res = await delTeam(params);
// const { data, msg, code } = res.data;
// if (code === 200) {
// this.$message.success('');
// const arr = [...this.lists];
// this.lists = arr.filter(item => item.id !== teamId);
// // TODO:
// } else {
// throw msg;
// }
} catch (error) {
this.$message.error(error || '删除失败');
}
},
},
};
</script>
<style lang="stylus" scoped>
.main .img {
width: 100%;
}
.main .big_img {
width: 200px;
}
</style>

229
src/components/Sharing/SharingEdit.vue

@ -0,0 +1,229 @@
<template>
<div class="d-flex flex-wrap pb-3">
<!-- 编辑 -->
<a-modal :closable="false" footer title="修改研发团队" v-model="editVisible" width="700px">
<a-form :form="form" @submit="handleSubmit">
<!-- 中文名称 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="中文名称"
>
<a-input
placeholder="中文名称"
v-decorator="[
'chineseName',
{
rules: [
{ required: true, message: '团队名称不能为空' },
{ whitespace: true, message: '团队名称不能为空' },
{ max: 140, massage: '团队名称最多140个字符' },
],
},
]"
/>
</a-form-item>
<!-- 英文名称 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="英文名称"
>
<a-input
placeholder="英文名称"
v-decorator="[
'englishName',
{
rules: [
{ required: true, message: '英文名称不能为空' },
{ whitespace: true, message: '英文名称不能为空' },
{ max: 140, massage: '英文名称最多140个字符' },
],
},
]"
/>
</a-form-item>
<!-- 主要性能指标及功能用途 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="主要性能指标及功能用途"
>
<a-input
placeholder="主要性能指标及功能用途"
v-decorator="[
'performance',
{
rules: [
{ required: true, message: '主要性能指标及功能用途不能为空' },
{ whitespace: true, message: '主要性能指标及功能用途不能为空' },
{ max: 140, massage: '主要性能指标及功能用途最多140个字符' },
],
},
]"
/>
</a-form-item>
<!-- 说明图片 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="说明图片"
>
<a-upload
:before-upload="beforeUpload"
:show-upload-list="false"
@change="handleChange"
action="https://www.mocky.io/v2/5cc8019d300000980a055e76"
class="avatar-uploader"
list-type="picture-card"
name="avatar"
>
<img :src="imageUrl" alt="avatar" v-if="imageUrl" />
<div v-else>
<a-icon :type="loading ? 'loading' : 'plus'" />
<div class="ant-upload-text">Upload</div>
</div>
</a-upload>
</a-form-item>
<!-- 设备所属 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="设备所属"
>
<a-input
placeholder="设备所属"
v-decorator="[
'equipmentOwnership',
]"
/>
</a-form-item>
<!-- 分类 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="分类"
>
<a-select class="ml-3" placeholder="分类" style="width: 200px">
<a-select-option
:key="index"
:value="category.name"
v-for="(category, index) in categories"
>{{ category.name }}</a-select-option>
</a-select>
</a-form-item>
<!-- 备注 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="备注"
>
<a-textarea placeholder="备注" v-decorator="['remark']" />
</a-form-item>
<a-form-item class="d-flex flex-row-reverse">
<a-button @click="$emit('closeModal')" class="mr-3">取消</a-button>
<a-button class="white--text" html-type="submit" type="primary">保存</a-button>
</a-form-item>
</a-form>
</a-modal>
</div>
</template>
<script>
const formItemLayout = {
labelCol: { span: 8 },
wrapperCol: { span: 14 },
};
const tailItemLayout = { wrapperCol: { span: 16, offset: 6 } };
function getBase64(img, callback) {
const reader = new FileReader();
reader.addEventListener('load', () => callback(reader.result));
reader.readAsDataURL(img);
}
export default {
name: "SharingEdit",
props: { editVisible: { type: Boolean, default: false } },
data() {
return {
formItemLayout,
tailItemLayout,
form: this.$form.createForm(this, { name: 'sharing-add' }),
categories: [{id:1,name:'软件'},{id:2,name:'硬件'}],
loading: false,
imageUrl: '',
}
},
methods: {
//
handleChange(info) {
if (info.file.status === 'uploading') {
this.loading = true;
return;
}
if (info.file.status === 'done') {
// Get this url from response in real world.
getBase64(info.file.originFileObj, imageUrl => {
this.imageUrl = imageUrl;
this.loading = false;
});
}
},
beforeUpload(file) {
const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png';
if (!isJpgOrPng) {
this.$message.error('You can only upload JPG file!');
}
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isLt2M) {
this.$message.error('Image must smaller than 2MB!');
}
return isJpgOrPng && isLt2M;
},
//
handleSubmit(e) {
e.preventDefault();
this.form.validateFieldsAndScroll(async (err, values) => {
if (!err) {
try {
console.log('values: ', values);
// const params = this.generateParams(values);
// const res = await createTask(params);
// const { data, msg, code } = res.data;
// //
// this.clearCreateTask();
// this.$emit('closeDialog');
// if (code === 200) {
// this.handleCreateSuccess(params.executorId);
// } else {
// throw msg;
// }
} catch (error) {
this.$message.error(error || '添加研发团队失败');
}
}
});
},
},
};
</script>
<style scoped lang="stylus">
.avatar-uploader > .ant-upload {
width: 128px;
height: 128px;
}
.ant-upload-select-picture-card i {
font-size: 32px;
color: #999;
}
.ant-upload-select-picture-card .ant-upload-text {
margin-top: 8px;
color: #666;
}
</style>

87
src/components/Sharing/SharingSearch.vue

@ -0,0 +1,87 @@
<template>
<div class="d-flex flex-wrap pb-3">
<!-- 中文名称 -->
<div>
<a-input
@change="handleChangeChineseName"
placeholder="中文名称"
style="width: 150px"
v-model="chineseName"
/>
<a-input
@change="handleChangeEnglishName"
class="ml-3"
placeholder="英文名称"
style="width: 150px"
v-model="englishName"
/>
<a-select @change="getCategory" class="ml-3" placeholder="分类" style="width: 200px">
<a-select-option
:key="index"
:value="category.name"
v-for="(category, index) in categories"
>{{ category.name }}</a-select-option>
</a-select>
<a-button @click="handleTableChange" class="ml-3" type="primary">搜索</a-button>
</div>
<div class="flex-1"></div>
<a-button @click="showModal" class="editable-add-btn">增加</a-button>
<!-- 添加 -->
<sharing-add :visible="visible" @closeModal="closeModal" />
</div>
</template>
<script>
import SharingAdd from "components/Sharing/SharingAdd.vue";
export default {
name: "SharingSearch",
components: {
SharingAdd,
},
data() {
return {
visible: false,
chineseName: '',
englishName: '',
performance: '',
category: '',
categories: [{id:1,name:'软件'},{id:2,name:'硬件'}]
}
},
methods: {
showModal(){
this.visible = true;
},
closeModal(){
this.visible = false;
},
handleChangeChineseName(value) {
console.log('value: ', value);
this.chineseName = value;
},
handleChangeEnglishName(value) {
console.log('value: ', value);
this.englishName = value;
},
getCategory(value) {
console.log('value: ', value);
this.category = value;
},
handleTableChange() {
console.log('搜索');
},
},
};
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="stylus"></style>

123
src/components/SignUp/SignUpDate.vue

@ -0,0 +1,123 @@
<template>
<div class="main flex-1">
<div style="width:100%" v-if="lists && lists.length > 0">
<a-table
:columns="columns"
:data-source="lists"
:loading="loading"
:row-key="record => record.id"
bordered
class="white"
>
<template slot="id" slot-scope="text, record, index">
<span>{{ index + 1 }}</span>
</template>
</a-table>
</div>
<a-empty v-else />
</div>
</template>
<script>
const columns = [
{
title: '序号',
align: 'center',
dataIndex: 'id',
key: 'id',
width: '7%',
scopedSlots: { customRender: 'id' },
},
{
title: '联系人',
align: 'center',
dataIndex: 'name',
key: 'name',
},
{
title: '联系方式',
align: 'center',
dataIndex: 'phone',
key: 'phone',
},
{
title: '企业名字',
align: 'center',
dataIndex: 'company',
key: 'company',
},
{
title: '其他参赛人员',
align: 'center',
dataIndex: 'others',
key: 'others',
},
];
const lists = [
{
id:'001',
name:'张三',
phone: '15235360226',
company:'传控科技',
others:'工程师,软硬件',
},
{
id:'002',
name:'赵柳',
phone: '15235360226',
company:'中绿环保',
others:'博士,硬件',
}
];
export default {
name: "SignUpDate",
data() {
this.cacheData = lists.map(item => ({ ...item }));
return {
columns,
lists,
loading: false,
editingKey: '',
height: '',
editVisible: false
}
},
mounted() {
this.height = document.getElementsByClassName('main')[0].offsetHeight - 150;
},
methods: {
showEditModal(){
this.editVisible = true;
},
closeModal(){
this.editVisible = false;
},
//
async onDelete(teamId) {
try {
const params = { param: { teamId } };
// const res = await delTeam(params);
// const { data, msg, code } = res.data;
// if (code === 200) {
// this.$message.success('');
// const arr = [...this.lists];
// this.lists = arr.filter(item => item.id !== teamId);
// // TODO:
// } else {
// throw msg;
// }
} catch (error) {
this.$message.error(error || '删除失败');
}
},
},
};
</script>
<style scoped lang="stylus"></style>

38
src/components/SignUp/SignUpSearch.vue

@ -0,0 +1,38 @@
<template>
<div class="d-flex flex-wrap pb-3">
<!-- 联系人 -->
<div>
<a-input @change="handleChangeName" placeholder="联系人" style="width: 150px" v-model="name" />
<a-button @click="handleTableChange" class="mx-2" type="primary">搜索</a-button>
</div>
<div class="flex-1"></div>
<a-button class="editable-add-btn">导出</a-button>
</div>
</template>
<script>
export default {
name: "SignUpSearch",
data() {
return {
name: '',
}
},
methods: {
handleChangeName(value) {
console.log('value: ', value);
this.name = value;
},
handleTableChange() {
console.log('搜索');
},
},
};
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="stylus"></style>

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save