Commit 944654c1 authored by jiaxu.yan's avatar jiaxu.yan

Merge branch 'developer/yanjiaxu' into develop

# Conflicts:
#	README.md
parents 6c1595ff cd436e41
## 开发
```bash
# 克隆项目
git clone https://gitee.com/y_project/RuoYi-Vue
# 进入项目目录
cd ruoyi-ui
# 安装依赖
npm install
# 建议不要直接使用 cnpm 安装依赖,会有各种诡异的 bug。可以通过如下操作解决 npm 下载速度慢的问题
npm install --registry=https://registry.npmmirror.com
# 启动服务
npm run dev
# 代码风格确定
## 组件化
如果我们将一个页面中所有的处理逻辑全部放在一起,处理起来就会变得非常复杂,而且不利于后续的管理以及扩展。
但如果,我们将一个页面拆分成一个个小的功能块,每个功能块完成属于自己这部分独立的功能,那么之后整个页面的管理和维护就变得非常容易。
​它提供了一种抽象,让我们可以开发出一个个独立可复用的小组件来构造我们的应用。
任何的应用都会被抽象成一颗组件树。
组件化思想的应用:
​有了组件化的思想,我们在之后的开发中就要充分
尽可能的将页面拆分成一个个小的、可复用的组件
这样让我们的代码更加方便组织和管理,并且扩展性也更强
### 具体实现
对每个子页面进行拆分,并在主页面进行引用,个个子组件只完成当前子页面的功能,主页面负责衔接个个子组件,
## 逻辑函数化
对一个功能的实现,往往要有多个函数。而这些函数全部放在一个方法里会降低代码的可读性,项目会显得臃肿,某些地方会造成强耦合形成屎山
造成后续维护只能添加逻辑,原先的逻辑没人能维护的尴尬状况
### 函数柯里化
柯里化(Currying)是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数且返回结果的新函数的技术。这个技术以逻辑学家 Haskell Curry 命名的
什么意思?简单来说,柯里化是一项技术,它用来改造多参数的函数。比如:
```javascript
// 这是一个接受3个参数的函数
const add = function(x, y, z) {
return x + y + z
}
```
我们将它变换一下,可以得到这样一个函数:
```javascript
// 接收一个单一参数
const curryingAdd = function(x) {
// 并且返回接受余下的参数的函数
return function(y, z) {
return x + y + z
}
}
```
这样有什么区别呢?从调用上来对比:
```javascript
// 调用add
add(1, 2, 3)
浏览器访问 http://localhost:80
// 调用curryingAdd
curryingAdd(1)(2, 3)
// 看得更清楚一点,等价于下面
const fn = curryingAdd(1)
fn(2, 3)
```
可以看到,变换后的的函数可以分批次接受参数,先记住这一点,下面会讲用处。甚至fn(curryingAdd返回的函数)还可以继续变换:
```javascript
const curryingAdd = function(x) {
return function(y) {
return function(z) {
return x + y + z
}
}
}
```
// 调用
```javascript
curryingAdd(1)(2)(3)
// 即
const fn = curryingAdd(1)
const fn1 = fn(2)
fn1(3)
```
上面的两次变换过程,就是函数柯里化
### 函数复用
若是项目的组件中有多处地方采用同一种方式进行处理,例如处理如期格式化,校验规则,文件上传之类我们可以将这些复用较高的代码进行抽象
### 具体实现
我们可以在 src/utils 文件夹下收集这种可以重复使用的函数。根据其性质或者功能点进行归类,总结出自己的工具库
这是对后续项目大有帮助的
对已有公用组件的一些说明
### 列表页面函数集合组件
mixins/page.js
对列表页面的查询和加载,分页进行了一定程度的封装
在页面中通过
```javascript
import page from '@/mixins/page'
export default {
...
mixins: [page],
...
}
```
#### 参数说明
```javascript
listUrl: '',
//列表接口地址
queryParams: {
//接口所需参数
pageNum: 1,
//当前的页数
pageSize: 10
//分页的页数
},
tableId: false,
loading: false,
//是否显示加载
showSearch: true,
// 显示搜索条件
refreshTable: true,
// 重新渲染表格状态
tableData: [],
// 返回数据
total: 0
// 返回数据总条数
```
#### 方法介绍
```javascript
// 重制参数
resetQuery() {
},
//根据参数加载
handleQuery() {
},
//加载数据
loadData() {
}
## 发布
```
### 根据resful 规范衍生的对单一数据增删改查组件
```bash
# 构建测试环境
npm run build:stage
在页面中调用
```javascript
data() {
return {
...
model: this.$modelDataSource({
url: '/system/enterprise',//接口根地址
dataKey: 'model',
attributes: { //你需要获取的参数
id: ''
}
})
...
}
}
# 构建生产环境
npm run build:prod
```
```javascript
this.model.reset() //重置
this.model.fetch( // 根据id获取单条数据
newValue,
{}, //其他参数
(success) => { //成功回调
},
(err) => { //失败回调
}
)
```
\ No newline at end of file
import request from '@/utils/request'
/**
* 创建场景变更任务
* @param {} data
* @returns
*/
export function createScene(data) {
return request({
url: '/review/scene/change/task/create',
method: 'post',
data
})
}
import request from '@/utils/request'
// 获取任务详情
export function taskDetail(data) {
return request({
url: '/system/review/task/view',
method: 'post',
data
})
}
/**
* 细则提交
* @param {*} data
* @returns
*/
export function reviewDetailsSubmit(data) {
return request({
url: '/review/details/result/save',
method: 'post',
data
})
}
// 提交审查问卷
export function taskSubmit(data) {
return request({
url: '/system/review/task/submit',
method: 'post',
data
})
}
\ No newline at end of file
......@@ -6,7 +6,7 @@
<!--1-抬头标题-->
<div class="title-style">
<div class="title-content-style">
确认审查结果(所属任务: 广汽丰田体系审查)
确认审查结果(所属任务{{ model.systemReviewTask.name }})
</div>
<div class="title-content-style">
<el-button type="text" @click="goToProcessedReview">返回</el-button>
......@@ -19,17 +19,17 @@
<el-row :gutter="60">
<el-col :span="8">
<el-form-item label="任务编号:">
<span>IATF17889</span>
<span>{{ model.systemReviewTask.taskNo }}</span>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="任务名称:">
<span>iso三体系审核</span>
<span>{{ model.systemReviewTask.name }}</span>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="委托单位:">
<span>广汽丰田有限公司</span>
<span>{{ model.systemReviewTask.taskInitiatorDept }}</span>
</el-form-item>
</el-col>
</el-row>
......@@ -121,8 +121,10 @@
</thead>
<tbody>
<!-- 循环遍历 arr -->
<template v-for="(item, index) in questionnaireSummary">
<tr :key="index">
<template
v-for="(item, index) in model.systemReviewTask.standard"
>
<tr :key="'standard-1' + index">
<td align="center" :rowspan="getRows2(item)">
{{ item.chapter }}
</td>
......@@ -132,7 +134,7 @@
</tr>
<!-- 循环遍历 keyPointList -->
<template v-for="(i, PointIndex) in item.keyPointList">
<tr :key="PointIndex">
<tr :key="'PointIndex-2' + PointIndex + index">
<td align="center" :rowspan="getRows(i)">
{{ i.text }}
</td>
......@@ -141,7 +143,14 @@
<template
v-for="(v, reviewDetailIndex) in i.reviewDetailsList"
>
<tr :key="reviewDetailIndex">
<tr
:key="
'reviewDetailIndex-3' +
PointIndex +
reviewDetailIndex +
index
"
>
<td
align="center"
:rowspan="v.reviewSceneList.length + 1"
......@@ -153,10 +162,36 @@
<template
v-for="(s, reviewSceneIndex) in v.reviewSceneList"
>
<tr :key="reviewSceneIndex">
<tr
:key="
'reviewSceneIndex-4' +
PointIndex +
reviewDetailIndex +
index +
reviewSceneIndex
"
>
<td align="center">{{ s.text }}</td>
<td align="center">{{ s.result }}</td>
<td align="center">{{ s.people }}</td>
<td align="center">
{{
v.result
? v.result.passed === null
? '__'
: v.result.passed === 0
? '不通过'
: '通过'
: '__'
}}
</td>
<td align="center">
{{
v.result
? v.result.userName
? v.result.userName
: '__'
: '__'
}}
</td>
</tr>
</template>
</template>
......@@ -172,7 +207,7 @@
<span class="title-content">签字确认</span>
</div>
<el-form
ref="ruleForm"
ref="form"
:model="ruleForm"
:rules="rules"
class="img-display"
......@@ -225,276 +260,16 @@
</template>
<!--js逻辑-->
<script>
import { taskDetail, taskSubmit } from '@/api/task/task'
export default {
data() {
return {
isShow: true,
questionnaireSummary: [
{
id: 1734848009319092224,
chapter: '5.1',
text: '标准要求-车辆制造商应具备车辆全生命周期的汽车信息安全管理体系。注:车辆全生命周期包括车辆的开发阶段、生产阶段及后生产阶段。',
keyPointList: [
{
id: 1734848009323286528,
text: '审查要点-车辆制造商是否建立汽车信息安全管理制度。',
reviewStandardId: 1734848009319092224,
reviewDetailsList: [
{
id: 1734848009323286529,
text: '审查细则-车辆制造商是否能够提供/展示汽车信息安全管理制度正式发布的证明材料。',
reviewKeypointId: 1734848009323286528,
reviewSceneList: [
{
id: 1734848009323286530,
text: '符合场景-1.管理制度发布会红头文件',
result: '合格',
people: '小明',
reviewDetailsId: 1734848009323286529
},
{
id: 1734848010472525824,
text: '2.管理制度正式发布会议纪要',
result: '不合格',
people: '小三',
reviewDetailsId: 1734848009323286529
},
{
id: 1734848010719989760,
text: '3.专用系统正式发布流程或记录',
result: '合格',
people: '小明',
reviewDetailsId: 1734848009323286529
}
]
}
]
}
]
},
{
id: 1734848011609182208,
chapter: '5.2',
text: '汽车信息安全管理体系应包括以下内容。建立企业内部管理汽车信息安全的过程。',
keyPointList: [
{
id: 1734848011609182209,
text: '车辆制造商汽车信息安全管理制度是否建立并明确汽车信息安全管理制度的组织架构及权责。',
reviewStandardId: 1734848011609182208,
reviewDetailsList: [
{
id: 1734848011609182210,
text: '车辆制造商汽车信息安全管理制度的角色应覆盖车辆/车辆产品在生命周期中的信息安全活动。',
reviewKeypointId: 1734848011609182209,
reviewSceneList: [
{
id: 1734848011609182211,
text: '1.汽车信息安全管理制度或其配套的流程文件中包含流程图,定义了信息安全活动及对应的角色,并有角色的权责定义。',
reviewDetailsId: 1734848011609182210,
result: '合格',
people: '小明'
}
]
},
{
id: 1734848012057972736,
text: '车辆制造商汽车信息安全管理制度的角色应与车辆制造商的组织架构匹配。',
reviewKeypointId: 1734848011609182209,
reviewSceneList: [
{
id: 1734848012057972737,
text: '1.汽车信息安全管理制度中定义的角色与车辆制造商的组织架构岗位名称一致。',
reviewDetailsId: 1734848012057972736,
result: '合格',
people: '小明'
},
{
id: 1734848012225744896,
text: '2.汽车信息安全管理制度中定义的角色与车辆制造商的组织架构岗位有映射关系。',
reviewDetailsId: 1734848012057972736,
result: '不合格',
people: '小明'
}
]
}
]
},
{
id: 1734848012976525312,
text: '车辆制造商汽车信息安全管理制度是否明确为保障汽车信息安全需求实现和维持所投入的资源。',
reviewStandardId: 1734848011609182208,
reviewDetailsList: [
{
id: 1734848012976525313,
text: '车辆制造商应提供在信息安全方面提供资源支持的证明材料,包括投入的场地、基础软硬件设备、技术人员和资金等。',
reviewKeypointId: 1734848012976525312,
reviewSceneList: [
{
id: 1734848012976525314,
text: '1.典型的资源要求为人力投入,例如负责网络安全风险管理的人员、研发人员和事件管理响应人员。',
reviewDetailsId: 1734848012976525313,
result: '合格',
people: '小明'
}
]
}
]
},
{
id: 1734848013714722816,
text: '车辆制造商汽车信息安全管理制度是否明确与其它管理流程(如QMS、ISMS)的适配性。',
reviewStandardId: 1734848011609182208,
reviewDetailsList: [
{
id: 1734848013714722817,
text: '车辆制造商应提供信息安全管理制度在建设实施中与企业其他管理流程相适配的证明材料。',
reviewKeypointId: 1734848013714722816,
reviewSceneList: [
{
id: 1734848013714722818,
text: '1.明确信息安全管理要求融合到现有管理制度流程中,如在现有ISMS制度中增加汽车信息安全管理要求。',
reviewDetailsId: 1734848013714722817,
result: '合格',
people: '小明'
},
{
id: 1734848013899272192,
text: '2.在信息安全管理制度中明确与其它管理流程的接口。',
reviewDetailsId: 1734848013714722817,
result: '不合格',
people: '小明'
}
]
}
]
}
]
}
],
dataList: [
{
id: 1734848009319092224,
chapter: '5.1',
text: '车辆制造商应具备车辆全生命周期的汽车信息安全管理体系。注:车辆全生命周期包括车辆的开发阶段、生产阶段及后生产阶段。',
keyPointList: [
{
id: 1734848009323286528,
text: '车辆制造商是否建立汽车信息安全管理制度。',
reviewStandardId: 1734848009319092224,
reviewDetailsList: [
{
id: 1734848009323286529,
text: '车辆制造商是否能够提供/展示汽车信息安全管理制度正式发布的证明材料。',
reviewKeypointId: 1734848009323286528,
reviewSceneList: [
{
id: 1734848009323286530,
text: '1.管理制度发布会红头文件',
reviewDetailsId: 1734848009323286529
},
{
id: 1734848010472525824,
text: '2.管理制度正式发布会议纪要',
reviewDetailsId: 1734848009323286529
},
{
id: 1734848010719989760,
text: '3.专用系统正式发布流程或记录',
reviewDetailsId: 1734848009323286529
}
]
}
]
}
]
},
{
id: 1734848011609182208,
chapter: '5.2',
text: '汽车信息安全管理体系应包括以下内容。建立企业内部管理汽车信息安全的过程。',
keyPointList: [
{
id: 1734848011609182209,
text: '车辆制造商汽车信息安全管理制度是否建立并明确汽车信息安全管理制度的组织架构及权责。',
reviewStandardId: 1734848011609182208,
reviewDetailsList: [
{
id: 1734848011609182210,
text: '车辆制造商汽车信息安全管理制度的角色应覆盖车辆/车辆产品在生命周期中的信息安全活动。',
reviewKeypointId: 1734848011609182209,
reviewSceneList: [
{
id: 1734848011609182211,
text: '1.汽车信息安全管理制度或其配套的流程文件中包含流程图,定义了信息安全活动及对应的角色,并有角色的权责定义。',
reviewDetailsId: 1734848011609182210
}
]
},
{
id: 1734848012057972736,
text: '车辆制造商汽车信息安全管理制度的角色应与车辆制造商的组织架构匹配。',
reviewKeypointId: 1734848011609182209,
reviewSceneList: [
{
id: 1734848012057972737,
text: '1.汽车信息安全管理制度中定义的角色与车辆制造商的组织架构岗位名称一致。',
reviewDetailsId: 1734848012057972736
},
{
id: 1734848012225744896,
text: '2.汽车信息安全管理制度中定义的角色与车辆制造商的组织架构岗位有映射关系。',
reviewDetailsId: 1734848012057972736
}
]
}
]
},
{
id: 1734848012976525312,
text: '车辆制造商汽车信息安全管理制度是否明确为保障汽车信息安全需求实现和维持所投入的资源。',
reviewStandardId: 1734848011609182208,
reviewDetailsList: [
{
id: 1734848012976525313,
text: '车辆制造商应提供在信息安全方面提供资源支持的证明材料,包括投入的场地、基础软硬件设备、技术人员和资金等。',
reviewKeypointId: 1734848012976525312,
reviewSceneList: [
{
id: 1734848012976525314,
text: '1.典型的资源要求为人力投入,例如负责网络安全风险管理的人员、研发人员和事件管理响应人员。',
reviewDetailsId: 1734848012976525313
}
]
}
]
},
{
id: 1734848013714722816,
text: '车辆制造商汽车信息安全管理制度是否明确与其它管理流程(如QMS、ISMS)的适配性。',
reviewStandardId: 1734848011609182208,
reviewDetailsList: [
{
id: 1734848013714722817,
text: '车辆制造商应提供信息安全管理制度在建设实施中与企业其他管理流程相适配的证明材料。',
reviewKeypointId: 1734848013714722816,
reviewSceneList: [
{
id: 1734848013714722818,
text: '1.明确信息安全管理要求融合到现有管理制度流程中,如在现有ISMS制度中增加汽车信息安全管理要求。',
reviewDetailsId: 1734848013714722817
},
{
id: 1734848013899272192,
text: '2.在信息安全管理制度中明确与其它管理流程的接口。',
reviewDetailsId: 1734848013714722817
}
]
}
]
}
]
}
],
model: {
systemReviewTask: {},
reviewSceneChangeTasks: {},
detailsList: []
},
columns: [],
ruleForm: {
enterpriseLeader: '',
......@@ -508,136 +283,25 @@ export default {
{ required: true, message: '请输入检验负责人', trigger: 'blur' }
]
},
tableData: [
{
id: '12987122',
name: '王小虎',
amount1: '234',
amount2: '3.2',
amount3: 10
},
{
id: '12987123',
name: '王小虎',
amount1: '165',
amount2: '4.43',
amount3: 12
},
{
id: '12987124',
name: '王小虎',
amount1: '324',
amount2: '1.9',
amount3: 9
},
{
id: '12987125',
name: '王小虎',
amount1: '621',
amount2: '2.2',
amount3: 17
},
{
id: '12987126',
name: '王小虎',
amount1: '539',
amount2: '4.1',
amount3: 15
},
{
id: '12987123',
name: '王小虎',
amount1: '165',
amount2: '4.43',
amount3: 12
},
{
id: '12987124',
name: '王小虎',
amount1: '324',
amount2: '1.9',
amount3: 9
},
{
id: '12987125',
name: '王小虎',
amount1: '621',
amount2: '2.2',
amount3: 17
},
{
id: '12987126',
name: '王小虎',
amount1: '539',
amount2: '4.1',
amount3: 15
},
{
id: '12987123',
name: '王小虎',
amount1: '165',
amount2: '4.43',
amount3: 12
},
{
id: '12987124',
name: '王小虎',
amount1: '324',
amount2: '1.9',
amount3: 9
},
{
id: '12987125',
name: '王小虎',
amount1: '621',
amount2: '2.2',
amount3: 17
},
{
id: '12987126',
name: '王小虎',
amount1: '539',
amount2: '4.1',
amount3: 15
},
{
id: '12987123',
name: '王小虎',
amount1: '165',
amount2: '4.43',
amount3: 12
},
{
id: '12987124',
name: '王小虎',
amount1: '324',
amount2: '1.9',
amount3: 9
},
{
id: '12987125',
name: '王小虎',
amount1: '621',
amount2: '2.2',
amount3: 17
},
{
id: '12987126',
name: '王小虎',
amount1: '539',
amount2: '4.1',
amount3: 15
}
]
taskId: ''
}
},
created() {
if (this.dataList.length > 0) {
const firstItem = this.dataList[0]
this.columns = Object.keys(firstItem)
}
mounted() {
this.taskId = this.$route.query.id
this.getTask()
},
methods: {
getTask() {
taskDetail({
taskId: this.taskId
}).then(res => {
if (res.code === 200) {
this.model = res.data
} else {
this.$modal.msgError(res.msg)
}
})
},
getRowspan(arr) {
return arr.length > 0
? arr.reduce((acc, curr) => acc + curr.reviewDetailsList.length, 0)
......@@ -645,8 +309,18 @@ export default {
},
/* 返回跳转*/
goToProcessedReview() {
this.$modal.msgSuccess('确认提交成功')
this.$router.back()
this.$refs.form.validate(valid => {
if (valid) {
taskSubmit(this.form).then(res => {
if (res.code === 200) {
this.$modal.msgSuccess('确认提交成功')
this.$router.back()
} else {
this.$modal.msgError(res.msg)
}
})
}
})
},
getRows(i) {
let n = 0
......@@ -857,10 +531,10 @@ td {
height: 100%;
}
.bottom-btn {
position: absolute;
bottom: 20px; /* 调整按钮距离底部的距离 */
left: 50%; /* 将按钮水平居中 */
transform: translateX(-50%);
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 20px;
}
.tips {
......
......@@ -138,7 +138,7 @@ export default {
data() {
return {
pageType: '1',
listUrl: '/finishTasklist',
listUrl: '/system/review/task/findInFinish',
showSearch: true,
tableData: []
}
......
......@@ -70,26 +70,26 @@
开始时间
</div>
<div class="cell-value">
{{ item.startTime ? item.startTime : '---' }}
{{ item.taskBeginTime ? parseTime(item.taskBeginTime) : '---' }}
</div>
</div>
<div class="card-cell">
<div class="cell-lable">任务编号</div>
<div class="cell-value">
{{ item.missionNo ? item.missionNo : '---' }}
{{ item.taskNo ? item.taskNo : '---' }}
</div>
</div>
<div class="card-cell">
<div class="cell-lable">任务名称</div>
<div class="cell-value">
{{ item.tit ? item.tit : '---' }}
{{ item.name ? item.name : '---' }}
</div>
</div>
<div class="card-cell">
<div class="cell-lable">任务组长</div>
<div class="cell-value">
<i class="el-icon-user"></i>
{{ item.owener ? item.owener : '---' }}
{{ item.leader ? item.leader : '---' }}
</div>
</div>
<div v-if="!isSysReview" class="card-cell">
......@@ -154,9 +154,9 @@
</div>
<div v-if="isSysReview" class="card-cell">
<div class="cell-lable">任务状态</div>
<div v-if="item.costTime === 0" class="cell-value">● 未开始</div>
<div v-else class="cell-value yellow">
● 已耗时({{ item.costTime }}小时)
<div v-if="item.taskStatus === 'NEW'" class="cell-value">● 未开始</div>
<div v-if="item.taskStatus === 'PENDING'" class="cell-value yellow">
● 已耗时({{ getHourDiff(item.taskBeginTime) }}小时)
</div>
</div>
<div v-if="isSysReview" class="card-cell">
......@@ -165,16 +165,13 @@
<el-link
v-if="item.progress === 0"
type="primary"
@click="handleReviewForm"
@click="handleReviewForm(item.id)"
>查看检查表单</el-link
>
<el-link
v-else-if="item.progress < 90"
type="primary"
@click="handleReviewQuestionnaire"
>填写审查问卷</el-link
>
<el-link v-else type="primary" @click="handleConfirmFindings"
><br />
<el-link type="primary" @click="handleReviewQuestionnaire(item.id)"
>填写检查表单</el-link
><br />
<el-link type="primary" @click="handleConfirmFindings(item.id)"
>确认审查结果</el-link
>
</div>
......@@ -195,6 +192,7 @@
icon="el-icon-arrow-right"
circle
title="任务详情"
@click="goDetail(item.id)"
></el-button>
<el-button
type="warning"
......@@ -228,11 +226,12 @@
@click="handleFileLibrary(item)"
></el-button>
<el-button
v-if="item.progress === 0"
v-if="item.taskStatus === 'NEW'"
type="danger"
icon="el-icon-video-play"
circle
title="开始"
@click="startTask(item)"
></el-button>
</div>
</div>
......@@ -255,6 +254,7 @@
<script>
import page from '@/mixins/page'
import taskDialog from './components/dialog'
import request from '@/utils/request'
export default {
dicts: ['sys_job_status', 'sys_scene_type', 'task_type'],
components: { taskDialog },
......@@ -273,7 +273,7 @@ export default {
},
dialogVisible: false,
pageType: '1', // 代办任务类型 1-体系审查 其他-车型测评
listUrl: '/tasklist',
listUrl: '/system/review/task/findInProcess',
showSearch: true,
tableData: []
}
......@@ -307,6 +307,24 @@ export default {
path: '/processing/fileLibrary'
})
},
startTask(item) {
request({
url: '/system/review/task/start',
method: 'post',
data: {
taskId: item.id
}
}).then(res => {
console.log(res)
this.loadData()
})
},
goDetail(id) {
this.$router.push({
path: '/task/task-detail?id=' + id
})
},
closeDialog() {
this.dialogVisible = false
},
......@@ -320,9 +338,9 @@ export default {
path: '/processing/reviewReport'
})
},
handleReviewQuestionnaire() {
handleReviewQuestionnaire(id) {
this.$router.push({
path: '/processing/write-check-form'
path: '/processing/write-check-form?id=' + id
})
},
handleReviewForm() {
......@@ -337,9 +355,9 @@ export default {
path: '/processing/review-form'
})
},
handleConfirmFindings() {
handleConfirmFindings(id) {
this.$router.push({
path: '/processing/confirm-result'
path: '/processing/confirm-result?id=' + id
})
},
handleTaskContent(msg) {
......@@ -348,6 +366,19 @@ export default {
path: '/processing/vehicle-type'
})
}
},
getHourDiff(time) {
// 获取当前时间
var now = new Date()
// 设置目标时间(这里为2021年9月30日)
var targetTime = new Date(time) // 注意月份从0开始计数,所以8表示九月
// 计算时间差(单位为毫秒)
var timeDiff = Math.abs(targetTime - now)
// 将时间差转换成小时
return Math.floor(timeDiff / (60 * 60 * 1000))
}
}
}
......@@ -363,19 +394,24 @@ export default {
flex-wrap: nowrap;
min-width: 111px;
}
.status-multiple-cell {
width: 150px;
}
.option-cell {
width: 240px;
}
.box-card {
margin-bottom: 15px;
font-size: 14px;
::v-deep .el-card__body {
display: flex;
justify-content: space-between;
}
::v-deep .el-link.is-underline::after {
position: absolute;
right: 0;
......@@ -385,20 +421,25 @@ export default {
border-bottom: 1px solid #1890ff;
content: '';
}
.cell-progress {
width: 200px;
}
.cell-lable {
color: #515a6e;
font-size: 13px;
}
.cell-value {
font-size: 14px;
color: #606266;
}
.cell-value.yellow {
color: #fea623;
}
.cell-value.green {
color: #19be6b;
}
......
<template>
<el-dialog
title="新增场景对话框"
:visible.sync="dialogManger.dialogVisible"
width="35%"
append-to-body
:close-on-click-modal="false"
:close-on-press-escape="false"
:before-close="handleSceneClose"
>
<div class="file-prompt">
<div>
<i
class="el-icon-info"
/>新增场景,需要组织评审,评审通过后新增场景自动进入场景库。
</div>
</div>
<el-form
ref="sceneForm"
:model="sceneForm"
:rules="sceneRules"
label-width="80px"
class="scene-form"
>
<el-form-item label="评审类型" prop="reviewType">
<!-- 下拉框 -->
<el-select
v-model="sceneForm.reviewType"
placeholder="请选择评审类型"
style="width: 100%"
>
<el-option
v-for="item in reviewTypeOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="场景分类" prop="sceneClassification">
<el-select
v-model="sceneForm.sceneClassification"
placeholder="请选择评审类型"
style="width: 100%"
>
<el-option
v-for="item in reviewTypeOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="场景内容" prop="sceneContent">
<el-input
v-model="sceneForm.sceneContent"
maxlength="100"
show-word-limit
type="textarea"
/>
</el-form-item>
<el-form-item label="评审人员" prop="assessor">
<div>组长-xxx</div>
<div>组员-xxx、xxx、xxx</div>
</el-form-item>
<el-form-item label="备注信息" prop="remark">
<el-input
v-model="sceneForm.remark"
maxlength="100"
show-word-limit
type="textarea"
/>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="handleSceneClose()">取 消</el-button>
<el-button type="primary" @click="handleSaveNewScene()">
确 定
</el-button>
</span>
</el-dialog>
</template>
<script>
export default {
dicts: ['file_status'],
props: {
dialogManger: {
type: Object,
default() {
return {
dialogVisible: false
}
}
}
},
data() {
return {
sceneForm: {},
sceneRules: {
reviewType: [
{ required: true, message: '请选择评审类型', trigger: 'change' }
],
sceneClassification: [
{ required: true, message: '请选择场景分类', trigger: 'change' }
],
sceneContent: [
{ required: true, message: '请输入场景内容', trigger: 'blur' }
]
},
reviewTypeOptions: []
}
},
methods: {
// 新增场景对话框关闭时触发的回调函数
handleSceneClose() {
this.dialogManger.dialogVisible = false
this.$refs.sceneForm.resetFields()
},
/**
* 保存新场景
*/
handleSaveNewScene() {
// vue表单校验vue表单校验
this.$refs.sceneForm.validate(valid => {
if (valid) {
this.handleSceneClose()
}
})
}
}
}
</script>
......@@ -2,7 +2,7 @@
<div class="app-container">
<el-card class="custom-card">
<div slot="header" class="clearfix">
<span>填写检查表单(所属任务:广汽丰田体系审查)</span>
<span>填写检查表单(所属任务:{{ model.systemReviewTask.name }})</span>
<el-button icon="el-icon-back" class="back-btn" @click="handleBack">
返回
</el-button>
......@@ -10,7 +10,11 @@
</div>
<div class="main-content">
<div class="prompt-message">
<span>问卷填写情况:共10条审查细则,已完成1条,未完成9条</span>
<span
>问卷填写情况:共{{ model.detailsList.length }}条审查细则,已完成{{
readNumber
}}条,未完成{{ model.detailsList.length - readNumber }}</span
>
<!-- <span class="center-text">有 3 条场景变更待处理</span>-->
<el-checkbox v-model="checked">仅显示未完成页面</el-checkbox>
</div>
......@@ -18,25 +22,28 @@
<!-- 步骤条 -->
<el-col :span="2">
<div class="left-content" style="height: 300px; width: 110px">
<div v-for="(item, index) in circleList" :key="index">
<div v-for="(item, index) in model.detailsList" :key="index">
<div
:class="{
'exclamation-point': item.problem === true,
'no-exclamation-point': item.problem === false
'exclamation-point': true,
'no-exclamation-point': false
}"
>
<div v-show="item.problem" class="exclamation">!</div>
<div v-show="true" class="exclamation">!</div>
</div>
<div
class="no-select-circle"
:class="{
'select-circle': item.checked === true,
'no-select-circle': item.checked === false
'select-circle': index === activeModel
}"
@click="handleCircle(item)"
@click="handleCircle(index)"
>
<span class="inner-text">{{ item.id }}</span>
<span class="inner-text">{{ index + 1 }}</span>
</div>
<span v-show="item.tick" class="tick-class">
<span
v-show="item.result && item.result.passed !== null"
class="tick-class"
>
<i class="el-icon-check" />
</span>
</div>
......@@ -48,24 +55,20 @@
ref="form"
class="right-content"
:model="form"
:rules="rules"
label-width="90px"
>
<el-form-item label="标准章节">
<span>5.1</span>
<span>{{ taskModel.chapter }}</span>
</el-form-item>
<el-form-item label="标准要求">
<span
>车辆制造商应具备车辆全生命周期的汽车信息安全管理体系。
注:车辆全生命周期包括车辆的开发阶段、生产阶段及后生产阶段。</span
>
<span>{{ taskModel.standardText }}</span>
</el-form-item>
<el-form-item label="审查要点">
<span>车辆制造商是否建立汽车信息安全管理制度。</span>
<span>{{ taskModel.reviewKeypointText }}</span>
</el-form-item>
<el-form-item label="审查细则">
<span
>车辆制造商是否能够提供/展示汽车信息安全管理制度文件,制度文件应定义信息安全政策以及信息安全规则和流程,信息安全政策应致力于管理与车辆制造商活动相关的信息安全风险。</span
>
<span>{{ taskModel.text }}</span>
</el-form-item>
<el-form-item :label="'符合场景'">
<template slot="label">
......@@ -80,18 +83,21 @@
</el-button>
</template>
<div class="match-scene">
<div>1.管理制度发布会红头文件</div>
<div>2.管理制度正式发布会议纪要</div>
<div>3.专用系统正式发布流程或记录</div>
<div
v-for="(scene, key) in taskModel.reviewSceneList"
:key="key"
>
{{ scene.text }}
</div>
</div>
</el-form-item>
<el-form-item label="审查结果">
<el-radio-group v-model="radio">
<el-form-item label="审查结果" prop="passed">
<el-radio-group v-model="form.passed">
<el-radio :label="1">符合</el-radio>
<el-radio :label="2">不符合</el-radio>
<el-radio :label="0">不符合</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="相关记录">
<!-- <el-form-item label="相关记录">
<el-row>
<el-col :span="8">
<div>
......@@ -112,14 +118,14 @@
</div>
</el-col>
</el-row>
<!-- 文件第一次提示 -->
//文件第一次提示
<div class="file-prompt">
<div>
<i class="el-icon-info"></i
>该文件第一次出现,请维护如下相关信息
</div>
</div>
<!-- 车企文件信息 -->
//车企文件信息
<el-card>
<div slot="header" class="clearfix">
<span>车企文件信息</span>
......@@ -226,128 +232,56 @@
>保存车企文件</el-button
>
</el-card>
</el-form-item>
</el-form-item> -->
<el-form-item label="条目填写人">
<span>赵小刚</span>
<span>{{ name }}</span>
</el-form-item>
</el-form>
</el-col>
</el-row>
</div>
<div class="bottom-btn">
<el-button type="warning" @click="saveCurrentItem">
<el-button type="warning" @click="submitQuestionnaire(1)">
保存当前边界
</el-button>
<el-button type="primary" @click="submitQuestionnaire"
<el-button type="primary" @click="submitQuestionnaire(2)"
>提交表格</el-button
>
</div>
</el-card>
<!-- 新增场景对话框 -->
<el-dialog
title="新增场景对话框"
:visible.sync="senceDialogVisible"
width="35%"
append-to-body
:close-on-click-modal="false"
:close-on-press-escape="false"
:before-close="handleSceneClose"
>
<div class="file-prompt">
<div>
<i
class="el-icon-info"
/>新增场景,需要组织评审,评审通过后新增场景自动进入场景库。
</div>
</div>
<el-form
ref="sceneForm"
:model="sceneForm"
:rules="sceneRules"
label-width="80px"
class="scene-form"
>
<el-form-item label="评审类型" prop="reviewType">
<!-- 下拉框 -->
<el-select
v-model="sceneForm.reviewType"
placeholder="请选择评审类型"
style="width: 100%"
>
<el-option
v-for="item in reviewTypeOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="场景分类" prop="sceneClassification">
<el-select
v-model="sceneForm.sceneClassification"
placeholder="请选择评审类型"
style="width: 100%"
>
<el-option
v-for="item in reviewTypeOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="场景内容" prop="sceneContent">
<el-input
v-model="sceneForm.sceneContent"
maxlength="100"
show-word-limit
type="textarea"
/>
</el-form-item>
<el-form-item label="评审人员" prop="assessor">
<div>组长-xxx</div>
<div>组员-xxx、xxx、xxx</div>
</el-form-item>
<el-form-item label="备注信息" prop="remark">
<el-input
v-model="sceneForm.remark"
maxlength="100"
show-word-limit
type="textarea"
/>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="senceDialogVisible = false">取 消</el-button>
<el-button type="primary" @click="handleSaveNewScene">
确 定
</el-button>
</span>
</el-dialog>
<sence-dialog :dialog-manger="senceManger"></sence-dialog>
</div>
</template>
<script>
import { taskDetail, reviewDetailsSubmit } from '@/api/task/task'
import senceDialog from './components/senceDialog.vue'
import { mapGetters } from 'vuex'
export default {
dicts: ['file_status'],
components: {
'sence-dialog': senceDialog
},
data() {
return {
sceneForm: {},
senceDialogVisible: false,
form: {},
senceManger: {
dialogVisible: false
},
form: {
passed: null
},
model: {
systemReviewTask: {},
reviewSceneChangeTasks: {},
detailsList: []
},
taskModel: {},
activeModel: 0,
checked: false,
circleList: [
{ id: 1, checked: false, problem: false, tick: true },
{ id: 2, checked: true, problem: false, tick: false },
{ id: 3, checked: false, problem: true, tick: false },
{ id: 4, checked: false, problem: false, tick: false },
{ id: 5, checked: false, problem: false, tick: false },
{ id: 6, checked: false, problem: false, tick: false },
{ id: 7, checked: false, problem: false, tick: false },
{ id: 8, checked: false, problem: false, tick: false },
{ id: 9, checked: false, problem: false, tick: false },
{ id: 10, checked: false, problem: false, tick: false }
],
rules: {
passed: [{ required: true, message: '请选择审查结果', trigger: 'blur' }]
},
fileRules: {
enterpriseName: [
{ required: true, message: '请输入企业名称', trigger: 'blur' }
......@@ -374,17 +308,6 @@ export default {
{ required: true, message: '请选择文件照片', trigger: 'change' }
]
},
sceneRules: {
reviewType: [
{ required: true, message: '请选择评审类型', trigger: 'change' }
],
sceneClassification: [
{ required: true, message: '请选择场景分类', trigger: 'change' }
],
sceneContent: [
{ required: true, message: '请输入场景内容', trigger: 'blur' }
]
},
// TODO 删除
checkedTwo: false,
checkedThree: false,
......@@ -400,22 +323,61 @@ export default {
storageLocation: ''
},
value1: '',
reviewTypeOptions: []
taskId: ''
}
},
created() {
console.log('人', this.$store.state.user.name)
computed: {
readNumber() {
let num = 0
this.model.detailsList.map(i => {
if (i.result && i.result.passed !== null) {
num++
}
})
return num
},
...mapGetters(['name'])
},
mounted() {
this.taskId = this.$route.query.id
this.getTask()
},
methods: {
getTask() {
taskDetail({
taskId: this.taskId
}).then(res => {
if (res.code === 200) {
this.model = res.data
this.handleCircle(0)
} else {
this.$modal.msgError(res.msg)
}
})
},
/**
* 点击左侧圆圈触发的回调函数
* @param item 圆圈对象
*/
handleCircle(item) {
this.circleList.forEach(item => {
item.checked = false
})
item.checked = true
handleCircle(index) {
this.activeModel = index
this.taskModel = JSON.parse(JSON.stringify(this.model.detailsList[index]))
if (this.taskModel.result) {
this.form = {
passed: this.taskModel.result.passed,
reviewDetailsId: this.taskModel.id,
taskId: this.taskId
}
} else {
this.form = {
passed: null,
reviewDetailsId: this.taskModel.id,
taskId: this.taskId
}
}
},
// 返回
handleBack() {
......@@ -423,33 +385,30 @@ export default {
},
// 新增场景
handleAddScene() {
this.senceDialogVisible = true
console.log('a')
this.senceManger.dialogVisible = true
},
// 保存当前条目
saveCurrentItem() {
this.$modal.msgSuccess('保存当前边界成功')
},
submitQuestionnaire() {
this.$modal.msgSuccess('提交表格成功')
this.$router.back()
},
// 新增场景对话框关闭时触发的回调函数
handleSceneClose() {
this.senceDialogVisible = false
this.$refs.sceneForm.resetFields()
},
handleSaveFile() {
// vue表单校验
this.$refs.fileRef.validate(valid => {
submitQuestionnaire(type) {
this.$refs.form.validate(valid => {
if (valid) {
console.log('ddd')
reviewDetailsSubmit(this.form).then(res => {
if (res.code === 200) {
if (!this.model.detailsList[this.activeModel].result) {
this.model.detailsList[this.activeModel].result = { passed: 0 }
}
this.model.detailsList[this.activeModel].result.passed =
this.form.passed
this.$modal.msgSuccess('提交表格成功')
} else {
this.$modal.msgError(res.msg)
}
})
}
})
},
handleSaveNewScene() {
// vue表单校验vue表单校验
this.$refs.sceneForm.validate(valid => {
handleSaveFile() {
// vue表单校验
this.$refs.fileRef.validate(valid => {
if (valid) {
console.log('ddd')
}
......@@ -462,44 +421,54 @@ export default {
<style scoped lang="scss">
.app-container {
padding: 20px;
.custom-card {
::v-deep.el-card__header {
background-color: #f9f9f9;
}
.back-btn {
margin-left: 10px;
float: right;
}
.other-btn {
float: right;
}
.main-content {
min-height: 550px;
.prompt-message {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 40px;
.center-text {
color: #f56c6c;
}
}
.left-content {
.tick-class {
float: right;
position: relative;
top: -1.8em;
left: -1em;
i {
color: #25c173;
}
}
.no-exclamation-point {
float: left;
width: 1px;
height: 1px;
padding-left: 30px;
}
.exclamation-point {
float: left;
margin-top: 6px;
......@@ -515,6 +484,7 @@ export default {
font-size: 24px;
font-weight: bold;
margin-bottom: 5px;
.exclamation {
position: absolute;
font-size: 12px;
......@@ -522,6 +492,7 @@ export default {
font-weight: bold;
}
}
.no-select-circle {
cursor: pointer;
width: 35px;
......@@ -535,6 +506,7 @@ export default {
font-weight: bold;
position: relative;
margin-bottom: 5px;
.inner-text {
position: absolute;
font-size: 16px;
......@@ -542,6 +514,7 @@ export default {
color: #c0c0c0;
}
}
.select-circle {
cursor: pointer;
width: 35px;
......@@ -555,6 +528,7 @@ export default {
font-weight: bold;
position: relative;
margin-bottom: 5px;
.inner-text {
position: absolute;
font-size: 16px;
......@@ -563,23 +537,28 @@ export default {
}
}
}
.right-content {
.file-form-class {
::v-deep.el-form-item {
margin-bottom: 20px;
}
}
.match-scene {
display: flex;
flex-direction: column;
background-color: #fafafa;
padding: 5px;
}
.file-prompt {
margin: 10px 0 10px 0;
background-color: #ebf5ff;
div {
padding-left: 10px;
i {
color: #409eff;
margin-right: 10px;
......@@ -588,27 +567,33 @@ export default {
}
}
}
.bottom-btn {
display: flex;
justify-content: center;
}
}
}
.file-prompt {
margin: 0 0 10px 0;
padding: 10px;
background-color: #ebf5ff;
div {
font-size: 12px;
padding-left: 10px;
i {
color: #409eff;
margin-right: 10px;
}
}
}
.label-btn {
width: 60px;
span {
font-size: 12px;
position: relative;
......
......@@ -29,7 +29,7 @@
<el-row :gutter="20">
<el-col :span="8">
<el-form-item label="任务编码" prop="status">
<el-input v-model="model.status" placeholder="请输入" clearable />
<el-input v-model="model.taskNo" placeholder="请输入" clearable />
</el-form-item>
</el-col>
<el-col :span="8">
......@@ -237,6 +237,7 @@
</template>
<script>
import image from '@/assets/images/login-background.jpg'
import request from '@/utils/request'
export default {
data() {
return {
......@@ -256,8 +257,23 @@ export default {
}
}
},
mounted() {
this.getTask(this.$route.query.id)
console.log(this.$route.query.id)
},
dicts: ['sys_task_status', 'sys_pro'],
methods: {
getTask(id) {
request({
url: '/system/review/task/view',
method: 'post',
data: {
taskId: id
}
}).then(res => {
console.log(res)
})
},
handleAvatarSuccess(res, file) {
this.imageUrl = URL.createObjectURL(file.raw)
},
......
......@@ -314,6 +314,7 @@
</page-standard>
</template>
<script>
import { taskDetail } from '@/api/task/task'
export default {
dicts: ['sys_task_status', 'sys_pro'],
data() {
......@@ -323,30 +324,8 @@ export default {
formType: 1,
/* 表单对象*/
model: {
no: '12345',
status: '资产审查任务',
taskStatus: '1',
pname: '广汽丰田',
carType: '油车',
weituo: '广汽丰田汽车有限公司',
weituoAddress: '广州市南沙区黄阁镇市南大道8号',
phonenumber: '15320986678',
youzheng: '233546',
type: '小型车',
shibie: 'ZGH6788',
yangpin: '全新第四代汉兰达',
shengchan: '广汽丰田汽车有限公司',
songyangzhe: '赵平',
songyangdata: '2023-08-05',
shangbiao: 'ZGH6788',
shuliang: '200',
riqi: '2022-12-23',
yijv: 'ZGH6788',
jianyan: '广汽丰田汽车有限公司',
qianfa: '2023-11-02',
bianhao: '91440101717852200L',
jielun:
'广汽丰田汽车有限公司(GAC TOYOTA),成立于2004年9月1日,由广汽集团股份有限公司与日本丰田汽车公司各出资50%组建,合作期限30年,注册资本16.92亿元。 公司位于中国极具活力的珠三角的几何中心--广州南沙区,占地面积187万平方米,建筑面积40万平方米,起步产能20万辆/年。共有员工5500余人,其中大专及其以上学历者达24.9%,平均年龄为26岁。'
systemReviewTask: {},
reviewSceneChangeTasks: {}
},
loading: false,
/* 表格对象*/
......@@ -463,7 +442,20 @@ export default {
]
}
},
mounted() {
this.getTask(this.$route.query.id)
console.log(this.$route.query.id)
},
methods: {
getTask(id) {
taskDetail({
taskId: id
}).then(res => {
if (res.code === 200) {
this.model = res.data
}
})
},
/**
* 小组信息修改
* @param row 行内信息
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment