Browse Source

在线评估

liting2017 6 years ago
parent
commit
d6ea1bf649
35 changed files with 3240 additions and 134 deletions
  1. 2 3
      js/component/account/achievement/achievementForm.jsx
  2. 2 2
      js/component/account/business/businessForm.jsx
  3. 2 2
      js/component/account/demand/demandForm.jsx
  4. 126 0
      js/component/account/evaluate/create.jsx
  5. 17 0
      js/component/account/evaluate/create.less
  6. 58 0
      js/component/account/evaluate/createDes.jsx
  7. 189 0
      js/component/account/evaluate/index.jsx
  8. 0 0
      js/component/account/evaluate/index.less
  9. 508 0
      js/component/account/evaluate/info.jsx
  10. 85 0
      js/component/account/evaluate/info.less
  11. 171 0
      js/component/account/evaluate/steps.jsx
  12. 44 0
      js/component/account/evaluate/steps.less
  13. 172 0
      js/component/account/evaluate/steps/dict.js
  14. 298 0
      js/component/account/evaluate/steps/step1.jsx
  15. 151 0
      js/component/account/evaluate/steps/step2.jsx
  16. 199 0
      js/component/account/evaluate/steps/step3.jsx
  17. 206 0
      js/component/account/evaluate/steps/step4.jsx
  18. 344 0
      js/component/account/evaluate/steps/step5.jsx
  19. 96 0
      js/component/account/evaluate/steps/step6.jsx
  20. 140 0
      js/component/account/evaluate/steps/step7.jsx
  21. 358 0
      js/component/account/evaluate/steps/step8.jsx
  22. 2 0
      js/component/account/index/content.jsx
  23. 12 0
      js/component/account/menu.jsx
  24. 3 3
      js/component/account/setAccount/unit.jsx
  25. 1 1
      js/component/administration/banner/bannerForm.jsx
  26. 2 2
      js/component/administration/business/businessCategory.jsx
  27. 0 53
      js/component/administration/business/businessLibrary.jsx
  28. 0 53
      js/component/administration/business/businessProject.jsx
  29. 1 1
      js/component/administration/news/newForm.jsx
  30. 3 4
      js/component/administration/policy/policyForm.jsx
  31. 15 0
      js/component/money.js
  32. 12 0
      js/user/account/assessment.js
  33. 1 1
      package.json
  34. 9 3
      webpack.config.js
  35. 11 6
      webpack/entry.config.js

+ 2 - 3
js/component/account/achievement/achievementForm.jsx

@@ -94,7 +94,6 @@ const KeyWordTagGroup = React.createClass({
     }
 });
 
-
 const PicturesWall = React.createClass({
 	getInitialState() {
 		return {
@@ -249,8 +248,8 @@ const DemandDetailForm = Form.create()(React.createClass({
                         fieldB: values.industryCategory ? values.industryCategory[1] : undefined,
                         dataCategory: values.dataCategory,
                         category: values.category,
-						technicalPictureUrl: thePictureUrl,
-						pictureUrlMin: thepictureUrlMin,
+						technicalPictureUrl: thePictureUrl.length?thePictureUrl:'',
+						pictureUrlMin: thepictureUrlMin.length?thepictureUrlMin:'',
 						introduction:values.introduction,
 						keyword: this.state.tags ? this.state.tags.join(",") : [],
 						keywords: this.state.tags,

+ 2 - 2
js/component/account/business/businessForm.jsx

@@ -109,8 +109,8 @@ const DemandDetailForm = Form.create()(
 				message.warning('请输入项目名称');
 				return;
 			}
-			if ((this.state.name).length>16) {
-				message.warning('项目名称在16个字以内');
+			if ((this.state.name).length>50) {
+				message.warning('项目名称在50个字以内');
 				return false;
 			};
 			if (!this.state.categoryId||!this.state.categoryId[1]) {

+ 2 - 2
js/component/account/demand/demandForm.jsx

@@ -260,8 +260,8 @@ const DemandDetailForm = Form.create()(React.createClass({
                         industryCategoryB: values.industryCategory ? values.industryCategory[1] : undefined,
                         demandType: values.demandType,
                         problemDes: values.problemDes,
-						pictureUrl: thePictureUrl,
-						pictureUrlMin: thepictureUrlMin,
+						pictureUrl: thePictureUrl.length?thePictureUrl:'',
+						pictureUrlMin: thepictureUrlMin.length?thepictureUrlMin:'',
 						crowdCost:values.crowdCost,
 						keyword: this.state.tags ? this.state.tags.join(",") : [],
 						keywords: this.state.tags,

+ 126 - 0
js/component/account/evaluate/create.jsx

@@ -0,0 +1,126 @@
+import React from 'react';
+import { Icon, message, Button, Spin, Checkbox } from 'antd';
+import './create.less';
+import ajax from 'jquery/src/ajax/xhr.js'
+import $ from 'jquery/src/ajax';
+import Steps from './steps';
+
+const CreateEvaluate = React.createClass({
+  getInitialState() {
+    return {
+      title: '',
+      id: '',
+      checked: false,
+      loading: false,
+      announce: ''
+    };
+  },
+  theLoad(){
+    this.setState({
+      loading: true
+    })
+    $.ajax({
+      url: globalConfig.context + '/open/html/get/evaluation_announcement'
+    }).done(function (res) {
+      if (res) {
+        this.setState({
+          loading: true,
+          announce: res
+        })
+      }
+    }.bind(this)).always(function () {
+      this.setState({
+        loading: false
+      })
+    }.bind(this));
+  },
+  
+  returnList() {
+    if (this.props.handlekey) {
+      this.props.handlekey('evaluate');
+    }
+  },
+  announce() {
+    return {
+      __html: this.state.announce
+    }
+  },
+  agree() {
+    $.ajax({
+      url: globalConfig.context + '/api/user/evaluate/create'
+    }).done(function (res) {
+      if (res && res.data) {
+        this.setState({
+          loading: true,
+          id: res.data
+        })
+      }
+    }.bind(this)).always(function () {
+      this.setState({
+        loading: false
+      })
+    }.bind(this));
+  },
+  onChanged(e) {
+    this.setState({
+      checked: e.target.checked
+    });
+  },
+  titleChanged(title) {
+    this.setState({
+      title: title
+    });
+  },
+  componentWillMount() {
+    if (this.props.data.id) {
+      this.state.id = this.props.data.id;
+    } else {
+      this.state.id='';
+      this.state.title='';
+      this.theLoad();
+    }
+  },
+  componentWillReceiveProps(nextProps) {
+    if (!this.props.visible && nextProps.visible) {
+        if (nextProps.data.id) {
+            this.state.id = nextProps.data.id;
+        } else {
+            this.setState({id:'',title:''});
+            this.theLoad();
+        };
+    };
+},
+  renderBody() {
+    if (this.state.id) {
+      return <Steps id={this.state.id} title={this.titleChanged} visible={this.props.visible} />
+    } else {
+      return <div>
+        <div className="announce-head">
+          本系统使用说明
+          <p>使用本系统之前,请您务必仔细阅读并透彻理解本声明。当您使用本系统,将视为您认可本声明内容。</p>
+        </div>
+        <div className="announce-body" dangerouslySetInnerHTML={this.announce()} />
+        <div className="announce-foot">
+          <Checkbox checked={this.state.checked} onChange={this.onChanged}>我同意以上声明</Checkbox>
+          <Button type="primary" onClick={this.agree} disabled={!this.state.checked}>继续</Button>
+        </div>
+      </div>
+    }
+  },
+  render() {
+    return (
+      <Spin spinning={this.state.loading}>
+        <div className="content-container">
+          <div className="content-title">
+            科技评估 {this.state.title ? '- ' + this.state.title : ''}
+          </div>
+          <div className="content-body">
+            {this.renderBody()}
+          </div>
+        </div>
+      </Spin>
+    )
+  },
+});
+
+export default CreateEvaluate;

+ 17 - 0
js/component/account/evaluate/create.less

@@ -0,0 +1,17 @@
+.announce-head {
+  font-size: 14px;
+  font-weight: bold;
+  p {
+    font-weight: lighter;
+  }
+}
+.announce-body {
+  margin: 10px 0 15px;
+  p {
+    margin: 6px 0;
+  }
+}
+.announce-foot { 
+  border-top: 1px solid #80b9ff;
+  padding: 10px 0;
+}

+ 58 - 0
js/component/account/evaluate/createDes.jsx

@@ -0,0 +1,58 @@
+import React from 'react';
+import { Modal, Spin } from 'antd';
+import CreateFrom from '@/account/evaluate/create';
+
+class DemandDesc extends React.Component {
+	constructor(props) {
+		super(props);
+		this.state = {
+			loading: false,
+			showState:false
+		};
+	}
+	handleCancel() {
+		this.setState({
+			visible: false,
+		});
+		this.props.closeDesc(false, true);
+	}
+	handOk() {
+		this.setState({
+			visible: false,
+		});
+		this.props.closeDesc(false, true);
+	}
+	componentWillReceiveProps(nextProps) {
+		this.state.visible = nextProps.showDesc;
+	}
+	render() {
+		let data = this.props.data || {};
+		return (
+			<div className="patent-desc">
+				<Modal
+					maskClosable={false}
+					visible={this.state.visible}
+					onOk={this.handOk.bind(this)}
+					onCancel={this.handleCancel.bind(this)}
+					width="1200px"
+					title={!data.id ? '开始新评估' : '评估结果'}
+					footer=""
+					className="admin-desc-content"
+				>
+					<div>
+						<div>
+							<CreateFrom 
+								closeDesc={this.handleCancel.bind(this)}
+								data={this.props.data}
+								visible={this.state.visible}
+								handOk={this.handOk.bind(this)}
+								/>
+						</div>
+					</div>
+				</Modal>
+			</div>
+		);
+	}
+}
+
+export default DemandDesc;

+ 189 - 0
js/component/account/evaluate/index.jsx

@@ -0,0 +1,189 @@
+import React from 'react';
+import { Icon, message, Button, Spin, Table } from 'antd';
+import Moment from 'moment';
+import './index.less';
+import ajax from 'jquery/src/ajax/xhr.js'
+import $ from 'jquery/src/ajax';
+import money from '@/money.js';
+import CreateDes from './createDes'
+
+const Evaluate = React.createClass({
+  getInitialState() {
+    return {
+      loading: false,
+      dataSource: [],
+      pagination: {
+        defaultCurrent: 1,
+        current: 1,
+        defaultPageSize: 10,
+        showQuickJumper: true,
+        pageSize: 10,
+        onChange: function (page) {
+          this.loadData(page);
+        }.bind(this),
+        showTotal: function (total) {
+          return '共' + (total || 0) + '条数据';
+        }
+      },
+      selectedRowKeys: []
+    };
+  },
+  componentWillMount() {
+    this.loadData(1);
+  },
+  showCreate() {
+    if (this.props.handlekey) {
+      this.props.handlekey('createEvaluate');
+    }
+  },
+  loadData(pageNo) {
+    if (this.state.loading) {
+      return;
+    }
+    this.setState({
+      loading: true
+    });
+    let { pagination } = this.state;
+    $.ajax({
+      url: globalConfig.context + '/api/user/evaluate/list',
+      data: {
+        pageNo: pageNo || 1,
+        pageSize: pagination.pageSize,
+      },
+      success: function (data) {
+        if (!data.data || !data.data.list) {
+          return;
+        }
+        pagination.current = data.data.pageNo;
+        pagination.total = data.data.totalCount;
+        this.setState({
+          dataSource: data.data.list,
+          pagination: pagination
+        });
+      }.bind(this),
+    }).always(function () {
+      this.setState({
+        loading: false
+      });
+    }.bind(this));
+  },
+  addClick() {
+    this.state.RowData = {};
+    this.setState({
+        showDesc: true
+    });
+  },
+  closeDesc(e, s) {
+      this.state.showDesc = e;
+      if (s) {
+          this.loadData(this.state.page);
+      };
+  },
+  tableRowClick(record, index) {
+      this.state.RowData = record;
+      this.setState({
+          showDesc: true
+      });
+  },
+  remove() {
+    if (this.state.loading || !this.state.selectedRowKeys.length) {
+      return;
+    }
+    this.setState({
+      loading: true
+    });
+    $.ajax({
+      url: globalConfig.context + '/api/user/evaluate/remove',
+      data: {
+        ids: this.state.selectedRowKeys.join(',')
+      },
+      method: 'post',
+      success: function (res) {
+        if (res.error && res.error.length) {
+          message.error(res.error[0].message);
+        } else {
+          message.info("删除" + (res.data || 0) + '条记录。',0.1, () => {
+            this.loadData(this.state.pagination.current);
+          })
+        }
+      }.bind(this),
+    }).always(function () {
+      this.setState({
+        loading: false
+      });
+    }.bind(this));
+  },
+  preview(e, it) {
+    e.stopPropagation();
+    e.preventDefault();
+    window.open(globalConfig.context + '/user/account/evaluateInfo?id=' + it.id);
+  },
+  render() {
+    const rowSelection = {
+      onChange: (selectedRowKeys, selectedRows) => {
+        this.setState({
+          selectedRowKeys
+        });
+      },
+      getCheckboxProps: record => ({
+        disabled: record.step === 7
+      })
+    }, columns = [
+      {
+        title: '编号',
+        dataIndex: 'id',
+        key: 'id',
+      }, {
+        title: '技术名称',
+        dataIndex: 'name',
+        key: 'name',
+      }, {
+        title: '价值',
+        dataIndex: 'value',
+        key: 'value',
+        render: (text, it) => { return it.value ? money(it.value) : ''; }
+      }, {
+        title: '预览',
+        dataIndex: 'preview',
+        key: 'preview',
+        render: (text, record) => {
+          return record.value ?
+            <Icon type="eye-o" style={{ fontSize: 18,cursor:"pointer" }} onClick={(e) => {
+              this.preview(e, record)
+            }}></Icon> : <div />
+        }
+      }, {
+        title: '日期',
+        dataIndex: 'createTime',
+        key: 'createTime',
+        render: (text, it) => { return Moment(it.createTime).format('YYYY/MM/DD') }
+      }
+    ];
+    return (
+      <Spin spinning={this.state.loading}>
+        <div className="content-container">
+          <div className="content-title">
+            科技评估管理列表
+              <div className="content-actions"><Button type="primary" onClick={this.addClick}>开始新评估<Icon type="plus" /></Button></div>
+          </div>
+          <div className="content-search">
+            <Button type="danger" onClick={this.remove} disabled={!this.state.selectedRowKeys.length}>删除</Button>
+          </div>
+          <div className="content-body">
+            <Table rowKey="id" columns={columns}
+              dataSource={this.state.dataSource}
+              pagination={this.state.pagination}
+              onRowClick={this.tableRowClick}
+              rowSelection={rowSelection} />
+          </div>
+          <CreateDes
+              data={this.state.RowData}
+              showDesc={this.state.showDesc}
+              closeDesc={this.closeDesc} />
+        </div>
+      </Spin>
+    )
+  },
+});
+
+export default Evaluate;

+ 0 - 0
js/component/account/evaluate/index.less


File diff suppressed because it is too large
+ 508 - 0
js/component/account/evaluate/info.jsx


+ 85 - 0
js/component/account/evaluate/info.less

@@ -0,0 +1,85 @@
+.rotate(@degrees) {
+  -webkit-transform: rotate(@degrees);
+      -ms-transform: rotate(@degrees);
+       -o-transform: rotate(@degrees);
+          transform: rotate(@degrees);
+}
+.report-container {
+  width: 595px;
+  margin: auto;
+  line-height: 1.5;
+  font-size: 14px;
+  color: #333;
+  .export {
+    position: fixed;
+    top: 10%;
+    right: 20%;
+    z-index: 2;
+    &.ant-btn.ant-btn-loading {
+      position: fixed;
+    }
+  }
+}
+
+.report-title {
+  text-align: center;
+  font-size: 20px;
+  font-weight: bold;
+}
+
+.report-subtitle {
+  text-align: center;
+  font-size: 18px;
+  font-weight: bold;
+  margin-bottom: 10px;
+}
+
+.report-page {
+  height: 842px;
+  padding: 5px 50px 25px;
+  position: relative;
+  p {
+    margin: 4px 0;
+  }
+  .ant-table-wrapper {
+    margin-bottom: 12px;
+  }
+  &:before {
+    content: '';
+    position: absolute;
+    top: 40%;
+    left: 34%;
+    width: 200px;
+    height: 100px;
+    opacity: 0.2;
+    .rotate(330deg);
+    background-repeat: no-repeat;
+    background-size: contain;
+    background-image: url('../../../../image/logo-2.png') no-repeat;
+  }
+}
+
+.report-info {
+  margin: 115px 0;
+  .ant-row {
+    margin: 4px 0;
+  }
+}
+.report-announce {
+  position: absolute;
+  bottom: 30px;
+  left: 0;
+  width: 100%;
+  color: #999;
+  text-align: center;
+  font-size: 12px;
+}
+.report-pageno {
+  position: absolute;
+  bottom: 6px;
+  left: 0;
+  width: 100%;
+  color: #999;
+  text-align: center;
+  font-size: 12px;
+}

+ 171 - 0
js/component/account/evaluate/steps.jsx

@@ -0,0 +1,171 @@
+import React from 'react';
+import { Steps, Spin } from 'antd';
+import './steps.less';
+import ajax from 'jquery/src/ajax/xhr.js';
+import $ from 'jquery/src/ajax';
+import Step1 from './steps/step1';
+import Step2 from './steps/step2';
+import Step3 from './steps/step3';
+import Step4 from './steps/step4';
+import Step5 from './steps/step5';
+import Step6 from './steps/step6';
+import Step7 from './steps/step7';
+import Step8 from './steps/step8';
+
+const Step = Steps.Step;
+const steps = [
+	{
+		title: '基本信息',
+		content: Step1
+	},
+	{
+		title: '法律状况评估',
+		content: Step2
+	},
+	{
+		title: '技术状况评估',
+		content: Step3
+	},
+	{
+		title: '历史收入',
+		content: Step4
+	},
+	{
+		title: '收入预估',
+		content: Step5
+	},
+	{
+		title: '所得税预估',
+		content: Step6
+	},
+	{
+		title: '风险预估',
+		content: Step7
+	},
+	{
+		title: '评估值',
+		content: Step8
+	}
+];
+
+const EvaluateSteps = React.createClass({
+	getInitialState() {
+		return {
+			current: 0,
+			loading: true,
+			steps: null,
+			value: 0,
+			step: 0
+		};
+	},
+	next(values) {
+		if (this.state.current == 7) {
+			this.state.value = values;
+			return;
+		} else {
+			this.state.value = 0;
+		}
+		const current = this.state.current + 1;
+		this.state.steps[this.state.current] = values;
+		if (this.state.current === 0 && this.props.title) {
+			this.props.title(values.name);
+		}
+		this.setState({
+			current: current,
+			steps: this.state.steps
+		});
+	},
+	prev() {
+		const current = this.state.current - 1;
+		this.setState({ current });
+	},
+	loadData(id) {
+		this.state.step=0;
+		$.ajax({
+			url: globalConfig.context + '/api/user/evaluate/info/' + id
+		})
+			.done(
+				function(res) {
+					if (res && res.data) {
+						this.setState({
+							steps: res.data.steps || {},
+							current: res.data.step || 0,
+							step: res.data.step || 0,
+							value: res.data.value || 0,
+							loading: false
+						});
+						if (this.props.title) {
+							this.props.title(res.data.name || '');
+						}
+					}
+				}.bind(this)
+			)
+			.fail(
+				function() {
+					this.setState({
+						loading: false
+					});
+				}.bind(this)
+			);
+		this.setState({
+			current: this.props.step || 0
+		});
+	},
+	componentWillMount() {
+		this.loadData(this.props.id);
+	},
+	componentWillReceiveProps(nextProps) {
+		if (!this.props.visible && nextProps.visible) {
+			if (nextProps.id) {
+        		this.loadData(nextProps.id);
+			}
+		}
+	},
+	progressDot(dot, { index }) {
+		return (
+			<span
+				style={{ cursor: 'pointer' }}
+				onClick={() => {
+					if (index == this.state.step || !!this.state.steps[index]) {
+						this.setState({
+							current: index
+						});
+					}
+				}}
+			>
+				{dot}
+			</span>
+		);
+	},
+	render() {
+		this.state.StepContent = steps[this.state.current].content;
+		let loadContent = !!this.state.steps;
+		console.log(this.state.step)
+		return (
+			<Spin spinning={this.state.loading}>
+				<div style={{ marginTop: 10 }}>
+					<Steps current={this.state.current} progressDot={this.progressDot} value={this.state.value}>
+						{steps.map((item) => <Step key={item.title} title={item.title} />)}
+					</Steps>
+					<div className="steps-content">
+						{loadContent ? (
+							<this.state.StepContent
+								next={this.next}
+								prev={this.prev}
+								id={this.props.id}
+								visible={this.props.visible}
+								data={(this.state.step)?this.state.steps[this.state.current]:{}}
+								record={this.state.steps}
+								value={this.state.value}
+							/>
+						) : (
+							<div />
+						)}
+					</div>
+				</div>
+			</Spin>
+		);
+	}
+});
+
+export default EvaluateSteps;

+ 44 - 0
js/component/account/evaluate/steps.less

@@ -0,0 +1,44 @@
+.steps-content {
+    margin-top: 16px;
+    min-height: 360px;
+    text-align: left;
+    padding: 6px 24px;
+}
+
+.steps-name {
+    margin: 16px 0 0;
+    font-size: 16px;
+    font-weight: bold;
+}
+
+.steps-action {
+    padding: 6px 0;
+}
+.steps-result {
+    min-height: 300px;
+    margin-bottom: 20px;
+    .steps-value {
+        font-size: 24px;
+        font-weight: bold;
+        color: #ff0036;
+    }
+}
+.steps-form {
+    min-height: 300px;
+    .ant-form-item {
+        border-radius: 3px;
+        background: #fafafa;
+        padding: 10px 24px;
+        margin-bottom: 12px;
+        .ant-form-item-label {
+            text-align: left;
+        }
+    }
+    .ant-input-number {
+        width: 160px;
+    }
+}
+
+.steps-cell-key {
+    font-weight: bold;
+}

+ 172 - 0
js/component/account/evaluate/steps/dict.js

@@ -0,0 +1,172 @@
+
+module.exports = {
+  toMap(arr) {
+    let map = {};
+    arr.forEach((it) => {
+      map[it.id] = it.text;
+    });
+    return map;
+  },
+  transferTypes: [
+    { id: "1", text: "所有权转让" },
+    { id: "2", text: "独占许可" },
+    { id: "3", text: "普通许可" }
+  ],
+  leftTimes: [
+    { id: "3", text: "3年" },
+    { id: "4", text: "4年" },
+    { id: "5", text: "5年" },
+    { id: "6", text: "6年" },
+    { id: "7", text: "7年" },
+    { id: "8", text: "8年" },
+    { id: "9", text: "9年" },
+    { id: "10", text: "10年" },
+    { id: "11", text: "11年" },
+    { id: "12", text: "12年" },
+    { id: "13", text: "13年" },
+    { id: "14", text: "14年" },
+    { id: "15", text: "15年" },
+    { id: "16", text: "16年" },
+    { id: "17", text: "17年" },
+    { id: "18", text: "18年" },
+    { id: "19", text: "19年" },
+    { id: "20", text: "20年以上" }
+  ],
+  accessMethods: [
+    { id: "1", text: "自主研发" },
+    { id: "2", text: "外购取得" },
+    { id: "3", text: "许可取得" },
+  ],
+  legalStatus: [
+    { id: "1", text: "已获专利证书-发明专利,受法律保护" },
+    { id: "2", text: "已获专利证书-实用新型专利,受法律保护" },
+    { id: "3", text: "已获专利证书-外观技术专利,受法律保护" },
+    { id: "4", text: "已申请尚未获得证书,一定程度上受法律保护" },
+    { id: "5", text: "专有技术,未申请法律保护" },
+  ],
+  maintenanceStatus: [
+    { id: "1", text: "专利按时缴纳年费" },
+    { id: "2", text: "专利已过期或未按时缴纳年费" },
+  ],
+  confidentialities: [
+    { id: "1", text: "他人无法获知,保密性强" },
+    { id: "2", text: "他人较少可能获知,保密性较强" },
+    { id: "3", text: "他人可能获知,保密性一般" },
+    { id: "4", text: "他人很有可能获知,保密性较差" },
+    { id: "5", text: "无法保密" },
+  ],
+  decidabilities: [
+    { id: "1", text: "易发现且易判定" },
+    { id: "2", text: "易发现但不易判定" },
+    { id: "3", text: "难以发现他人是否侵权" },
+    { id: "4", text: "非专利技术,无法判定他人侵权" },
+  ],
+  rightLimitations: [
+    { id: "1", text: "否" },
+    { id: "2", text: "是" },
+  ],
+  progressiveness: [
+    { id: "1", text: "填补了世界空白" },
+    { id: "2", text: "填补了国内空白" },
+    { id: "3", text: "国家级领先技术" },
+    { id: "4", text: "省域级领先技术" },
+    { id: "5", text: "市域级领先技术" },
+    { id: "6", text: "先进性方面与类似技术相差不大" },
+  ],
+  innovativeness: [
+    { id: "1", text: "具有突破性创新" },
+    { id: "2", text: "非突破性创新,但功效有显著提升" },
+    { id: "3", text: "非突破性创新,但功效有一定提升" },
+    { id: "4", text: "有类似技术且功效差不多" },
+    { id: "5", text: "功效差于现行类似技术" },
+    { id: "6", text: "功效无法判定" },
+  ],
+  ripeness: [
+    { id: "1", text: "技术成熟并已产业化多年" },
+    { id: "2", text: "技术成熟,已产业化一年以下" },
+    { id: "3", text: "技术成熟,已成功进行试生产,即将产业化" },
+    { id: "4", text: "技术已研发完成,尚未投入生产" },
+    { id: "5", text: "技术处于中试阶段" },
+    { id: "6", text: "仅为概念或早期阶段、小试阶段" },
+  ],
+  alternatives: [
+    { id: "1", text: "具有不可替代性" },
+    { id: "2", text: "与其他类似技术相比具有优势,较难被替代" },
+    { id: "3", text: "有其他相同的替代技术" },
+    { id: "4", text: "有其他更好的替代技术" },
+  ],
+  defensive: [
+    { id: "1", text: "技术复杂程度高,所需资金量大" },
+    { id: "2", text: "技术复杂程度较高,所需资金量较大" },
+    { id: "3", text: "技术复杂程度较高,但所需资金量不大" },
+    { id: "4", text: "技术复杂程度不高,所需资金量较大" },
+    { id: "5", text: "技术复杂程度不高,所需资金量不大" },
+    { id: "6", text: "技术简单,所需资金量小" },
+  ],
+  prospect: [
+    { id: "1", text: "技术产品所属领域发展前景好" },
+    { id: "2", text: "技术产品所属领域发展前景较好" },
+    { id: "3", text: "技术产品所属领域发展前景一般" },
+    { id: "4", text: "技术产品所属领域发展前景较差" },
+    { id: "5", text: "技术产品所属领域发展前景差" },
+  ],
+  supplyAndDemand: [
+    { id: "1", text: "解决了行业的必需技术问题,为广大厂商所需要,具有一定垄断性" },
+    { id: "2", text: "解决了行业的重要技术问题,供不应求" },
+    { id: "3", text: "解决了行业一般技术问题,形成一定需求" },
+    { id: "4", text: "解决了行业非重要技术问题,形成少量需求" },
+    { id: "5", text: "解决了生产中某一附加技术问题或改进了某一技术环节,对于整体生产环节的改进有一定作用,形成一定潜在需求" },
+    { id: "6", text: "解决了生产中某一附加技术问题或改进了某一技术环节,对于整体生产环节的改进并未产生作用" },
+  ],
+  rangeOfApplication: [
+    { id: "1", text: "技术产品应用于全国" },
+    { id: "2", text: "技术产品应用于省域或省级区域" },
+    { id: "3", text: "技术产品应用范围较小" },
+    { id: "4", text: "技术产品应用范围非常小" },
+  ],
+  imitable: [
+    { id: "1", text: "较低" },
+    { id: "2", text: "中等" },
+    { id: "3", text: "高" },
+  ],
+  profitability: [
+    { id: "1", text: "可以单独应用于产品,发挥技术作用" },
+    { id: "2", text: "需要与其他相关技术或专利一起应用于产品,共同发挥作用,且占主要作用" },
+    { id: "3", text: "需要与其他相关技术或专利一起应用于产品,共同发挥作用,只起次要作用" },
+  ],
+  political: [
+    { id: "1", text: "政府大力支持,出台了支持行业发展的政策,政策风险低" },
+    { id: "2", text: "政府鼓励发展的行业或项目,政策风险较低" },
+    { id: "3", text: "政府既未鼓励、也未限制的行业,政策风险一般" },
+    { id: "4", text: "政府限制发展的行业或项目,政策风险较高" },
+    { id: "5", text: "政府限制或禁止的行业或项目,出台了相关限制或禁止政策,风险高" },
+  ],
+  technical: [
+    { id: "1", text: "技术先进,创新性好,技术成熟,防御力高" },
+    { id: "2", text: "技术较先进,创新性较好,防御力较高,技术较成熟" },
+    { id: "3", text: "技术先进度一般,创新性较好,防御力一般,技术较成熟" },
+    { id: "4", text: "技术先进度一般,创新性一般,防御力一般,技术尚未产业化" },
+    { id: "5", text: "技术先进度一般,创新性一般,防御力一般,技术处于研发或试验阶段" },
+  ],
+  market: [
+    { id: "1", text: "产品市场容量大,产品供不应求,具有一定垄断地位" },
+    { id: "2", text: "产品市场容量较大,产品供不应求,具有先发优势" },
+    { id: "3", text: "产品市场容量不大,产品供需大致平衡" },
+    { id: "4", text: "产品市场容量小,但能够在竞争中取得一定市场份额" },
+    { id: "5", text: "产品市场容量小,供大于求,竞争激烈" },
+  ],
+  capital: [
+    { id: "1", text: "所需资金量小,融资渠道宽" },
+    { id: "2", text: "所需资金量较小,融资渠道较宽" },
+    { id: "3", text: "所需资金量较大,融资渠道较宽" },
+    { id: "4", text: "所需资金量较大,融资渠道较窄" },
+    { id: "5", text: "所需资金量大,且融资渠道窄" },
+  ],
+  management: [
+    { id: "1", text: "拟实施该技术的企业管理内部规范,内控健全有效,管理层团队稳定" },
+    { id: "2", text: "拟实施该技术的企业管理内部较规范,管理层团队较稳定,内控体系较健全" },
+    { id: "3", text: "拟实施该技术的企业管理内部较规范,管理层团队较稳定,内控体系较存在缺陷" },
+    { id: "4", text: "拟实施该技术的企业管理内部不够规范,内控体系存在缺陷,管理层团队较稳定" },
+    { id: "5", text: "拟实施该技术的企业管理内部不规范,内控体系存在较大缺陷,管理层团队不稳定" },
+  ]
+}

+ 298 - 0
js/component/account/evaluate/steps/step1.jsx

@@ -0,0 +1,298 @@
+import React from 'react';
+import { Form, Select, Input, Cascader, Spin, message, Button, DatePicker } from 'antd';
+import ajax from 'jquery/src/ajax/xhr.js'
+import $ from 'jquery/src/ajax';
+import moment from 'moment';
+import { transferTypes, leftTimes } from './dict.js';
+
+const FormItem = Form.Item;
+const Option = Select.Option;
+const MonthPicker = DatePicker.MonthPicker;
+
+const formItemLayout = {
+  labelCol: { span: 4 },
+  wrapperCol: { span: 10 },
+};
+const currency = ['人民币 (RMB)', '美金 (USD)', '台币(TWD)', '港币 (HKD)', '澳门元(MOP)', '欧元 (EUR)', '英镑 (GBP)', '日元 (JPY)', '澳大利亚元 (AUD)', '巴西里亚尔(BRL)', '加拿大元 (CAD)', '瑞士法郎 (CHF)', '丹麦克朗(DKK)', '印尼卢比 (IDR)', '韩国元 (KRW)', '林吉特(MYR)', '新西兰元 (NZD)', '菲律宾比索 (PHP)', '瑞典克朗 (SEK)', '新加坡元 (SGD)', '泰国铢 (THB)', '越南盾 (VND)', '南非兰特 (ZAR)']
+
+const EvaluateStep1 = Form.create({})(React.createClass({
+  getInitialState() {
+    return {
+      loading: true,
+      industry: [],
+      district: [],
+      subIndustries: {},
+      subIndustry: [],
+      initialData: {}
+    };
+  },
+  componentWillMount() {
+      this.loadData();
+      this.state.initialData = this.props.data || {};
+  },
+  componentWillReceiveProps(nextProps) {
+      if(!this.props.visible&&nextProps.visible){
+        this.setState({
+          initialData:nextProps.data
+        })
+      }
+	},
+  loadData() {
+    $.when($.ajax({
+      url: globalConfig.context + '/open/findIndustryCategory'
+    }), $.ajax({
+      url: globalConfig.context + '/open/findDistrict'
+    })).done(function (industryRes, districtRes) {
+      let i = [], d = [{
+        id: 0, level: 0, pid: 0, name: '全国'
+      }];
+      if (industryRes[0] && industryRes[0].data) {
+        i = industryRes[0].data;
+      }
+      if (districtRes[0] && districtRes[0].data) {
+        d = d.concat(districtRes[0].data);
+      }
+      this.setState({
+        loading: false,
+        industry: i,
+        district: d
+      });
+      if (this.state.initialData) {
+        this.changeFormField({
+          'industry': this.stringify(this.state.initialData.industry),
+          'transferArea': this.state.initialData.transferArea && this.state.initialData.transferArea.split(',')
+        });
+        this.loadSubIndustry(this.state.initialData.industry, this.state.initialData.subIndustry)
+      }
+    }.bind(this)).fail(function () {
+      this.setState({
+        loading: false
+      })
+    }.bind(this));
+  },
+  loadIndustry(pid, initValue) {
+    if (this.industryLoader) {
+      this.industryLoader.abort();
+    }
+    this.setState({
+      loading: true
+    })
+    this.industryLoader = $.ajax({
+      url: globalConfig.context + '/open/findIndustryCategory',
+      method: 'get',
+      data: {
+        id: pid || 0
+      }
+    }).done(function (res) {
+      if (res.data && res.data.length) {
+        this.state.subIndustries[pid] = res.data;
+        this.setState({
+          loading: false,
+          subIndustry: res.data
+        })
+        if (initValue) {
+          this.changeFormField({
+            'subIndustry': initValue.split(',')
+          });
+        }
+      }
+    }.bind(this)).always(function () {
+      this.setState({
+        loading: false
+      })
+    }.bind(this));
+  },
+  loadSubIndustry(pid, initValue) {
+    let { subIndustries } = this.state;
+    pid = Number(pid);
+    this.changeFormField({
+      'subIndustry': []
+    });
+    if (subIndustries[pid]) {
+      this.setState({
+        subIndustry: subIndustries[pid]
+      })
+    } else {
+      this.loadIndustry(pid, initValue)
+    }
+  },
+  subIndustryChanged(values) {
+    let warn = false
+    while (values.length > 3) {
+      values.pop();
+      warn = true;
+    }
+    if (warn) {
+      message.warn("子行业最多选择三个!")
+      this.changeFormField({
+        'subIndustry': values
+      });
+    }
+  },
+  districtChanged(values) {
+    let warn = false
+    values.forEach((val) => {
+      if (val === '0') {
+        warn = true;
+      }
+    });
+    if (warn) {
+      this.changeFormField({
+        'transferArea': ['0']
+      });
+    }
+  },
+  changeFormField(data) {
+    setTimeout(function () {
+      this.props.form.setFieldsValue(data);
+    }.bind(this), 10);
+  },
+  next() {
+    if (this.state.loading) {
+      return;
+    }
+    this.props.form.validateFields((err, values) => {
+      if (!err) {
+        this.setState({
+          loading: true
+        })
+        values.id = this.props.id;
+        values.subIndustry = values.subIndustry.join(',');
+        values.transferArea = values.transferArea.join(',');
+        values.benchmarkDate = values.benchmarkDate.format('YYYY-MM-DD')
+        $.ajax({
+          url: globalConfig.context + '/api/user/evaluate/step1',
+          method: 'post',
+          data: values
+        }).done(function (res) {
+          if (res.error && res.error.length) {
+            message.error(res.error[0].message)
+          } else {
+            if (this.props.next) {
+              this.props.next(values);
+            }
+          }
+        }.bind(this)).fail(function () {
+          this.setState({
+            loading: false
+          })
+        }.bind(this));
+      }
+    });
+  },
+  onDateChange(date) {
+    date && date.date(1)
+    this.changeFormField({
+      'benchmarkDate': date
+    });
+  },
+  stringify(val) {
+    return val && String(val)
+  },
+  render() {
+    const { getFieldDecorator } = this.props.form;
+    let { subIndustry, industry, district, loading, initialData } = this.state;
+    console.log(this.state.initialData)
+    return (
+      <Spin spinning={loading}>
+        <Form className="steps-form">
+          <FormItem label="技术名称" {...formItemLayout}>
+            {getFieldDecorator('name', {
+              rules: [{ required: true, message: '请输入技术名称!' }],
+              initialValue: initialData.name
+            })(
+              <Input placeholder="请输入技术名称" />
+              )}
+          </FormItem>
+          <FormItem label="所属主行业" {...formItemLayout}>
+            {getFieldDecorator('industry', {
+              rules: [{ required: true, message: '请选择技术所属主行业!' }],
+              initialValue:initialData.industry
+            })(
+              <Select placeholder="请选择技术所属主行业" onChange={this.loadSubIndustry}>
+                {industry.map((it) => {
+                  return <Option key={it.id} value={String(it.id)}>{it.name}</Option>
+                })}
+              </Select>
+              )}
+          </FormItem>
+          <FormItem label="所属子行业" {...formItemLayout}>
+            {getFieldDecorator('subIndustry', {
+              rules: [{ required: true, message: '请选择技术所属子行业!' }],
+              initialValue:initialData.subIndustry
+            })(
+              <Select placeholder="请选择技术所属子行业" allowClear={true} multiple={true} onChange={this.subIndustryChanged}>
+                {
+                  subIndustry.length ? subIndustry.map((it) => {
+                    return <Option key={it.id} value={String(it.id)}>{it.name}</Option>
+                  }) : []
+                }
+              </Select>
+              )}
+          </FormItem>
+          <FormItem label="转让方式" {...formItemLayout}>
+            {getFieldDecorator('transferType', {
+              rules: [{ required: true, message: '请选择技术转让方式!' }],
+              initialValue: this.stringify(initialData.transferType)
+            })(
+              <Select placeholder="请选择技术转让方式">
+                {transferTypes.map((it) => {
+                  return <Option key={it.id} value={it.id}>{it.text}</Option>
+                })}
+              </Select>
+              )}
+          </FormItem>
+          <FormItem label="预估技术剩余寿命" {...formItemLayout}>
+            {getFieldDecorator('timeLeft', {
+              rules: [{ required: true, message: '请选择技术剩余寿命!' }],
+              initialValue: this.stringify(initialData.timeLeft)
+            })(
+              <Select placeholder="请选择技术剩余寿命">
+                {leftTimes.map((it) => {
+                  return <Option key={it.id} value={it.id}>{it.text}</Option>
+                })}
+              </Select>
+              )}
+          </FormItem>
+          <FormItem label="转让区域" {...formItemLayout}>
+            {getFieldDecorator('transferArea', {
+              rules: [{ required: true, message: '请选择技术转让区域!' }],
+              initialValue:initialData.transferArea
+            })(
+              <Select placeholder="请选择技术转让区域" allowClear={true} multiple={true} onChange={this.districtChanged}>
+                {district.map((it) => {
+                  return <Option key={it.id} value={String(it.id)}>{it.name}</Option>
+                })}
+              </Select>
+              )}
+          </FormItem>
+          <FormItem label="评估基准日" {...formItemLayout}>
+            {getFieldDecorator('benchmarkDate', {
+              rules: [{ required: true, message: '请输入评估基准日!' }],
+              initialValue: initialData.benchmarkDate ? moment(initialData.benchmarkDate, 'YYYY-MM-DD') : null
+            })(
+              <MonthPicker allowClear={false} onChange={this.onDateChange} placeholder="请输入评估基准日" format="YYYY-MM-DD" />
+              )}
+          </FormItem>
+          <FormItem label="评估币种" {...formItemLayout}>
+            {getFieldDecorator('currencyType', {
+              rules: [{ required: true, message: '请选择评估币种!' }],
+              initialValue: initialData.currencyType || '人民币 (RMB)'
+            })(
+              <Select placeholder="请选择评估币种">
+                {currency.map((it, idx) => {
+                  return <Option key={idx} value={it}>{it}</Option>
+                })}
+              </Select>
+              )}
+          </FormItem>
+        </Form>
+        <div className="steps-action">
+          <Button type="primary" onClick={this.next}>保存,下一步</Button>
+        </div>
+      </Spin>
+    )
+  },
+}));
+
+export default EvaluateStep1;

+ 151 - 0
js/component/account/evaluate/steps/step2.jsx

@@ -0,0 +1,151 @@
+import React from 'react';
+import { Spin, Form, Button, Select, message } from 'antd';
+import ajax from 'jquery/src/ajax/xhr.js'
+import $ from 'jquery/src/ajax';
+import { accessMethods, legalStatus, maintenanceStatus, confidentialities, decidabilities, rightLimitations } from './dict.js';
+
+const FormItem = Form.Item;
+const Option = Select.Option;
+
+const formItemLayout = {
+  labelCol: { span: 6 },
+  wrapperCol: { span: 10 }
+};
+
+const EvaluateStep2 = Form.create({})(React.createClass({
+  getInitialState() {
+    return {
+      loading: false,
+      initialData: {}
+    };
+  },
+  componentWillMount() {
+    this.state.initialData = this.props.data || {};
+  },
+  next() {
+    if (this.state.loading) {
+      return;
+    }
+    this.props.form.validateFields((err, values) => {
+      if (!err) {
+        this.setState({
+          loading: true
+        })
+        values.id = this.props.id;
+        $.ajax({
+          url: globalConfig.context + '/api/user/evaluate/step2',
+          method: 'post',
+          data: values
+        }).done(function (res) {
+          if (res.error && res.error.length) {
+            message.error(res.error[0].message)
+          } else {
+            if (this.props.next) {
+              this.props.next(values);
+            }
+          }
+        }.bind(this)).fail(function () {
+          this.setState({
+            loading: false
+          })
+        }.bind(this));
+      }
+    });
+  },
+  prev() {
+    if (this.props.prev) {
+      this.props.prev();
+    }
+  },
+  stringify(val) {
+    return val && String(val)
+  },
+  render() {
+    let { loading, initialData } = this.state;
+    const { getFieldDecorator } = this.props.form;
+    return (
+      <Spin spinning={loading}>
+        <Form className="steps-form">
+          <FormItem label="取得方式" {...formItemLayout}>
+            {getFieldDecorator('accessMethod', {
+              rules: [{ required: true, message: '请选择技术取得的方式!' }],
+              initialValue: this.stringify(initialData.accessMethod)
+            })(
+              <Select placeholder="请选择技术取得的方式">
+                {accessMethods.map((it) => {
+                  return <Option key={it.id} value={it.id}>{it.text}</Option>
+                })}
+              </Select>
+              )}
+          </FormItem>
+          <FormItem label="法律状态" {...formItemLayout}>
+            {getFieldDecorator('legalStatus', {
+              rules: [{ required: true, message: '请选择法律保护状态!' }],
+              initialValue: this.stringify(initialData.legalStatus)
+            })(
+              <Select placeholder="请选择法律保护状态">
+                {legalStatus.map((it) => {
+                  return <Option key={it.id} value={it.id}>{it.text}</Option>
+                })}
+              </Select>
+              )}
+          </FormItem>
+          <FormItem label="专利维护" {...formItemLayout}>
+            {getFieldDecorator('patentMaintenance', {
+              rules: [{ required: true, message: '请选择专利维护状态!' }],
+              initialValue: this.stringify(initialData.patentMaintenance)
+            })(
+              <Select placeholder="请选择专利维护状态">
+                {maintenanceStatus.map((it) => {
+                  return <Option key={it.id} value={it.id}>{it.text}</Option>
+                })}
+              </Select>
+              )}
+          </FormItem>
+          <FormItem label="保密性" {...formItemLayout}>
+            {getFieldDecorator('confidentiality', {
+              rules: [{ required: true, message: '请选择保密性!' }],
+              initialValue: this.stringify(initialData.confidentiality)
+            })(
+              <Select placeholder="请选择保密性">
+                {confidentialities.map((it) => {
+                  return <Option key={it.id} value={it.id}>{it.text}</Option>
+                })}
+              </Select>
+              )}
+          </FormItem>
+          <FormItem label="他人侵权的易判定性" {...formItemLayout}>
+            {getFieldDecorator('decidability', {
+              rules: [{ required: true, message: '请选择他人侵权的易判定性!' }],
+              initialValue: this.stringify(initialData.decidability)
+            })(
+              <Select placeholder="请选择他人侵权的易判定性">
+                {decidabilities.map((it) => {
+                  return <Option key={it.id} value={it.id}>{it.text}</Option>
+                })}
+              </Select>
+              )}
+          </FormItem>
+          <FormItem label="是否涉及质押、担保、诉讼等权利限制" {...formItemLayout}>
+            {getFieldDecorator('hasRightLimitation', {
+              rules: [{ required: true, message: '请选择是否涉及质押、担保、诉讼等权利限制!' }],
+              initialValue: this.stringify(initialData.hasRightLimitation)
+            })(
+              <Select placeholder="请选择是否涉及质押、担保、诉讼等权利限制">
+                {rightLimitations.map((it) => {
+                  return <Option key={it.id} value={it.id}>{it.text}</Option>
+                })}
+              </Select>
+              )}
+          </FormItem>
+        </Form>
+        <div className="steps-action">
+          <Button type="primary" onClick={this.next}>保存,下一步</Button>
+          <Button style={{ marginLeft: 8 }} onClick={this.prev}>上一步</Button>
+        </div>
+      </Spin>
+    )
+  },
+}));
+
+export default EvaluateStep2;

+ 199 - 0
js/component/account/evaluate/steps/step3.jsx

@@ -0,0 +1,199 @@
+import React from 'react';
+import { Spin, Form, Button, Select, message } from 'antd';
+import ajax from 'jquery/src/ajax/xhr.js'
+import $ from 'jquery/src/ajax';
+import { progressiveness, innovativeness, ripeness, alternatives, defensive, prospect, supplyAndDemand, rangeOfApplication, imitable, profitability } from './dict.js';
+
+const FormItem = Form.Item;
+const Option = Select.Option;
+
+const formItemLayout = {
+  labelCol: { span: 4 },
+  wrapperCol: { span: 14 },
+};
+
+const EvaluateStep3 = Form.create({})(React.createClass({
+  getInitialState() {
+    return {
+      loading: false,
+      initialData: {}
+    };
+  },
+  componentWillMount() {
+    this.state.initialData = this.props.data || {};
+  },
+  next() {
+    if (this.state.loading) {
+      return;
+    }
+    this.props.form.validateFields((err, values) => {
+      if (!err) {
+        this.setState({
+          loading: true
+        })
+        values.id = this.props.id;
+        $.ajax({
+          url: globalConfig.context + '/api/user/evaluate/step3',
+          method: 'post',
+          data: values
+        }).done(function (res) {
+          if (res.error && res.error.length) {
+            message.error(res.error[0].message)
+          } else {
+            if (this.props.next) {
+              this.props.next(values);
+            }
+          }
+        }.bind(this)).fail(function () {
+          this.setState({
+            loading: false
+          })
+        }.bind(this));
+      }
+    });
+  },
+  prev() {
+    if (this.props.prev) {
+      this.props.prev();
+    }
+  },
+  stringify(val) {
+    return val && String(val)
+  },
+  render() {
+    let { loading, initialData } = this.state;
+    const { getFieldDecorator } = this.props.form;
+    return (
+      <Spin spinning={loading}>
+        <Form className="steps-form">
+          <FormItem label="先进性" {...formItemLayout}>
+            {getFieldDecorator('progressiveness', {
+              rules: [{ required: true, message: '请选择技术的先进性!' }],
+              initialValue: this.stringify(initialData.progressiveness)
+            })(
+              <Select placeholder="请选择技术的先进性">
+                {progressiveness.map((it) => {
+                  return <Option key={it.id} value={it.id}>{it.text}</Option>
+                })}
+              </Select>
+              )}
+          </FormItem>
+          <FormItem label="创新性" {...formItemLayout}>
+            {getFieldDecorator('innovativeness', {
+              rules: [{ required: true, message: '请选择技术的创新性!' }],
+              initialValue: this.stringify(initialData.innovativeness)
+            })(
+              <Select placeholder="请选择技术的创新性">
+                {innovativeness.map((it) => {
+                  return <Option key={it.id} value={it.id}>{it.text}</Option>
+                })}
+              </Select>
+              )}
+          </FormItem>
+          <FormItem label="成熟度" {...formItemLayout}>
+            {getFieldDecorator('ripeness', {
+              rules: [{ required: true, message: '请选择技术的成熟度!' }],
+              initialValue: this.stringify(initialData.ripeness)
+            })(
+              <Select placeholder="请选择技术的成熟度">
+                {ripeness.map((it) => {
+                  return <Option key={it.id} value={it.id}>{it.text}</Option>
+                })}
+              </Select>
+              )}
+          </FormItem>
+          <FormItem label="替代性" {...formItemLayout}>
+            {getFieldDecorator('alternatives', {
+              rules: [{ required: true, message: '请选择技术的替代性!' }],
+              initialValue: this.stringify(initialData.alternatives)
+            })(
+              <Select placeholder="请选择技术的替代性">
+                {alternatives.map((it) => {
+                  return <Option key={it.id} value={it.id}>{it.text}</Option>
+                })}
+              </Select>
+              )}
+          </FormItem>
+          <FormItem label="技术防御力" {...formItemLayout}>
+            {getFieldDecorator('defensive', {
+              rules: [{ required: true, message: '请选择技术的防御力!' }],
+              initialValue: this.stringify(initialData.defensive)
+            })(
+              <Select placeholder="请选择技术的防御力">
+                {defensive.map((it) => {
+                  return <Option key={it.id} value={it.id}>{it.text}</Option>
+                })}
+              </Select>
+              )}
+          </FormItem>
+          <FormItem label="技术领域发展前景" {...formItemLayout}>
+            {getFieldDecorator('prospect', {
+              rules: [{ required: true, message: '请选择技术领域发展前景!' }],
+              initialValue: this.stringify(initialData.prospect)
+            })(
+              <Select placeholder="请选择技术领域发展前景">
+                {prospect.map((it) => {
+                  return <Option key={it.id} value={it.id}>{it.text}</Option>
+                })}
+              </Select>
+              )}
+          </FormItem>
+          <FormItem label="供求关系" {...formItemLayout}>
+            {getFieldDecorator('supplyAndDemand', {
+              rules: [{ required: true, message: '请选择技术的供求关系!' }],
+              initialValue: this.stringify(initialData.supplyAndDemand)
+            })(
+              <Select placeholder="请选择技术的供求关系">
+                {supplyAndDemand.map((it) => {
+                  return <Option key={it.id} value={it.id}>{it.text}</Option>
+                })}
+              </Select>
+              )}
+          </FormItem>
+          <FormItem label="产品应用范围" {...formItemLayout}>
+            {getFieldDecorator('rangeOfApplication', {
+              rules: [{ required: true, message: '请选择技术的应用范围!' }],
+              initialValue: this.stringify(initialData.rangeOfApplication)
+            })(
+              <Select placeholder="请选择技术的应用范围">
+                {rangeOfApplication.map((it) => {
+                  return <Option key={it.id} value={it.id}>{it.text}</Option>
+                })}
+              </Select>
+              )}
+          </FormItem>
+          <FormItem label="遭他人模仿可能性" {...formItemLayout}>
+            {getFieldDecorator('imitable', {
+              rules: [{ required: true, message: '请选择技术的模仿可能性!' }],
+              initialValue: this.stringify(initialData.imitable)
+            })(
+              <Select placeholder="请选择技术的模仿可能性">
+                {imitable.map((it) => {
+                  return <Option key={it.id} value={it.id}>{it.text}</Option>
+                })}
+              </Select>
+              )}
+          </FormItem>
+          <FormItem label="独立获利能力" {...formItemLayout}>
+            {getFieldDecorator('profitability', {
+              rules: [{ required: true, message: '请选择技术的独立获利能力!' }],
+              initialValue: this.stringify(initialData.profitability)
+            })(
+              <Select placeholder="请选择技术的独立获利能力">
+                {profitability.map((it) => {
+                  return <Option key={it.id} value={it.id}>{it.text}</Option>
+                })}
+              </Select>
+              )}
+          </FormItem>
+        </Form>
+        <div className="steps-action">
+          <Button type="primary" onClick={() => this.next()}>保存,下一步</Button>
+          <Button style={{ marginLeft: 8 }} onClick={() => this.prev()}>上一步</Button>
+        </div>
+      </Spin>
+    )
+  },
+}));
+
+export default EvaluateStep3;

+ 206 - 0
js/component/account/evaluate/steps/step4.jsx

@@ -0,0 +1,206 @@
+import React from 'react';
+import { Spin, Form, Button, message, Radio, Table, InputNumber } from 'antd';
+import ajax from 'jquery/src/ajax/xhr.js'
+import $ from 'jquery/src/ajax';
+
+const RadioButton = Radio.Button;
+const RadioGroup = Radio.Group;
+const FormItem = Form.Item;
+
+const formItemLayout = {
+  labelCol: { span: 4 },
+  wrapperCol: { span: 10 },
+};
+
+const now = new Date();
+
+const EvaluateStep4 = Form.create({})(React.createClass({
+  getInitialState() {
+    return {
+      loading: false,
+      initialData: {},
+      hasIncome: '1',
+      dataSource: []
+    };
+  },
+  componentWillMount() {
+    let initialData = this.props.data || {}, dataSource = [];
+    if (initialData.incomes) {
+      dataSource = initialData.incomes;
+    } else {
+      let step1 = this.props.record && this.props.record[0] || {};
+      let year = now.getFullYear();//Number(step1.benchmarkDate && step1.benchmarkDate.split('-')[0]) || now.getFullYear();
+      for (let i = 1; i < 4; i++) {
+        dataSource.push({
+          year: year - i,
+          income: '',
+          profit: ''
+        })
+      }
+    }
+    this.state.dataSource = dataSource;
+    this.state.initialData = initialData;
+    this.state.hasIncome = initialData.hasIncome || '1'
+  },
+  next() {
+    if (this.state.loading) {
+      return;
+    }
+    this.props.form.validateFields((err, values) => {
+      if (!err) {
+        this.setState({
+          loading: true
+        })
+        let data = {
+          id: this.props.id,
+          hasIncome: values.hasIncome
+        }, val = {
+          hasIncome: values.hasIncome
+        }
+        if (data.hasIncome == 2) {
+          let incomes = [], year = 0;
+          for (let i = 0; i < 3; i++) {
+            year = this.state.dataSource[i].year;
+            incomes.push({
+              year: year,
+              income: values['income' + year] || 0,
+              profit: values['profit' + year] || 0
+            })
+          }
+          data.incomes = JSON.stringify(incomes);
+          val.incomes = incomes;
+        }
+        $.ajax({
+          url: globalConfig.context + '/api/user/evaluate/step4',
+          method: 'post',
+          data: data
+        }).done(function (res) {
+          if (res.error && res.error.length) {
+            message.error(res.error[0].message)
+          } else {
+            if (this.props.next) {
+              this.props.next(val);
+            }
+          }
+        }.bind(this)).fail(function () {
+          this.setState({
+            loading: false
+          })
+        }.bind(this));
+      } else {
+        for (let field in err) {
+          if (err.hasOwnProperty(field)) {
+            message.error(err[field].errors[0].message)
+            break;
+          }
+        }
+      }
+    });
+  },
+  prev() {
+    if (this.props.prev) {
+      this.props.prev();
+    }
+  },
+  onRadioChange(e) {
+    this.setState({
+      hasIncome: e.target.value,
+    });
+  },
+  tableCols() {
+    const { getFieldDecorator } = this.props.form;
+    return [
+      {
+        title: '年份',
+        dataIndex: 'year',
+        key: 'year',
+        render: (text, it) => {
+          return <div>{text}</div>
+        }
+      },
+      {
+        title: '营收(元)',
+        dataIndex: 'income',
+        key: 'income',
+        render: (text, it, index) => {
+          let rules = [];
+          if (index === 0) {
+            rules.push({ required: index === 0, message: '请输入' + it.year + '营收情况!' })
+            rules.push({
+              validator: (rule, value, callback) => {
+                if (!Number(value)) {
+                  callback('请输入' + it.year + '营收情况!' );
+                } else {
+                  callback();
+                }
+              },
+            })
+          }
+          return getFieldDecorator('income' + it.year, {
+            initialValue: text || 0,
+            rules: rules
+          })(<InputNumber min={0} placeholder="请输入营收情况" />);
+        }
+      },
+      {
+        title: '利润率(%)',
+        dataIndex: 'profit',
+        key: 'profit',
+        render: (text, it, index) => {
+          let rules = [];
+          if (index === 0) {
+            rules.push({ required: index === 0, message: '请输入' + it.year + '利润率!' })
+            rules.push({
+              validator: (rule, value, callback) => {
+                if (!Number(value)) {
+                  callback('请输入' + it.year + '利润率!' );
+                } else {
+                  callback();
+                }
+              },
+            })
+          }
+          return getFieldDecorator('profit' + it.year, {
+            initialValue: text || 0,
+            rules: rules
+          })(<InputNumber min={0} placeholder="请输入利润率" />);
+        }
+      },
+    ]
+  },
+  stringify(val) {
+    return val && String(val)
+  },
+  render() {
+    let { loading, initialData } = this.state;
+    const { getFieldDecorator } = this.props.form;
+    return (
+      <Spin spinning={loading}>
+        <div style={{ marginBottom: 10 }}>若该技术曾被应用于生产活动并产生收益,可选择【有历史收入】,若否,请选择【无历史收入】。</div>
+        <Form className="steps-form">
+          <FormItem label="是否有历史收入" {...formItemLayout}>
+            {getFieldDecorator('hasIncome', {
+              initialValue: this.stringify(initialData.hasIncome) || '1'
+            })(
+              <RadioGroup size="large" onChange={this.onRadioChange}>
+                <RadioButton value="1">无历史收入</RadioButton>
+                <RadioButton value="2">有历史收入</RadioButton>
+              </RadioGroup>
+              )}
+          </FormItem>
+          {
+            this.state.hasIncome == 1 ?
+              <div style={{ marginTop: 10 }}>无历史收入, 请直接进入下一步</div> :
+              <Table pagination={false} rowKey="year" columns={this.tableCols()} dataSource={this.state.dataSource} />
+          }
+        </Form>
+        <div className="steps-action">
+          <Button type="primary" onClick={() => this.next()}>保存,下一步</Button>
+          <Button style={{ marginLeft: 8 }} onClick={() => this.prev()}>上一步</Button>
+        </div>
+      </Spin>
+    )
+  },
+}));
+
+export default EvaluateStep4;

+ 344 - 0
js/component/account/evaluate/steps/step5.jsx

@@ -0,0 +1,344 @@
+import React from 'react';
+import { Spin, Form, Button, message, Radio, Table, InputNumber } from 'antd';
+import ajax from 'jquery/src/ajax/xhr.js'
+import $ from 'jquery/src/ajax';
+import money from '@/money.js';
+
+const RadioButton = Radio.Button;
+const RadioGroup = Radio.Group;
+const FormItem = Form.Item;
+
+const formItemLayout = {
+  labelCol: { span: 4 },
+  wrapperCol: { span: 10 },
+};
+const NUMBERS = {
+  1: '第一年',
+  2: '第二年',
+  3: '第三年',
+  4: '第四年',
+  5: '第五年',
+}
+
+const EvaluateStep5 = Form.create({})(React.createClass({
+  getInitialState() {
+    return {
+      loading: false,
+      initialData: {},
+      hasIncome: '1',
+      type: '1',
+      dataSource: []
+    };
+  },
+  componentWillMount() {
+    let initialData = this.props.data || {}, dataSource = initialData.forecastIncomes || [];
+    let step4 = this.props.record && this.props.record[3] || {};
+    let type = initialData.type || '1';
+    if (step4.hasIncome == 2) {
+      $.ajax({
+        url: globalConfig.context + '/api/user/evaluate/step5/' + this.props.id
+      }).done(function (res) {
+        if (res.error && res.error.length) {
+          message.error(res.error[0].message)
+        } else if (res.data && res.data.length === 3) {
+          for (let i = 0; i < 3; i++) {
+            dataSource[i] = Object.assign({
+              key: i,
+              income: 0,
+              unitPrice: 0,
+              saleCount: 0,
+              marketScale: 0,
+              marketRate: 0,
+              recommend: res.data[i] || 0
+            }, dataSource[i]);
+          }
+          this.setState({
+            loading: false,
+            dataSource: dataSource
+          })
+        }
+      }.bind(this)).fail(function () {
+        this.setState({
+          loading: false
+        })
+      }.bind(this));
+    } else {
+      for (let i = 0; i < 3; i++) {
+        dataSource[i] = Object.assign({
+          key: i,
+          income: 0,
+          unitPrice: 0,
+          saleCount: 0,
+          marketScale: 0,
+          marketRate: 0
+        }, dataSource[i] || {});
+      }
+      this.state.dataSource = dataSource;
+    }
+    this.state.initialData = initialData;
+    this.state.type = type;
+    this.state.hasIncome = String(step4.hasIncome) || '1'
+  },
+  next() {
+    if (this.state.loading) {
+      return;
+    }
+    this.props.form.validateFields((err, values) => {
+      if (!err) {
+        this.setState({
+          loading: true
+        })
+
+        let incomes = [];
+        for (let i = 0; i < 3; i++) {
+          incomes.push({
+            unitPrice: values['unitPrice' + i] || 0,
+            saleCount: values['saleCount' + i] || 0,
+            marketScale: values['marketScale' + i] || 0,
+            marketRate: values['marketRate' + i] || 0,
+            income: values['income' + i] || 0
+          })
+        }
+
+        $.ajax({
+          url: globalConfig.context + '/api/user/evaluate/step5',
+          method: 'post',
+          data: {
+            id: this.props.id,
+            type: values.type,
+            forecastIncomes: JSON.stringify(incomes)
+          }
+        }).done(function (res) {
+          if (res.error && res.error.length) {
+            message.error(res.error[0].message)
+          } else {
+            if (this.props.next) {
+              this.props.next({
+                type: values.type,
+                forecastIncomes: incomes
+              });
+            }
+          }
+        }.bind(this)).fail(function () {
+          this.setState({
+            loading: false
+          })
+        }.bind(this));
+      } else {
+        for (let field in err) {
+          if (err.hasOwnProperty(field)) {
+            message.error(err[field].errors[0].message)
+            break;
+          }
+        }
+      }
+    });
+  },
+  prev() {
+    if (this.props.prev) {
+      this.props.prev();
+    }
+  },
+  onRadioChange(e) {
+    this.props.form.resetFields();
+    this.setState({
+      type: e.target.value,
+    });
+  },
+  tableCols() {
+    const { getFieldDecorator, getFieldValue, setFieldsValue } = this.props.form;
+    const { type } = this.state;
+    let cols = [{
+      title: '年份',
+      dataIndex: 'key',
+      key: 'key',
+      render: (text, it, idx) => {
+        return <div>{NUMBERS[idx + 1]}</div>
+      }
+    }];
+    switch (type) {
+      case "2":
+        function calc(rate, scale, key) {
+          let fv = {};
+          fv['income' + key] = (scale * rate / 100) | 0
+          setFieldsValue(fv);
+        }
+        cols.push({
+          title: '市场规模(元)',
+          dataIndex: 'marketScale',
+          key: 'marketScale',
+          render: (text, it, idx) => {
+            return getFieldDecorator('marketScale' + it.key, {
+              initialValue: text || 0,
+              rules: [{
+                validator: (rule, value, callback) => {
+                  if (!Number(value)) {
+                    callback('请输入' + NUMBERS[idx + 1] + '市场规模!');
+                  } else {
+                    callback();
+                  }
+                },
+              }]
+            })(<InputNumber min={0} placeholder="请输入市场规模" onChange={value => {
+              calc(Number(getFieldValue('marketRate' + it.key)) || 0, Number(value) || 0, it.key);
+            }} />);
+          }
+        });
+        cols.push({
+          title: '技术覆盖率/市场份额(%)',
+          dataIndex: 'marketRate',
+          key: 'marketRate',
+          render: (text, it, idx) => {
+            return getFieldDecorator('marketRate' + it.key, {
+              initialValue: text || 0,
+              rules: [{
+                validator: (rule, value, callback) => {
+                  if (!Number(value)) {
+                    callback('请输入' + NUMBERS[idx + 1] + '市场份额!');
+                  } else {
+                    callback();
+                  }
+                },
+              }]
+            })(<InputNumber min={0} placeholder="请输入市场份额" onChange={value => {
+              calc(Number(value) || 0, getFieldValue('marketScale' + it.key) || 0, it.key);
+            }} />);
+          }
+        });
+        cols.push({
+          title: '营业收入(元)',
+          dataIndex: 'income',
+          key: 'income',
+          render: (text, it, idx) => {
+            return getFieldDecorator('income' + it.key, {
+              initialValue: text || 0
+            })(<InputNumber min={0} disabled={true} />);
+          }
+        });
+        break;
+      case "3":
+        function calc(rate, scale, key) {
+          let fv = {};
+          fv['income' + key] = (scale * rate) | 0
+          setFieldsValue(fv);
+        }
+        cols.push({
+          title: '单价(元)',
+          dataIndex: 'unitPrice',
+          key: 'unitPrice',
+          render: (text, it, idx) => {
+            return getFieldDecorator('unitPrice' + it.key, {
+              initialValue: text || 0,
+              rules: [{
+                validator: (rule, value, callback) => {
+                  if (!Number(value)) {
+                    callback('请输入' + NUMBERS[idx + 1] + '单价!');
+                  } else {
+                    callback();
+                  }
+                },
+              }]
+            })(<InputNumber min={0} placeholder="请输入单价" onChange={value => {
+              calc(Number(getFieldValue('saleCount' + it.key)) || 0, Number(value) || 0, it.key);
+            }} />);
+          }
+        });
+        cols.push({
+          title: '销量',
+          dataIndex: 'saleCount',
+          key: 'saleCount',
+          render: (text, it, idx) => {
+            return getFieldDecorator('saleCount' + it.key, {
+              initialValue: text || 0,
+              rules: [{
+                validator: (rule, value, callback) => {
+                  if (!Number(value)) {
+                    callback('请输入' + NUMBERS[idx + 1] + '销量!');
+                  } else {
+                    callback();
+                  }
+                },
+              }]
+            })(<InputNumber min={0} placeholder="请输入销量" onChange={value => {
+              calc(Number(value) || 0, getFieldValue('unitPrice' + it.key) || 0, it.key);
+            }} />);
+          }
+        });
+        cols.push({
+          title: '营业收入(元)',
+          dataIndex: 'income',
+          key: 'income',
+          render: (text, it, idx) => {
+            return getFieldDecorator('income' + it.key, {
+              initialValue: text || 0
+            })(<InputNumber min={0} disabled={true} />);
+          }
+        });
+        break;
+      default:
+        cols.push({
+          title: '营业收入(元)',
+          dataIndex: 'income',
+          key: 'income',
+          render: (text, it, idx) => {
+            return getFieldDecorator('income' + it.key, {
+              initialValue: text || 0,
+              rules: [{
+                validator: (rule, value, callback) => {
+                  if (!Number(value)) {
+                    callback('请输入' + NUMBERS[idx + 1] + '预估营业收入!');
+                  } else {
+                    callback();
+                  }
+                },
+              }]
+            })(<InputNumber min={0} placeholder="请输入预估营业收入" />);
+          }
+        })
+        break;
+    }
+    if (this.state.hasIncome == '2') {
+      cols.push({
+        title: '参考值(元)',
+        dataIndex: 'recommend',
+        key: 'recommend',
+        render: (text) => {
+          return money(text)
+        }
+      })
+    }
+    return cols
+  },
+  stringify(val) {
+    return val && String(val)
+  },
+  render() {
+    let { loading, dataSource, type } = this.state;
+    const { getFieldDecorator, getFieldValue, setFieldsValue } = this.props.form;
+    return (
+      <Spin spinning={loading}>
+        <div style={{ marginBottom: 10 }}>根据市场等,预测该技术应用于生产活动并产生收入情况。(选择以下三种方式中的一种预估方法)</div>
+        <Form className="steps-form">
+          <FormItem label="请选择预测方法" {...formItemLayout}>
+            {getFieldDecorator('type', {
+              initialValue: this.stringify(type)
+            })(
+              <RadioGroup size="large" onChange={this.onRadioChange}>
+                <RadioButton value="1">直接输入预测值法</RadioButton>
+                <RadioButton value="2">市场份额法</RadioButton>
+                <RadioButton value="3">数量单价法</RadioButton>
+              </RadioGroup>
+              )}
+          </FormItem>
+          <Table pagination={false} columns={this.tableCols()} dataSource={dataSource} />
+        </Form>
+        <div className="steps-action">
+          <Button type="primary" onClick={() => this.next()}>保存,下一步</Button>
+          <Button style={{ marginLeft: 8 }} onClick={() => this.prev()}>上一步</Button>
+        </div>
+      </Spin>
+    )
+  },
+}));
+
+export default EvaluateStep5;

+ 96 - 0
js/component/account/evaluate/steps/step6.jsx

@@ -0,0 +1,96 @@
+import React from 'react';
+import { Spin, Form, Button, InputNumber, message } from 'antd';
+import ajax from 'jquery/src/ajax/xhr.js'
+import $ from 'jquery/src/ajax';
+
+const FormItem = Form.Item;
+
+const formItemLayout = {
+  labelCol: { span: 6 },
+  wrapperCol: { span: 10 },
+};
+
+const EvaluateStep6 = Form.create({})(React.createClass({
+  getInitialState() {
+    return {
+      loading: false,
+      initialData: {}
+    };
+  },
+  componentWillMount() {
+    this.state.initialData = this.props.data || {};
+  },
+  next() {
+    if (this.state.loading) {
+      return;
+    }
+    this.props.form.validateFields((err, values) => {
+      if (!err) {
+        this.setState({
+          loading: true
+        })
+        $.ajax({
+          url: globalConfig.context + '/api/user/evaluate/step6',
+          method: 'post',
+          data: {
+            id: this.props.id,
+            taxRate: values.taxRate
+          }
+        }).done(function (res) {
+          if (res.error && res.error.length) {
+            message.error(res.error[0].message)
+          } else {
+            if (this.props.next) {
+              this.props.next(values);
+            }
+          }
+        }.bind(this)).fail(function () {
+          this.setState({
+            loading: false
+          })
+        }.bind(this));
+      }
+    });
+  },
+  prev() {
+    if (this.props.prev) {
+      this.props.prev();
+    }
+  },
+  stringify(val) {
+    return val && String(val)
+  },
+  render() {
+    let { loading, initialData } = this.state;
+    const { getFieldDecorator } = this.props.form;
+    return (
+      <Spin spinning={loading}>
+        <div style={{ marginBottom: 10 }}>提示:一般企业所得税率为25%,如果应用该项技术的公司有所得税优惠政策,按照优惠政策填列。如为高新技术企业请填15%</div>
+        <Form className="steps-form">
+          <FormItem label="预估企业所得税率(%)" {...formItemLayout}>
+            {getFieldDecorator('taxRate', {
+              initialValue: this.stringify(initialData.taxRate),
+              rules: [{ required: true, message: '请输入预估企业所得税率!' }, {
+                validator: (rule, value, callback) => {
+                  if (!Number(value)) {
+                    callback('请输入预估企业所得税率!');
+                  } else {
+                    callback();
+                  }
+                },
+              }]
+            })(
+              <InputNumber min={0} placeholder="请输入预估企业所得税率" />
+              )}
+          </FormItem>
+        </Form>
+        <div className="steps-action">
+          <Button type="primary" onClick={() => this.next()}>保存,下一步</Button>
+          <Button style={{ marginLeft: 8 }} onClick={() => this.prev()}>上一步</Button>
+        </div>
+      </Spin>
+    )
+  },
+}));
+
+export default EvaluateStep6;

+ 140 - 0
js/component/account/evaluate/steps/step7.jsx

@@ -0,0 +1,140 @@
+import React from 'react';
+import { Spin, Form, Button, Select } from 'antd';
+import ajax from 'jquery/src/ajax/xhr.js'
+import $ from 'jquery/src/ajax';
+import { political, technical, market, capital, management } from './dict.js';
+
+const FormItem = Form.Item;
+const Option = Select.Option;
+
+const formItemLayout = {
+  labelCol: { span: 4 },
+  wrapperCol: { span: 10 },
+};
+
+const EvaluateStep7 = Form.create({})(React.createClass({
+  getInitialState() {
+    return {
+      loading: false,
+      initialData: {}
+    };
+  },
+  componentWillMount() {
+    this.state.initialData = this.props.data || {};
+  },
+  next() {
+    if (this.state.loading) {
+      return;
+    }
+    this.props.form.validateFields((err, values) => {
+      if (!err) {
+        this.setState({
+          loading: true
+        })
+        values.id = this.props.id;
+        $.ajax({
+          url: globalConfig.context + '/api/user/evaluate/step7',
+          method: 'post',
+          data: values
+        }).done(function (res) {
+          if (res.error && res.error.length) {
+            message.error(res.error[0].message)
+          } else {
+            if (this.props.next) {
+              this.props.next(values);
+            }
+          }
+        }.bind(this)).fail(function () {
+          this.setState({
+            loading: false
+          })
+        }.bind(this));
+      }
+    });
+  },
+  prev() {
+    if (this.props.prev) {
+      this.props.prev();
+    }
+  },
+  stringify(val) {
+    return val && String(val)
+  },
+  render() {
+    let { loading, initialData } = this.state;
+    const { getFieldDecorator } = this.props.form;
+    return (
+      <Spin spinning={loading}>
+        <div style={{ marginBottom: 10 }}>项目整体获利情况受政策、技术、市场、资金、管理等影响。</div>
+        <Form className="steps-form">
+          <FormItem label="政策风险" {...formItemLayout}>
+            {getFieldDecorator('political', {
+              rules: [{ required: true, message: '请选择政策风险!' }],
+              initialValue: this.stringify(initialData.political)
+            })(
+              <Select placeholder="请选择政策风险">
+                {political.map((it) => {
+                  return <Option key={it.id} value={it.id}>{it.text}</Option>
+                })}
+              </Select>
+              )}
+          </FormItem>
+          <FormItem label="技术风险" {...formItemLayout}>
+            {getFieldDecorator('technical', {
+              rules: [{ required: true, message: '请选择技术风险!' }],
+              initialValue: this.stringify(initialData.technical)
+            })(
+              <Select placeholder="请选择技术风险">
+                {technical.map((it) => {
+                  return <Option key={it.id} value={it.id}>{it.text}</Option>
+                })}
+              </Select>
+              )}
+          </FormItem>
+          <FormItem label="市场风险" {...formItemLayout}>
+            {getFieldDecorator('market', {
+              rules: [{ required: true, message: '请选择市场风险!' }],
+              initialValue: this.stringify(initialData.market)
+            })(
+              <Select placeholder="请选择市场风险">
+                {market.map((it) => {
+                  return <Option key={it.id} value={it.id}>{it.text}</Option>
+                })}
+              </Select>
+              )}
+          </FormItem>
+          <FormItem label="资金风险" {...formItemLayout}>
+            {getFieldDecorator('capital', {
+              rules: [{ required: true, message: '请选择资金风险!' }],
+              initialValue: this.stringify(initialData.capital)
+            })(
+              <Select placeholder="请选择资金风险">
+                {capital.map((it) => {
+                  return <Option key={it.id} value={it.id}>{it.text}</Option>
+                })}
+              </Select>
+              )}
+          </FormItem>
+          <FormItem label="管理风险" {...formItemLayout}>
+            {getFieldDecorator('management', {
+              rules: [{ required: true, message: '请选择管理风险!' }],
+              initialValue: this.stringify(initialData.management)
+            })(
+              <Select placeholder="请选择管理风险">
+                {management.map((it) => {
+                  return <Option key={it.id} value={it.id}>{it.text}</Option>
+                })}
+              </Select>
+              )}
+          </FormItem>
+        </Form>
+        <div className="steps-action">
+          <Button type="primary" onClick={() => this.next()}>保存,下一步</Button>
+          <Button style={{ marginLeft: 8 }} onClick={() => this.prev()}>上一步</Button>
+        </div>
+      </Spin>
+    )
+  },
+}));
+
+export default EvaluateStep7;

+ 358 - 0
js/component/account/evaluate/steps/step8.jsx

@@ -0,0 +1,358 @@
+import React from 'react';
+import { Spin, Form, Button, message, Table } from 'antd';
+import ajax from 'jquery/src/ajax/xhr.js'
+import $ from 'jquery/src/ajax';
+import dict from './dict.js';
+import money from '@/money.js';
+
+const FormItem = Form.Item;
+
+const formItemLayout = {
+  labelCol: { span: 4 },
+  wrapperCol: { span: 10 },
+};
+
+const NUMBERS = {
+  1: '第一年',
+  2: '第二年',
+  3: '第三年',
+  4: '第四年',
+  5: '第五年',
+}
+
+const getText = (map, key, field) => {
+  if (field) {
+    return map[key] ? (map[key][field || 'text'] || '') : key;
+  }
+  return map[key] ? map[key] : key;
+}
+
+const EvaluateStep8 = Form.create({})(React.createClass({
+  getInitialState() {
+    return {
+      loading: true,
+      record: {},
+      industries: {},
+      subIndustries: {},
+      districts: {},
+      value: 0,
+      recommends: []
+    };
+  },
+  componentWillMount() {
+    let record = this.props.record || {}, dictMap = {};
+    if (record[0] && record[0].industry) {
+      this.loadData(record[0].industry);
+    } else {
+      this.state.loading = false;
+    }
+    this.state.record = record;
+    this.state.value = this.props.value || 0;
+    for (let key in dict) {
+      if (dict.hasOwnProperty(key) && key != 'toMap') {
+        dictMap[key] = dict.toMap(dict[key]);
+      }
+    }
+    this.state.dictMap = dictMap;
+  },
+  loadData(pid) {
+    $.when($.ajax({
+      url: globalConfig.context + '/open/findIndustryCategory'
+    }), $.ajax({
+      url: globalConfig.context + '/open/findIndustryCategory',
+      data: { id: pid }
+    }), $.ajax({
+      url: globalConfig.context + '/open/findDistrict'
+    }), $.ajax({
+      url: globalConfig.context + '/api/user/evaluate/step5/' + this.props.id
+    })).done(function (industryRes, subIndustryRes, districtRes, recommendRes) {
+      let i = {}, si = {}, d = { 0: "全国" }, r = [];
+      if (industryRes[0] && industryRes[0].data) {
+        industryRes[0].data.forEach(it => {
+          i[String(it.id)] = it;
+        })
+      }
+      if (subIndustryRes[0] && subIndustryRes[0].data) {
+        subIndustryRes[0].data.forEach(it => {
+          si[String(it.id)] = it;
+        })
+      }
+      if (districtRes[0] && districtRes[0].data) {
+        districtRes[0].data.forEach(it => {
+          d[String(it.id)] = it.name;
+        })
+      }
+      if (recommendRes[0] && recommendRes[0].data) {
+        r = recommendRes[0].data;
+      }
+      this.setState({
+        loading: false,
+        industries: i,
+        subIndustries: si,
+        districts: d,
+        recommends: r
+      })
+    }.bind(this)).fail(function () {
+      this.setState({
+        loading: false
+      })
+    }.bind(this));
+  },
+  next() {
+    if (this.props.next) {
+      this.props.next();
+    }
+  },
+  prev() {
+    if (this.props.prev) {
+      this.props.prev();
+    }
+  },
+  step1Col() {
+    return [{ dataIndex: 'key', key: 'key', width: '40%', className: 'steps-cell-key' }, { dataIndex: 'text', key: 'text', width: '60%' }]
+  },
+  step4Col() {
+    return [{
+      title: '年份', dataIndex: 'year', key: 'year'
+    }, {
+      title: '营收', dataIndex: 'income', key: 'income', render: (text) => { return money(text || 0) + '元' }
+    }, {
+      title: '利润率', dataIndex: 'profit', key: 'profit', render: (text) => { return (text || 0) + '%' }
+    }]
+  },
+  step5Col() {
+    const step = this.state.record[4];
+    let cols = [{
+      title: '年份', dataIndex: 'key', key: 'key', render: (text) => { return NUMBERS[text + 1] }
+    }]
+    switch (step.type) {
+      case "2":
+        cols.push({ title: '市场规模', dataIndex: 'marketScale', key: 'marketScale', render: (text) => { return money(text || 0) + '元' } });
+        cols.push({ title: '技术覆盖率/市场份额', dataIndex: 'marketRate', key: 'marketRate', render: (text) => { return (text || 0) + '%' } });
+        break;
+      case "3":
+        cols.push({ title: '单价', dataIndex: 'unitPrice', key: 'unitPrice', render: (text) => { return money(text || 0) + '元' } });
+        cols.push({ title: '销量', dataIndex: 'saleCount', key: 'saleCount' });
+        break;
+    }
+    cols.push({ title: '营业收入', dataIndex: 'income', key: 'income', render: (text) => { return money(text || 0) + '元' } });
+    if(this.state.record[3].hasIncome=='2') {
+      cols.push({ title: '建议值', dataIndex: 'recommend', key: 'recommend', render: (text) => { return money(text || 0) + '元' } });
+    }
+    return cols;
+  },
+  step1Data() {
+    const step = this.state.record[0], { industries, subIndustries, districts } = this.state;
+    const { transferTypes, leftTimes } = this.state.dictMap;
+    return step ? [{
+      key: "技术名称",
+      text: step.name
+    }, {
+      key: "所属主行业",
+      text: getText(industries, String(step.industry), 'name')
+    }, {
+      key: "所属子行业",
+      text: step.subIndustry.split(',').map(it => {
+        return getText(subIndustries, it, 'name');
+      }).join(',')
+    }, {
+      key: "转让方式",
+      text: getText(transferTypes, String(step.transferType))
+    }, {
+      key: "预估技术剩余寿命",
+      text: getText(leftTimes, String(step.timeLeft))
+    }, {
+      key: "转让区域",
+      text: step.transferArea.split(',').map(it => {
+        return districts[it] || it;
+      }).join(',')
+    }, {
+      key: "评估基准日",
+      text: step.benchmarkDate
+    }, {
+      key: "评估币种",
+      text: step.currencyType
+    }] : []
+  },
+  step2Data() {
+    const step = this.state.record[1];
+    const { accessMethods, legalStatus, maintenanceStatus, confidentialities, decidabilities, rightLimitations } = this.state.dictMap;
+    return step ? [{
+      key: "取得方式",
+      text: getText(accessMethods, String(step.accessMethod))
+    }, {
+      key: "法律状态",
+      text: getText(legalStatus, String(step.legalStatus))
+    }, {
+      key: "专利维护",
+      text: getText(maintenanceStatus, String(step.patentMaintenance))
+    }, {
+      key: "保密性",
+      text: getText(confidentialities, String(step.confidentiality))
+    }, {
+      key: "他人侵权的易判定性",
+      text: getText(decidabilities, String(step.decidability))
+    }, {
+      key: "是否涉及质押、担保、诉讼等权利限制",
+      text: getText(rightLimitations, String(step.hasRightLimitation))
+    }] : []
+  },
+  step3Data() {
+    const step = this.state.record[2];
+    const { progressiveness, innovativeness, ripeness, alternatives,
+      defensive, prospect, supplyAndDemand, rangeOfApplication, imitable, profitability } = this.state.dictMap;
+    return step ? [{
+      key: "先进性",
+      text: getText(progressiveness, String(step.progressiveness))
+    }, {
+      key: "创新性",
+      text: getText(innovativeness, String(step.innovativeness))
+    }, {
+      key: "成熟度",
+      text: getText(ripeness, String(step.ripeness))
+    }, {
+      key: "替代性",
+      text: getText(alternatives, String(step.alternatives))
+    }, {
+      key: "技术防御力",
+      text: getText(defensive, String(step.defensive))
+    }, {
+      key: "技术领域发展前景",
+      text: getText(prospect, String(step.prospect))
+    }, {
+      key: "供求关系",
+      text: getText(supplyAndDemand, String(step.supplyAndDemand))
+    }, {
+      key: "产品应用范围",
+      text: getText(rangeOfApplication, String(step.rangeOfApplication))
+    }, {
+      key: "遭他人模仿可能性",
+      text: getText(imitable, String(step.imitable))
+    }, {
+      key: "独立获利能力",
+      text: getText(profitability, String(step.profitability))
+    }] : []
+  },
+  step4Data() {
+    const step = this.state.record[3];
+    return step.hasIncome == 2 && step.incomes || []
+  },
+  step5Data() {
+    const step = this.state.record[4], { recommends } = this.state;
+    let res = [];
+    if (step.forecastIncomes) {
+      step.forecastIncomes.forEach((it, idx) => {
+        res.push(Object.assign({}, it, {
+          key: idx,
+          recommend: recommends[idx]
+        }))
+      })
+    }
+    return res
+  },
+  step6Data() {
+    const step = this.state.record[5];
+    return step ? [{
+      key: "企业所得税率预估",
+      text: step.taxRate + '%'
+    }] : []
+  },
+  step7Data() {
+    const step = this.state.record[6];
+    const { political, technical, market, capital, management } = this.state.dictMap;
+    return step ? [{
+      key: "政策风险",
+      text: getText(political, String(step.political))
+    }, {
+      key: "技术风险",
+      text: getText(technical, String(step.technical))
+    }, {
+      key: "市场风险",
+      text: getText(market, String(step.market))
+    }, {
+      key: "资金风险",
+      text: getText(capital, String(step.capital))
+    }, {
+      key: "管理风险",
+      text: getText(management, String(step.management))
+    }] : []
+  },
+  step5Title() {
+    const step = this.state.record[4];
+    let title = "收入直接预估"
+    switch (step.type) {
+      case "2":
+        title = "市场占比预估"
+        break;
+      case "3":
+        title = "产品开发预估"
+        break;
+    }
+    return title;
+  },
+  calc() {
+    if(this.state.loading) {
+      return;
+    }
+    this.setState({
+      loading: true
+    })
+    $.ajax({
+      url: globalConfig.context + '/api/user/evaluate/calc/' + this.props.id
+    }).done(function (res) {
+      let val = res && res.data || 0;
+      this.setState({
+        value: val,
+        loading: false
+      })
+      if (this.props.next) {
+        this.props.next(val)
+      }
+    }.bind(this)).fail(function () {
+      this.setState({
+        loading: false
+      })
+    }.bind(this));
+  },
+  render() {
+    let { loading, record, value } = this.state;
+    const tableProps = {
+      showHeader: false,
+      pagination: false,
+      size: 'middle'
+    }
+    return (
+      <Spin spinning={loading}>
+        <div className="steps-result">
+          <div className="steps-name">基本信息</div>
+          <Table {...tableProps} columns={this.step1Col()} dataSource={this.step1Data()}></Table>
+          <div className="steps-name">法律状况评估</div>
+          <Table {...tableProps} columns={this.step1Col()} dataSource={this.step2Data()}></Table>
+          <div className="steps-name">技术状况评估</div>
+          <Table {...tableProps} columns={this.step1Col()} dataSource={this.step3Data()}></Table>
+          <div className="steps-name">历史收入</div>
+          <Table columns={this.step4Col()} dataSource={this.step4Data()} locale={{ emptyText: "无历史收入" }} rowKey="year" pagination={false} size="middle"></Table>
+          <div className="steps-name">收入预估</div>
+          <Table columns={this.step5Col()} dataSource={this.step5Data()} pagination={false} size="middle" showHeader={true} title={this.step5Title}></Table>
+          <div className="steps-name">所得税预估</div>
+          <Table {...tableProps} columns={this.step1Col()} dataSource={this.step6Data()}></Table>
+          <div className="steps-name">风险预估</div>
+          <Table {...tableProps} columns={this.step1Col()} dataSource={this.step7Data()}></Table>
+          {
+            value ? <div><div className="steps-name">价值评估结果:</div>
+              <div className="steps-value">{money(value)}元</div></div> : <div />
+          }
+        </div>
+        <div className="steps-action">
+          {
+            value ? <Button type="primary" onClick={() => window.open(globalConfig.context + '/user/account/evaluateInfo?id=' + this.props.id)}>查看评估报告</Button>
+              : <Button type="primary" onClick={this.calc}>确认表单,开始估值</Button>
+          }
+          <Button style={{ marginLeft: 8 }} onClick={() => this.prev()}>上一步</Button>
+        </div>
+      </Spin>
+    )
+  },
+}));
+
+export default EvaluateStep8;

+ 2 - 0
js/component/account/index/content.jsx

@@ -27,6 +27,7 @@ import ExpertX from "@/account/order/expertX";
 import ExpertS from "@/account/order/expertS";
 import AdviserX from "@/account/order/adviserX";
 import AdviserS from "@/account/order/adviserS";
+import Evaluate from "@/account/evaluate/index";
 
 import {hashHistory,Route,Router} from 'react-router';
 import {Layout} from 'antd';
@@ -65,6 +66,7 @@ export default class ContentRouter extends React.Component {
             <Route path="/expertS" component={ExpertS} />
             <Route path="/adviserX" component={AdviserX} />
             <Route path="/adviserS" component={AdviserS} />
+            <Route path="/evaluate" component={Evaluate} />
         </Router>
       </Content>
     )

+ 12 - 0
js/component/account/menu.jsx

@@ -41,6 +41,12 @@ module.exports = {
           children: [ { name: '业务项目管理', url: 'businessProject' }, ]
         },
         {
+          name: '我的科技评估',
+          url: 'sub8',
+          icon: 'bank',
+          children: [ { name: '科技评估管理', url: 'evaluate' }, ]
+        },
+        {
           name: '订单管理-我是服务商',
           url: 'sub6',
           icon: 'copy',
@@ -109,6 +115,12 @@ module.exports = {
           children: [ { name: '业务项目管理', url: 'businessProject' }, ]
         },
         {
+          name: '我的科技评估',
+          url: 'sub8',
+          icon: 'bank',
+          children: [ { name: '科技评估管理', url: 'evaluate' }, ]
+        },
+        {
           name: '订单管理-我是服务商',
           url: 'sub6',
           icon: 'copy',

+ 3 - 3
js/component/account/setAccount/unit.jsx

@@ -300,9 +300,9 @@ const Unit = React.createClass({
 				orgCode: this.state.orgCode,
 				businessScope: this.state.businessScope,
 				introduction: this.state.introduction,
-				companyLogoUrl: thecompanyLogoUrl != 0 ? thecompanyLogoUrl : '',
-				honorPicture: thequaliUrl != 0 ? thequaliUrl : '',
-				orgCodeUrl: theorgCodeUrl != 0 ? theorgCodeUrl : '',
+				companyLogoUrl: thecompanyLogoUrl.length != 0 ? thecompanyLogoUrl : '',
+				honorPicture: thequaliUrl.length != 0 ? thequaliUrl : '',
+				orgCodeUrl: theorgCodeUrl.length != 0 ? theorgCodeUrl : '',
 				auditStatus: this.state.auditStatus,
 				authentication:this.state.authentication,
 				type:this.state.type

+ 1 - 1
js/component/administration/banner/bannerForm.jsx

@@ -142,7 +142,7 @@ class BannerForm extends React.Component {
                         text:values.text,
                         forwardUrl:values.forwardUrl,
                         apiUrl:values.apiUrl,
-                        imgUrl:thePictureUrl,
+                        imgUrl:thePictureUrl.length?thePictureUrl:'',
                         deleteSign:false,
                         client:values.client
                     }

+ 2 - 2
js/component/administration/business/businessCategory.jsx

@@ -242,14 +242,14 @@ const BusinessCategory=Form.create()(React.createClass({
             dataList.id=this.state.id;
             dataList.name=this.state.name;
             dataList.summary=this.state.summary;
-            dataList.imgUrl=thePictureUrl;
+            dataList.imgUrl=thePictureUrl.length?thePictureUrl:'';
             dataList.module=this.state.moduleNumber?this.state.moduleNumber:'0';
             dataList.nextModule=this.state.modules;
         }else{
             dataList.id=this.state.id;
             dataList.name=this.state.name;
             dataList.summary=this.state.summary;
-            dataList.imgUrl=thePictureUrl;
+            dataList.imgUrl=thePictureUrl.length?thePictureUrl:'';
             dataList.oldSuperId=this.state.superId;
             dataList.superId=this.state.superNameId;
         }

+ 0 - 53
js/component/administration/business/businessLibrary.jsx

@@ -22,59 +22,6 @@ import { getGameState, splitUrl, getprovince ,getReleaseStateList
 } from '@/tools.js';
 import { releaseStateList } from '@/dataDic.js';
 
-//图片组件
-const PicturesWall = React.createClass({
-	getInitialState() {
-		return {
-			previewVisible: false,
-			previewImage: '',
-			fileList: []
-		};
-	},
-	handleCancel() {
-		this.setState({ previewVisible: false });
-	},
-	handlePreview(file) {
-		this.setState({
-			previewImage: file.url || file.thumbUrl,
-			previewVisible: true
-		});
-	},
-	handleChange(info) {
-		let fileList = info.fileList;
-		this.setState({ fileList });
-		this.props.fileList(fileList);
-	},
-	componentWillReceiveProps(nextProps) {
-		this.state.fileList = nextProps.pictureUrl;
-	},
-	render() {
-		const { previewVisible, previewImage, fileList } = this.state;
-		const uploadButton = (
-			<div>
-				<Icon type="plus" />
-				<div className="ant-upload-text">点击上传</div>
-			</div>
-		);
-		return (
-			<div style={{ display: 'inline-block' }}>
-				<Upload
-					action={globalConfig.context + '/api/admin/jtBusiness/project/uploadPicture'}
-					data={{ sign: 'jt_project_picture' }}
-					listType="picture-card"
-					fileList={fileList}
-					onPreview={this.handlePreview}
-					onChange={this.handleChange}
-				>
-					{fileList.length >= 1 ? null : uploadButton}
-				</Upload>
-				<Modal maskClosable={false} visible={previewVisible} footer={null} onCancel={this.handleCancel}>
-					<img alt="example" style={{ width: '100%' }} src={previewImage} />
-				</Modal>
-			</div>
-		);
-	}
-});
 //主体
 const BusinessProject = Form.create()(
 	React.createClass({

+ 0 - 53
js/component/administration/business/businessProject.jsx

@@ -20,59 +20,6 @@ import {
 } from 'antd';
 import { getGameState, splitUrl, getprovince } from '@/tools.js';
 
-//图片组件
-const PicturesWall = React.createClass({
-	getInitialState() {
-		return {
-			previewVisible: false,
-			previewImage: '',
-			fileList: []
-		};
-	},
-	handleCancel() {
-		this.setState({ previewVisible: false });
-	},
-	handlePreview(file) {
-		this.setState({
-			previewImage: file.url || file.thumbUrl,
-			previewVisible: true
-		});
-	},
-	handleChange(info) {
-		let fileList = info.fileList;
-		this.setState({ fileList });
-		this.props.fileList(fileList);
-	},
-	componentWillReceiveProps(nextProps) {
-		this.state.fileList = nextProps.pictureUrl;
-	},
-	render() {
-		const { previewVisible, previewImage, fileList } = this.state;
-		const uploadButton = (
-			<div>
-				<Icon type="plus" />
-				<div className="ant-upload-text">点击上传</div>
-			</div>
-		);
-		return (
-			<div style={{ display: 'inline-block' }}>
-				<Upload
-					action={globalConfig.context + '/api/admin/jtBusiness/project/uploadPicture'}
-					data={{ sign: 'jt_project_picture' }}
-					listType="picture-card"
-					fileList={fileList}
-					onPreview={this.handlePreview}
-					onChange={this.handleChange}
-				>
-					{fileList.length >= 1 ? null : uploadButton}
-				</Upload>
-				<Modal maskClosable={false} visible={previewVisible} footer={null} onCancel={this.handleCancel}>
-					<img alt="example" style={{ width: '100%' }} src={previewImage} />
-				</Modal>
-			</div>
-		);
-	}
-});
 //主体
 const BusinessProject = Form.create()(
 	React.createClass({

+ 1 - 1
js/component/administration/news/newForm.jsx

@@ -167,7 +167,7 @@ const NewDetailForm = Form.create()(React.createClass({
 						type:values.type,
 						title: values.title,
                         author: values.author,
-                        titleImg: thePictureUrl,
+                        titleImg: thePictureUrl.length?thePictureUrl:'',
 						content:this.state.edit,
 						hot:values.hot,
 						source:values.source,

+ 3 - 4
js/component/administration/policy/policyForm.jsx

@@ -146,7 +146,6 @@ const NewDetailForm = Form.create()(React.createClass({
                 thePictureUrl = picArr.join(",");
 			};
             if (!err) {
-				
 				let publishPages =(values.publishPages).join(',')
                 this.setState({
                     loading: true
@@ -161,7 +160,7 @@ const NewDetailForm = Form.create()(React.createClass({
 						type:0,
 						title: values.title,
                         author: values.author,
-                        titleImg: thePictureUrl,
+                        titleImg: thePictureUrl.length?thePictureUrl:'',
 						content:this.state.edit.content,
 						hot:values.hot,
 						source:values.source,
@@ -201,7 +200,7 @@ const NewDetailForm = Form.create()(React.createClass({
 			this.state.pictureUrl = [];
 			this.state.Province=undefined;
 			this.setState({
-				edit:{content:''},
+				edit:{content:'<p><br></p>'},
 				publishPages:['web_policy_main','app_policy_main']
 			})
         };
@@ -218,7 +217,7 @@ const NewDetailForm = Form.create()(React.createClass({
 				this.state.theData={};
 				this.state.Province=undefined;
 				this.setState({
-					edit:{content:''},
+					edit:{content:'<p><br></p>'},
 					publishPages:['web_policy_main','app_policy_main']
 				})
             };

+ 15 - 0
js/component/money.js

@@ -0,0 +1,15 @@
+function money(s, n) {
+  n = n || 0;
+  n = n >= 0 && n <= 5 ? n : 2;
+  s = parseFloat((s + '').replace(/[^\d\.-]/g, '')).toFixed(n) + '';
+  s = s.split('.');
+  let l = s[0].split('').reverse(),
+    r = s[1] || '',
+    t = '';
+  for (let i = 0; i < l.length; i++) {
+    t += l[i] + ((i + 1) % 3 == 0 && (i + 1) != l.length ? ',' : '');
+  }
+  return t.split('').reverse().join('') + (r ? ('.' + r) : r);
+}
+
+module.exports = money;

+ 12 - 0
js/user/account/assessment.js

@@ -0,0 +1,12 @@
+import React from 'react';
+import ReactDOM from 'react-dom';
+import 'css/base.less';
+
+import Content from '@/account/evaluate/info.jsx';
+
+ReactDOM.render(
+    <div className="wrap clearfix">
+        <Content />
+    </div>,
+    document.getElementById('root')
+)

+ 1 - 1
package.json

@@ -12,7 +12,7 @@
     "buildtest": "node bin/clean.js && webpack --progress --colors --env.deploy test",
     "buildstage": "node bin/clean.js && webpack --progress --colors --env.deploy stage",
     "pro": "node bin/clean.js && webpack --progress --colors --env.deploy prod",
-    "dev": "webpack-dev-server --port 80 --devtool eval --progress --colors --hot --content-base build --env.deploy dev --env.watch watch"
+    "dev": "webpack-dev-server --port 8088 --devtool eval --progress --colors --hot --content-base build --env.deploy dev --env.watch watch"
   },
   "repository": {
     "type": "git",

+ 9 - 3
webpack.config.js

@@ -85,6 +85,12 @@ module.exports = (function () {
             template: './template/template.html',
             chunks: ['user/account/index', 'vendors']
         }),
+        new HtmlWebpackPlugin({
+            title: '在线评估',
+            filename: 'user/account/evaluateInfo.html',
+            template: './template/template.html',
+            chunks: ['user/account/evaluateInfo', 'vendors']
+        }),
         //管理员模块
         new HtmlWebpackPlugin({
             title: '管理员-登录',
@@ -115,7 +121,7 @@ module.exports = (function () {
         }));
     }
 
-    let staticHost = 'http://192.168.0.188:80';    
+    let staticHost = 'http://192.168.0.188:8088';    
     switch (argv.env.deploy) {
         case 'test':
             staticHost = 'http://statics.jishutao.com';
@@ -142,7 +148,7 @@ module.exports = (function () {
         	alias:{
                 '@':__dirname+'/js/component',
                 'img':__dirname+'/image',
-                '@css':__dirname+'/css',
+                'css':__dirname+'/css',
                 'js':__dirname+'/js'
             },
             extensions: ['.js', '.jsx']
@@ -151,7 +157,7 @@ module.exports = (function () {
         devServer: {
             disableHostCheck: true,
             host: '192.168.0.188',
-            port: 80,
+            port: 8088,
             allowedHosts: ['127.0.0.1','192.168.0.20','192.168.0.99'],
             headers: {
                 "Access-Control-Allow-Origin": "*"

+ 11 - 6
webpack/entry.config.js

@@ -5,33 +5,38 @@ module.exports = {
     'user/login': './js/user/login.js',
     'user/signIn': './js/user/signIn.js',
     'user/account/index': './js/user/account/index.js',
+    'user/account/evaluateInfo': './js/user/account/assessment.js',
     //admin
     'admin/login': './js/user/adminLogin.js',
     'admin/index': './js/admin/index.js',
   },
   watch: {
-    'user/index': ['webpack-dev-server/client?http://192.168.0.188:80', // WebpackDevServer host and port
+    'user/index': ['webpack-dev-server/client?http://192.168.0.188:8088', // WebpackDevServer host and port
       'webpack/hot/only-dev-server',
       './js/user/index.js'
     ],
-    'user/login': ['webpack-dev-server/client?http://192.168.0.188:80', // WebpackDevServer host and port
+    'user/login': ['webpack-dev-server/client?http://192.168.0.188:8088', // WebpackDevServer host and port
       'webpack/hot/only-dev-server',
       './js/user/login.js'
     ],
-    'user/signIn': ['webpack-dev-server/client?http://192.168.0.188:80', // WebpackDevServer host and port
+    'user/signIn': ['webpack-dev-server/client?http://192.168.0.188:8088', // WebpackDevServer host and port
       'webpack/hot/only-dev-server',
       './js/user/signIn.js'
     ],
-    'user/account/index': ['webpack-dev-server/client?http://192.168.0.188:80', // WebpackDevServer host and port
+    'user/account/index': ['webpack-dev-server/client?http://192.168.0.188:8088', // WebpackDevServer host and port
       'webpack/hot/only-dev-server',
       './js/user/account/index.js'
     ],
+    'user/account/evaluateInfo': ['webpack-dev-server/client?http://192.168.0.188:8088', // WebpackDevServer host and port
+      'webpack/hot/only-dev-server',
+      './js/user/account/assessment.js'
+    ],
     //admin
-    'admin/login': ['webpack-dev-server/client?http://192.168.0.188:80', // WebpackDevServer host and port
+    'admin/login': ['webpack-dev-server/client?http://192.168.0.188:8088', // WebpackDevServer host and port
     'webpack/hot/only-dev-server',
     './js/user/adminLogin.js'
     ],
-    'admin/index': ['webpack-dev-server/client?http://192.168.0.188:80', // WebpackDevServer host and port
+    'admin/index': ['webpack-dev-server/client?http://192.168.0.188:8088', // WebpackDevServer host and port
       'webpack/hot/only-dev-server',
       './js/admin/index.js'
     ]