Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
M
mes-ui
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
周远喜
mes-ui
Commits
6f24cdd2
Commit
6f24cdd2
authored
Nov 16, 2020
by
renjintao
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' of git.mes123.com:zhouyx/mes-ui into product-rjt
parents
dbdeb7c7
69eb19e7
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
1478 additions
and
708 deletions
+1478
-708
userGroup.vue
components/page/userGroup.vue
+3
-0
api.js
pages/project/plan/api.js
+3
-0
gantt-header.vue
pages/project/plan/components/gantt-header.vue
+325
-0
gant.vue
pages/project/plan/gant.vue
+215
-0
index.vue
pages/project/plan/index.vue
+29
-2
detail.vue
pages/project/project/detail.vue
+19
-11
add.vue
pages/project/task/add.vue
+4
-3
index.vue
pages/project/task/index.vue
+5
-3
basicView.vue
pages/qc/dataTrace/components/basicView.vue
+91
-79
mainView.vue
pages/qc/dataTrace/components/mainView.vue
+39
-36
matching.vue
pages/qc/dataTrace/components/matching.vue
+131
-0
orderqcrecord.vue
pages/qc/dataTrace/components/orderqcrecord.vue
+5
-3
reviewCount.vue
pages/qc/dataTrace/components/reviewCount.vue
+66
-143
index.vue
pages/qc/dataTrace/index.vue
+543
-428
No files found.
components/page/userGroup.vue
View file @
6f24cdd2
...
...
@@ -96,6 +96,9 @@ export default {
this
.
load
();
}
},
value
(
v
){
this
.
name
=
v
;
}
},
};
</
script
>
...
...
pages/project/plan/api.js
View file @
6f24cdd2
...
...
@@ -16,6 +16,9 @@ export default {
update
(
params
)
{
return
Api
.
post
(
`
${
material
}
/projectplan/update`
,
params
);
},
batchUpdate
(
params
)
{
return
Api
.
post
(
`
${
material
}
/projectplan/updatepartbatch`
,
params
);
},
sendtask
(
params
)
{
return
Api
.
post
(
`
${
material
}
/projectplan/sendtask`
,
params
);
},
...
...
pages/project/plan/components/gantt-header.vue
0 → 100644
View file @
6f24cdd2
<!--
/**
* @fileoverview Header component
* @license MIT
* @author Rafal Pospiech <neuronet.io@gmail.com>
* @package GanttElasticHeader
*/
-->
<
template
>
<div
class=
"gantt-elastic__header"
:style=
"
{ ...style['header'] }">
<div
class=
"gantt-elastic__header-title"
:style=
"
{ ...style['header-title'] }">
<div
class=
"gantt-elastic__header-title--text"
:style=
"
{ ...style['header-title--text'] }"
v-if="!opts.title.html"
>
{{
opts
.
title
.
label
}}
</div>
<div
class=
"gantt-elastic__header-title--html"
:style=
"
{ ...style['header-title--html'] }"
v-if="opts.title.html"
v-html="opts.title.label"
>
</div>
</div>
<div
class=
"gantt-elastic__header-options"
:style=
"
{ ...style['header-options'] }">
<!--
<button
class=
"gantt-elastic__header-btn-recenter"
:style=
"
{ ...style['header-btn-recenter'] }"
@click.prevent="recenterPosition"
>
{{
opts
.
locale
.
Now
}}
</button>
-->
<label
class=
"gantt-elastic__header-label"
:style=
"
{ ...style['header-label'] }">
{{
opts
.
locale
[
"X-Scale"
]
}}
<div
class=
"gantt-elastic__header-slider-wrapper"
:style=
"
{ ...style['header-slider-wrapper'] }"
>
<vue-slider
class=
"gantt-elastic__header-slider"
tooltip=
"none"
:style=
"
{ ...style['header-slider'] }"
:process-style="{ ...style['header-slider--process'] }"
:slider-style="{ ...style['header-slider--slider'] }"
v-model="scale"
:max="24"
:min="2"
width="100px"
>
</vue-slider>
</div>
</label>
<label
class=
"gantt-elastic__header-label"
:style=
"
{ ...style['header-label'] }">
{{
opts
.
locale
[
"Y-Scale"
]
}}
<div
class=
"gantt-elastic__header-slider-wrapper"
:style=
"
{ ...style['header-slider-wrapper'] }"
>
<vue-slider
class=
"gantt-elastic__header-slider"
tooltip=
"none"
:style=
"
{ ...style['header-slider'] }"
:process-style="{ ...style['header-slider--process'] }"
:slider-style="{ ...style['header-slider--slider'] }"
v-model="height"
:max="100"
:min="7"
width="100px"
>
</vue-slider>
</div>
</label>
<label
class=
"gantt-elastic__header-label"
:style=
"
{ ...style['header-label'] }">
{{
opts
.
locale
[
"Before/After"
]
}}
<div
class=
"gantt-elastic__header-slider-wrapper"
:style=
"
{ ...style['header-slider-wrapper'] }"
>
<vue-slider
class=
"gantt-elastic__header-slider"
tooltip=
"none"
:style=
"
{ ...style['header-slider'] }"
:process-style="{ ...style['header-slider--process'] }"
:slider-style="{ ...style['header-slider--slider'] }"
v-model="scope"
:max="31"
:min="0"
width="100px"
>
</vue-slider>
</div>
</label>
<label
class=
"gantt-elastic__header-label"
:style=
"
{ ...style['header-label'] }">
{{
opts
.
locale
[
"Task list width"
]
}}
<div
class=
"gantt-elastic__header-slider-wrapper"
:style=
"
{ ...style['header-slider-wrapper'] }"
>
<vue-slider
class=
"gantt-elastic__header-slider"
tooltip=
"none"
:style=
"
{ ...style['header-slider'] }"
:process-style="{ ...style['header-slider--process'] }"
:slider-style="{ ...style['header-slider--slider'] }"
v-model="divider"
:max="100"
:min="0"
width="100px"
>
</vue-slider>
</div>
</label>
<label
class=
"gantt-elastic__header-task-list-switch--wrapper"
:style=
"
{ ...style['header-task-list-switch--label'] }"
>
<switches
class=
"gantt-elastic__header-task-list-switch"
:style=
"
{ ...style['header-task-list-switch'] }"
v-model="root.state.options.taskList.display"
>
</switches>
{{
opts
.
locale
[
"Display task list"
]
}}
</label>
</div>
</div>
</
template
>
<
script
>
import
vueSlider
from
"vue-slider-component"
;
import
"vue-slider-component/theme/default.css"
;
import
Switches
from
"vue-switches"
;
const
defaultStyle
=
{
header
:
{
margin
:
"0px auto"
,
background
:
"#f3f5f747"
,
padding
:
"10px"
,
overflow
:
"hidden"
,
clear
:
"both"
,
display
:
"flex"
,
"justify-content"
:
"space-between"
},
"header-title"
:
{
float
:
"left"
},
"header-options"
:
{
float
:
"right"
},
"header-title--text"
:
{
"font-size"
:
"20px"
,
"vertical-align"
:
"middle"
,
"font-weight"
:
"400"
,
"line-height"
:
"35px"
,
"padding-left"
:
"22px"
,
"letter-spacing"
:
"1px"
},
"header-title--html"
:
{
"font-size"
:
"20px"
,
"vertical-align"
:
"middle"
,
"font-weight"
:
"400"
,
"line-height"
:
"35px"
,
"padding-left"
:
"22px"
,
"letter-spacing"
:
"1px"
},
"header-btn-recenter"
:
{
background
:
"#95A5A6"
,
border
:
"none"
,
outline
:
"none"
,
cursor
:
"pointer"
,
color
:
"white"
,
"border-radius"
:
"3px"
,
"margin-right"
:
"27px"
,
"font-size"
:
"16px"
,
padding
:
"8px 12px"
},
"header-slider"
:
{
"box-sizing"
:
"content-box"
},
"header-slider-wrapper"
:
{
display
:
"inline-block"
,
"vertical-align"
:
"middle"
},
"header-slider--slider"
:
{
"box-sizing"
:
"content-box"
},
"header-slider--process"
:
{
"box-sizing"
:
"content-box"
},
"header-task-list-switch--label"
:
{
"box-sizing"
:
"content-box"
},
"header-task-list-switch"
:
{
margin
:
"0px 15px"
,
"vertical-align"
:
"middle"
},
"header-label"
:
{}
};
const
defaultOptions
=
{
title
:
{
// label: "任务甘特图",
html
:
false
},
locale
:
{
Now
:
"Now"
,
"X-Scale"
:
"缩放-X"
,
"Y-Scale"
:
"缩放-Y"
,
"Task list width"
:
"任务列表"
,
"Before/After"
:
"展开日期"
,
"Display task list"
:
"是否展开任务列表"
}
};
export
default
{
name
:
"GanttHeader"
,
components
:
{
vueSlider
,
Switches
},
props
:
[
"options"
,
"dynamicStyle"
],
inject
:
[
"root"
],
data
()
{
return
{
scaleTimeoutId
:
null
,
firstScale
:
false
,
localScale
:
0
,
localHeight
:
0
,
localBefore
:
0
,
localPercent
:
0
,
sliderOptions
:
{
xScale
:
{
value
:
0
}
},
style
:
{},
opts
:
{}
};
},
created
()
{
this
.
localScale
=
this
.
root
.
state
.
options
.
times
.
timeZoom
;
this
.
localHeight
=
this
.
root
.
state
.
options
.
row
.
height
;
this
.
localBefore
=
this
.
root
.
state
.
options
.
scope
.
before
;
this
.
localPercent
=
this
.
root
.
state
.
options
.
taskList
.
percent
;
this
.
sliderOptions
.
xScale
.
value
=
this
.
root
.
state
.
options
.
times
.
timeZoom
;
this
.
style
=
this
.
root
.
mergeDeep
({},
defaultStyle
,
this
.
dynamicStyle
);
this
.
opts
=
this
.
root
.
mergeDeep
({},
defaultOptions
,
this
.
options
);
},
methods
:
{
getImage
()
{
this
.
root
.
getImage
(
"image/png"
).
then
(
imgB64
=>
{
const
link
=
document
.
createElement
(
"a"
);
link
.
href
=
imgB64
;
link
.
download
=
"gantt-elastic.png"
;
document
.
body
.
appendChild
(
link
);
link
.
click
();
document
.
body
.
removeChild
(
link
);
});
},
recenterPosition
()
{
this
.
root
.
$emit
(
"recenterPosition"
);
},
setScale
(
value
)
{
if
(
this
.
scaleTimeoutId
!==
null
)
{
clearTimeout
(
this
.
scaleTimeoutId
);
this
.
scaleTimeoutId
=
null
;
}
// debouncing
if
(
this
.
firstScale
)
{
this
.
scaleTimeoutId
=
setTimeout
(()
=>
{
this
.
root
.
$emit
(
"times-timeZoom-change"
,
value
);
this
.
scaleTimeoutId
=
null
;
},
50
);
}
else
{
this
.
root
.
$emit
(
"times-timeZoom-change"
,
value
);
this
.
firstScale
=
true
;
}
}
},
computed
:
{
/**
* If there is a component slot specified for header
* @returns {bool}
*/
beforeOptionsIsComponent
()
{
const
headerSlot
=
this
.
options
.
slots
.
header
;
if
(
typeof
headerSlot
.
beforeOptions
===
"object"
&&
!
Array
.
isArray
(
headerSlot
.
beforeOptions
)
)
{
return
true
;
}
return
false
;
},
/**
* If there is a slot with beforeOptions html content
* @returns {bool}
*/
beforeOptionsIsHtml
()
{
if
(
typeof
this
.
options
.
slots
.
header
.
beforeOptions
===
"string"
)
{
return
true
;
}
return
false
;
},
scale
:
{
get
()
{
return
this
.
localScale
;
},
set
(
value
)
{
this
.
localScale
=
Number
(
value
);
this
.
setScale
(
this
.
localScale
);
}
},
height
:
{
get
()
{
return
this
.
localHeight
;
},
set
(
value
)
{
this
.
localHeight
=
Number
(
value
);
this
.
root
.
$emit
(
"row-height-change"
,
Number
(
value
));
}
},
scope
:
{
get
()
{
return
this
.
localBefore
;
},
set
(
value
)
{
this
.
localBefore
=
Number
(
value
);
this
.
root
.
$emit
(
"scope-change"
,
Number
(
value
));
}
},
divider
:
{
get
()
{
return
this
.
localPercent
;
},
set
(
value
)
{
this
.
localPercent
=
Number
(
value
);
this
.
root
.
$emit
(
"taskList-width-change"
,
Number
(
value
));
}
}
}
};
</
script
>
pages/project/plan/gant.vue
0 → 100644
View file @
6f24cdd2
<
template
>
<div
class=
"q-pa-sm"
>
<div
class=
"pr mt50"
v-if=
"tasks.length == 0"
>
<Spin
size=
"large"
fix
></Spin>
</div>
<gantt-elastic
v-else
:options=
"options"
:tasks=
"tasks"
@
tasks-changed=
"tasksUpdate"
@
options-changed=
"optionsUpdate"
@
dynamic-style-changed=
"styleUpdate"
>
<gantt-header
slot=
"header"
></gantt-header>
</gantt-elastic>
<div
class=
"q-mt-md"
/>
</div>
</
template
>
<
style
>
</
style
>
<
script
>
import
GanttElastic
from
"gantt-elastic"
;
import
GanttHeader
from
"./components/gantt-header"
;
import
dayjs
from
"dayjs"
;
import
Api
from
"./api"
;
function
GetTimeByTimeStr
(
dateString
)
{
if
(
dateString
){
var
timeArr
=
dateString
.
split
(
" "
);
var
d
=
timeArr
[
0
].
split
(
"-"
);
var
t
=
timeArr
[
1
].
split
(
":"
);
return
new
Date
(
d
[
0
],
d
[
1
]
-
1
,
d
[
2
],
t
[
0
],
t
[
1
],
t
[
2
]).
getTime
();
}
else
{
return
0
;
}
}
let
that
;
export
default
{
name
:
"Gantt"
,
components
:
{
GanttElastic
,
GanttHeader
,
},
props
:
{
eid
:
String
,
},
data
()
{
return
{
tasks
:
[],
options
:
{
taskMapping
:
{
progress
:
"percent"
,
},
maxRows
:
100
,
maxHeight
:
500
,
title
:
{
label
:
"Your project title as html (link or whatever...)"
,
html
:
false
,
},
row
:
{
height
:
24
,
},
calendar
:
{
hour
:
{
display
:
true
,
},
},
chart
:
{
progress
:
{
bar
:
false
,
},
expander
:
{
display
:
true
,
},
},
taskList
:
{
expander
:
{
straight
:
false
,
},
columns
:
[
// {
// id: 1,
// label: "ID",
// value: "id",
// width: 40,
// },
{
id
:
2
,
label
:
"名称"
,
value
:
v
=>
{
return
`<a>
${
v
.
name
}
</a>`
},
width
:
200
,
expander
:
true
,
html
:
true
,
events
:
{
click
({
data
,
column
})
{
alert
(
data
.
name
);
console
.
log
(
this
)
that
.
$Message
.
info
(
data
.
name
)
},
},
},
{
id
:
3
,
label
:
"状态"
,
value
:
"status"
,
width
:
100
,
html
:
true
,
events
:
{
click
(
e
)
{
console
.
log
(
e
)
that
.
$Message
.
info
(
e
.
data
.
name
)
},
},
},
{
id
:
4
,
label
:
"计划开始时间"
,
// value: 'startDate',
value
:
(
task
)
=>
dayjs
(
task
.
startDate
).
format
(
"YYYY-MM-DD"
),
width
:
160
,
},
{
id
:
5
,
label
:
"计划结束时间"
,
// value:'endDate',
value
:
(
task
)
=>
dayjs
(
task
.
endDate
).
format
(
"YYYY-MM-DD"
),
width
:
180
,
},
{
id
:
6
,
label
:
"计划类型"
,
value
:
"type"
,
width
:
80
,
}
],
},
locale
:
{
weekdays
:
[
"周日"
,
"周一"
,
"周二"
,
"周三"
,
"周四"
,
"周五"
,
"周六"
],
months
:
[
"一月"
,
"二月"
,
"三月"
,
"四月"
,
"五月"
,
"六月"
,
"七月"
,
"八月"
,
"九月"
,
"十月"
,
"十一月"
,
"十二月"
,
],
},
},
dynamicStyle
:
{},
lastId
:
16
,
};
},
created
()
{
that
=
this
;
this
.
gantData
();
},
methods
:
{
gantData
()
{
var
params
=
{
conditions
:
[
{
fieldName
:
"projectId"
,
conditionalType
:
"Equal"
,
fieldValue
:
this
.
eid
,
},
],
};
Api
.
list
(
params
).
then
((
r
)
=>
{
let
tasks
=
r
.
result
;
var
types
=
[
"project"
,
"milestone"
,
"task"
]
tasks
=
tasks
.
map
(
u
=>
{
var
obj
=
{
id
:
u
.
id
,
parentId
:
u
.
upId
,
name
:
u
.
title
,
startDate
:
u
.
startDate
,
endDate
:
u
.
endDate
,
start
:
GetTimeByTimeStr
(
u
.
startDate
),
duration
:
GetTimeByTimeStr
(
u
.
endDate
)
-
GetTimeByTimeStr
(
u
.
startDate
)
,
percent
:
85
,
status
:
u
.
status
,
type
:
types
[
u
.
type
],
};
return
obj
;
})
this
.
tasks
=
tasks
;
});
},
tasksUpdate
(
tasks
)
{
this
.
tasks
=
tasks
;
},
optionsUpdate
(
options
)
{
this
.
options
=
options
;
},
styleUpdate
(
style
)
{
this
.
dynamicStyle
=
style
;
},
},
};
</
script
>
pages/project/plan/index.vue
View file @
6f24cdd2
...
...
@@ -52,7 +52,7 @@
<
template
slot=
"batch"
>
<span
v-width=
"300"
style=
"color:#333"
>
<DateRange
v-model=
"dateEntity"
edit
v-width=
"260"
></DateRange>
<Button
type=
"primary"
>
设置2计划
日期
</Button>
<Button
type=
"primary"
@
click=
"setDate()"
>
设置
日期
</Button>
</span>
<span>
<UserGroup
...
...
@@ -61,7 +61,7 @@
:projectId=
"eid"
v-width=
"300"
></UserGroup>
<Button
type=
"primary"
>
设置执行人
</Button>
<Button
type=
"primary"
@
click=
"setExecutor()"
>
设置执行人
</Button>
</span>
<Button
type=
"primary"
@
click=
"bacthRemove()"
>
批量删除
</Button>
</
template
>
...
...
@@ -361,6 +361,33 @@ export default {
this
.
list
=
data
;
});
},
setDate
(){
var
items
=
this
.
batchItems
.
map
(
u
=>
{
return
{
id
:
u
.
id
,
startDate
:
this
.
dateEntity
.
startDate
,
endDate
:
this
.
dateEntity
.
endDate
,
}
})
Api
.
batchUpdate
(
items
).
then
(
r
=>
{
if
(
r
.
success
){
this
.
search
();
}
});
},
setExecutor
(){
var
items
=
this
.
batchItems
.
map
(
u
=>
{
return
{
id
:
u
.
id
,
executor
:
this
.
executors
}
})
Api
.
batchUpdate
(
items
).
then
(
r
=>
{
if
(
r
.
success
){
this
.
search
();
}
});
},
add
(
row
)
{
if
(
row
)
{
this
.
curId
=
row
.
id
;
...
...
pages/project/project/detail.vue
View file @
6f24cdd2
...
...
@@ -12,8 +12,14 @@
<DateRange
v-model=
"entity"
/>
</Filed>
<Filed
:span=
"24"
:name=
"l('users') + ':'"
>
<User
v-for=
"(u,i) in users"
:value=
"u.userId"
:key=
"u.userId"
mode=
"text"
class=
"mr10"
/>
<a
@
click=
"group"
><Avatar
icon=
"md-add"
/></a>
<User
v-for=
"(u, i) in users"
:value=
"u.userId"
:key=
"u.userId"
mode=
"text"
class=
"mr10"
/>
<a
@
click=
"group"
><Avatar
icon=
"md-add"
/></a>
</Filed>
</Row>
</div>
...
...
@@ -35,10 +41,15 @@
<span>
|
</span>
</li>
<li>
<a
@
click=
"
task
"
>
<Icon
type=
"ios-list-box"
size=
"18"
/>
任务监控
</a>
<a
@
click=
"
gant
"
>
<Icon
type=
"ios-list-box"
size=
"18"
/>
任务监控
</a>
<span>
|
</span>
</li>
<!--
<li>
<a
@
click=
"task"
>
<Icon
type=
"ios-list-box"
size=
"18"
/>
任务监控
</a>
<span>
|
</span>
</li>
-->
<li>
<a
@
click=
"group"
>
<Icon
type=
"ios-people"
size=
"18"
/>
成员
</a>
...
...
@@ -75,7 +86,7 @@ export default {
curId
:
this
.
eid
,
avatorPath
:
""
,
entity
:
{},
users
:[],
users
:
[],
rules
:
{
name
:
[
{
...
...
@@ -129,15 +140,12 @@ export default {
this
.
detail
=
()
=>
import
(
"../plan"
);
},
task
()
{
//this.curId = this.eid;
this
.
title
=
"任务"
;
this
.
detail
=
()
=>
import
(
"../task/index"
);
// this.$router.push({
// name: "project-task",
// params: {
// id: this.curId
// }
// });
},
gant
()
{
this
.
title
=
"任务监控"
;
this
.
detail
=
()
=>
import
(
"../plan/gant"
);
},
group
()
{
this
.
title
=
"项目成员"
;
...
...
pages/project/task/add.vue
View file @
6f24cdd2
...
...
@@ -12,7 +12,7 @@
</Col>
<Col
:span=
"12"
>
<FormItem
:label=
"l('userId')"
prop=
"userId"
>
<UserGroup
v-model=
"entity.userId"
:projectId=
"
ei
d"
/>
<UserGroup
v-model=
"entity.userId"
:projectId=
"
projectI
d"
/>
</FormItem>
</Col>
<Col
:span=
"12"
>
...
...
@@ -75,8 +75,9 @@ export default {
},
props
:
{
v
:
Object
,
eid
:
String
,
pid
:
String
,
eid
:
String
,
//当前id
pid
:
String
,
//计划id
projectId
:
String
,
//项目id
},
mounted
()
{
// if (this.eid != '' && this.eid != null) {
...
...
pages/project/task/index.vue
View file @
6f24cdd2
...
...
@@ -61,7 +61,7 @@
</
template
>
</DataGrid>
<Modal
v-model=
"modal"
:title=
"title"
width=
"1200"
:fullscreen=
"fullScreen"
footer-hide
>
<component
:is=
"detail"
:eid=
"curId"
:pid=
"planId"
:row=
"rowObj"
@
on-close=
"cancel"
@
on-ok=
"ok"
/>
<component
:is=
"detail"
:eid=
"curId"
:pid=
"planId"
:
projectId=
"projectId"
:
row=
"rowObj"
@
on-close=
"cancel"
@
on-ok=
"ok"
/>
</Modal>
</Content>
</Layout>
...
...
@@ -109,7 +109,7 @@ export default {
rowObj
:
null
,
curId
:
''
,
fullScreen
:
false
,
projectId
:
''
,
projectId
:
this
.
eid
,
columns
:
[
// {
// key: "selection",
...
...
@@ -407,6 +407,7 @@ export default {
},
productSearch
(
id
,
item
,
planIds
)
{
this
.
planId
=
item
.
selected
?
id
:
''
;
this
.
projectId
=
item
.
projectId
;
this
.
planIdsCur
=
item
.
selected
?
planIds
:
[]
let
where
=
{
planId
:
{
...
...
@@ -415,9 +416,10 @@ export default {
},
projectId
:
{
op
:
"Equal"
,
value
:
this
.
ei
d
value
:
item
.
projectI
d
},
};
this
.
curId
=
this
.
$refs
.
grid
.
reload
(
where
);
},
updatepart
(
valId
,
valStatus
)
{
...
...
pages/qc/dataTrace/components/basicView.vue
View file @
6f24cdd2
<
template
>
<div
class=
"orderDetail"
>
<div
class=
"orderDetail"
>
<Row>
<Col
span=
"8"
>
<span
class=
"fwBold"
>
{{
l
(
'mesCode'
)
}}
</span>
<p>
{{
baseData
.
mesCode
}}
</p>
</Col>
<Col
span=
"8"
>
<span
class=
"fwBold"
>
{{
l
(
'taskType'
)
}}
</span>
<Col
span=
"8"
>
<span
class=
"fwBold"
>
{{
l
(
"mesCode"
)
}}
</span>
<p>
{{
baseData
.
mesCode
}}
</p>
</Col>
<Col
span=
"8"
>
<span
class=
"fwBold"
>
{{
l
(
"taskType"
)
}}
</span>
<p>
<state
code=
"plan.order.taskType"
:value=
"baseData.taskType"
type=
"text"
></state>
<state
code=
"plan.order.taskType"
:value=
"baseData.taskType"
type=
"text"
></state>
</p>
</Col>
<Col
span=
"8"
>
<span
class=
"fwBold"
>
{{
l
(
'quantity'
)
}}
</span>
<p>
{{
baseData
.
quantity
}}
</p>
</Col>
</Col>
<Col
span=
"8"
>
<span
class=
"fwBold"
>
{{
l
(
"quantity"
)
}}
</span>
<p>
{{
baseData
.
quantity
}}
</p>
</Col>
</Row>
<Row>
<Col
span=
"8"
>
<span
class=
"fwBold"
>
{{
l
(
'status'
)
}}
</span>
<Col
span=
"8"
>
<span
class=
"fwBold"
>
{{
l
(
"status"
)
}}
</span>
<p>
<state
code=
"plan.order.status"
:value=
"baseData.status"
type=
"text"
></state>
<state
code=
"plan.order.status"
:value=
"baseData.status"
type=
"text"
></state>
</p>
</Col>
<Col
span=
"8"
>
<span
class=
"fwBold"
>
{{
l
(
'productName'
)
}}
</span>
<p>
{{
baseData
.
productName
}}
</p>
</Col>
<Col
span=
"8"
>
<span
class=
"fwBold"
>
{{
l
(
'drawnNumber'
)
}}
</span>
<p>
{{
baseData
.
drawnNumber
}}
</p>
</Col>
</Col>
<Col
span=
"8"
>
<span
class=
"fwBold"
>
{{
l
(
"productName"
)
}}
</span>
<p>
{{
baseData
.
productName
}}
</p>
</Col>
<Col
span=
"8"
>
<span
class=
"fwBold"
>
{{
l
(
"drawnNumber"
)
}}
</span>
<p>
{{
baseData
.
drawnNumber
}}
</p>
</Col>
</Row>
<Row>
<Col
span=
"8"
>
<span
class=
"fwBold"
>
{{
l
(
'batchNumber'
)
}}
</span>
<p>
{{
baseData
.
batchNumber
}}
</p>
</Col>
<Col
span=
"8"
>
<span
class=
"fwBold"
>
{{
l
(
'projectNumber'
)
}}
</span>
<p>
{{
baseData
.
projectNumber
}}
</p>
</Col>
<Col
span=
"8"
>
<span
class=
"fwBold"
>
{{
l
(
'urgencyLevel'
)
}}
</span>
<Col
span=
"8"
>
<span
class=
"fwBold"
>
{{
l
(
"batchNumber"
)
}}
</span>
<p>
{{
baseData
.
batchNumber
}}
</p>
</Col>
<Col
span=
"8"
>
<span
class=
"fwBold"
>
{{
l
(
"projectNumber"
)
}}
</span>
<p>
{{
baseData
.
projectNumber
}}
</p>
</Col>
<Col
span=
"8"
>
<span
class=
"fwBold"
>
{{
l
(
"urgencyLevel"
)
}}
</span>
<p>
<state
code=
"plan.order.urgencyLevel"
:value=
"baseData.urgencyLevel"
type=
"text"
></state>
<state
code=
"plan.order.urgencyLevel"
:value=
"baseData.urgencyLevel"
type=
"text"
></state>
</p>
</Col>
</Col>
</Row>
<Row>
<Col
span=
"8"
>
<span
class=
"fwBold"
>
{{
l
(
'demandStartDate'
)
}}
</span>
<Col
span=
"8"
>
<span
class=
"fwBold"
>
{{
l
(
"demandStartDate"
)
}}
</span>
<p>
<DTSpan
type=
"date"
v-model=
"baseData.demandStartDate"
></DTSpan>
<DTSpan
type=
"date"
v-model=
"baseData.demandStartDate"
></DTSpan>
</p>
</Col>
<Col
span=
"8"
>
<span
class=
"fwBold"
>
{{
l
(
'demandFinishDate'
)
}}
</span>
</Col>
<Col
span=
"8"
>
<span
class=
"fwBold"
>
{{
l
(
"demandFinishDate"
)
}}
</span>
<p>
<DTSpan
type=
"date"
v-model=
"baseData.demandFinishDate"
></DTSpan>
<DTSpan
type=
"date"
v-model=
"baseData.demandFinishDate"
></DTSpan>
</p>
</Col>
<Col
span=
"8"
>
<span
class=
"fwBold"
>
{{
l
(
'taskRequire'
)
}}
</span>
<p>
{{
baseData
.
taskRequire
}}
</p>
</Col>
</Col>
<Col
span=
"8"
>
<span
class=
"fwBold"
>
{{
l
(
"taskRequire"
)
}}
</span>
<p>
{{
baseData
.
taskRequire
}}
</p>
</Col>
</Row>
<Row
class=
"lastRow"
>
<Col
span=
"24"
>
<span
class=
"fwBold"
>
{{
l
(
'remark'
)
}}
</span>
<p>
{{
baseData
.
remark
}}
</p>
</Col>
<Col
span=
"24"
>
<span
class=
"fwBold"
>
{{
l
(
"remark"
)
}}
</span>
<p>
{{
baseData
.
remark
}}
</p>
</Col>
</Row>
</div>
</div>
</
template
>
<
script
>
export
default
{
props
:
[
'baseData'
],
data
()
{
return
{
themeBg
:
'light'
,
basicData
:
{},
}
},
methods
:
{
l
(
key
)
{
key
=
"mes_plan"
+
"."
+
key
;
return
this
.
$t
(
key
);
}
props
:
[
"baseData"
],
data
()
{
return
{
themeBg
:
"light"
,
basicData
:
{},
};
},
methods
:
{
l
(
key
)
{
key
=
"mes_plan"
+
"."
+
key
;
return
this
.
$t
(
key
);
},
}
},
};
</
script
>
<
style
lang=
"less"
>
.orderDetail {
line-height: 30px;
width: 9
0%;
margin: 0 auto;
line-height: 30px;
width: 10
0%;
margin: 0 auto;
.ivu-row {
padding-top: 20px;
padding-bottom: 20px;
border-bottom: #ccc solid 1px;
}
.ivu-row {
padding-top: 20px;
padding-bottom: 20px;
margin-right: 25px;
border-bottom: #ccc solid 1px;
}
.lastRow {
border-bottom: none;
}
.lastRow {
border-bottom: none;
}
}
</
style
>
pages/qc/dataTrace/components/mainView.vue
View file @
6f24cdd2
<
template
>
<div
class
>
<Tabs
:animated=
"false"
@
on-click=
"tabChange"
value=
"1"
>
<Tabs
:animated=
"false"
@
on-click=
"tabChange"
value=
'1'
>
<TabPane
label=
"工艺信息"
name=
"1"
>
<Form
:model=
"craftData"
:label-width=
"130"
inline
>
<Row>
...
...
@@ -74,25 +74,27 @@
</Form>
</TabPane>
-->
<TabPane
label=
"质量信息"
name=
"3"
>
<
orderqcrecord
ref=
"orderqcrecord1"
:items=
"items"
/>
<
Orderqcrecord
ref=
"orderqcrecord1"
:items=
"items"
/>
</TabPane>
<TabPane
label=
"配套数据"
name=
"4"
>
<
!--
<orderqcrecord
ref=
"orderqcrecord1"
/>
--
>
<
Matching
ref=
"matching"
:items=
"items"
/
>
</TabPane>
</Tabs>
</div>
</
template
>
<
script
>
import
service
from
"@/plugins/request"
;
import
orderqcrecord
from
"./orderqcrecord.vue"
;
import
Orderqcrecord
from
"./orderqcrecord.vue"
;
import
Matching
from
"./matching.vue"
;
export
default
{
components
:
{
orderqcrecord
},
components
:
{
Orderqcrecord
,
Matching
},
props
:
{
baseData
:
{
type
:
[
String
,
Number
,
Array
,
Object
],
},
items
:
{
mesCode
Id
:
{
order
Id
:
{
type
:
Number
,
},
headerid
:
{
...
...
@@ -108,8 +110,9 @@ export default {
},
data
()
{
return
{
selectName
:
"1"
,
themeBg
:
"light"
,
craftData
:
this
.
items
.
craftData
,
//工艺信息
craftData
:
this
.
items
.
craftData
,
//工艺信息
equipmentData
:
{},
//设备信息
headerid
:
""
,
//暂存传字段
routingType
:
""
,
//工艺类型(主/专业)
...
...
@@ -121,22 +124,22 @@ export default {
},
methods
:
{
// 获取设备信息 10020 /equipinfo/getlistall
getlistall
(
equipids
)
{
let
url02
=
`
${
systemUrl
}
/equipinfo/getlistall?equipids=`
+
equipids
;
service
.
get
(
`
${
url02
}
`
).
then
((
res
)
=>
{
if
(
res
.
success
)
{
if
(
res
.
result
.
length
!=
0
)
{
this
.
equipmentData
=
res
.
result
[
0
];
}
else
{
this
.
equipmentData
=
[];
console
.
log
(
"获取主工艺设备信息为空."
);
}
}
else
{
this
.
equipmentData
=
[];
console
.
log
(
"获取主工艺设备数据失败."
);
}
});
},
//
getlistall(equipids) {
//
let url02 = `${systemUrl}/equipinfo/getlistall?equipids=` + equipids;
//
service.get(`${url02}`).then((res) => {
//
if (res.success) {
//
if (res.result.length != 0) {
//
this.equipmentData = res.result[0];
//
} else {
//
this.equipmentData = [];
//
console.log("获取主工艺设备信息为空.");
//
}
//
} else {
//
this.equipmentData = [];
//
console.log("获取主工艺设备数据失败.");
//
}
//
});
//
},
getqc
(
executeid
)
{
this
.
$refs
.
orderqcrecord1
.
qcdatasearch
.
execute_id
=
executeid
;
},
...
...
@@ -146,22 +149,22 @@ export default {
this
.
$refs
.
orderqcrecord1
.
qcdatasearch
.
SkipCount
=
0
;
this
.
$refs
.
orderqcrecord1
.
onqcpage
();
},
tabChange
()
{
// console.log("切换tab"
)
tabChange
(
name
)
{
console
.
log
(
name
)
},
},
mounted
()
{},
watch
:
{
baseData
:
{
handler
(
v
,
o
)
{
// this.pamasId = v.id
// console.log(v.id)
// this.loaddata(v.id)
// console.info(o.id)
},
deep
:
true
,
},
},
//
watch: {
//
baseData: {
//
handler(v, o) {
//
// this.pamasId = v.id
//
// console.log(v.id)
//
// this.loaddata(v.id)
//
// console.info(o.id)
//
},
//
deep: true,
//
},
//
},
};
</
script
>
<
style
scoped
>
...
...
pages/qc/dataTrace/components/matching.vue
0 → 100644
View file @
6f24cdd2
<
template
>
<div>
<Table
border
:columns=
"cols"
:data=
"datas"
class=
"tableCommon"
>
</Table>
</div>
</
template
>
<
script
>
import
service
from
"@/plugins/request"
;
export
default
{
data
()
{
return
{
datas
:
[],
cols
:
[
{
key
:
"routingDetailNo"
,
title
:
this
.
l
(
"routingDetailNo"
),
align
:
"left"
,
width
:
80
,
},
{
key
:
"routingDetailName"
,
title
:
this
.
l
(
"routingDetailName"
),
align
:
"left"
,
},
{
key
:
"nameMaterial"
,
title
:
this
.
l
(
"nameMaterial"
),
align
:
"left"
,
},
{
key
:
"materialNumber"
,
title
:
this
.
l
(
"materialNumber"
),
align
:
"left"
,
width
:
150
,
},
{
key
:
"totalCount"
,
title
:
this
.
l
(
"totalCount"
),
align
:
"left"
,
},
{
key
:
"applicationNumber"
,
title
:
this
.
l
(
"applicationNumber"
),
align
:
"right"
,
},
{
key
:
""
,
title
:
this
.
l
(
"count3"
),
align
:
"right"
,
width
:
150
,
width
:
150
,
render
:
(
h
,
params
)
=>
{
return
h
(
"div"
,
{},
params
.
row
.
receiveNumber
+
"/"
+
params
.
row
.
outStockNumber
);
},
},
{
key
:
"creatorUserId"
,
title
:
"领用人"
,
align
:
"center"
,
width
:
150
,
render
:
(
h
,
params
)
=>
{
if
(
params
.
row
.
creatorUserId
)
{
return
h
(
"User"
,
{
props
:
{
value
:
params
.
row
.
creatorUserId
,
},
});
}
},
},
// {
// key: "remark",
// title: this.l("remark"),
// align: "left",
// },
],
};
},
async
fetch
({
store
,
params
})
{
await
store
.
dispatch
(
"loadDictionary"
);
// 加载数据字典
},
props
:
{
items
:
{
orderId
:
{
type
:
Number
,
},
headerid
:
{
type
:
Number
,
},
routingType
:
{
type
:
Number
,
},
craftData
:
{
type
:
Object
,
},
},
},
mounted
()
{
this
.
matchdetail
();
},
methods
:
{
matchdetail
()
{
//配套审核单列表
let
orderId
=
this
.
items
.
orderId
;
let
url
=
`
${
technologyUrl
}
materiallist/matchdetaillist?id=`
+
orderId
;
service
.
get
(
`
${
url
}
`
).
then
((
res
)
=>
{
if
(
res
.
result
)
{
this
.
datas
=
[];
let
suport
=
[];
res
.
result
.
forEach
((
e
,
index
)
=>
{
// console.log(e);
if
(
this
.
items
.
headerid
==
e
.
routingHeaderId
)
{
suport
=
e
.
suport
;
this
.
datas
=
suport
;
}
});
}
// console.log(this.datas);
});
},
l
(
key
)
{
let
vkey
=
"support_item"
+
"."
+
key
;
return
this
.
$t
(
vkey
)
||
key
;
},
},
};
</
script
>
\ No newline at end of file
pages/qc/dataTrace/components/orderqcrecord.vue
View file @
6f24cdd2
...
...
@@ -159,7 +159,7 @@ export default {
components
:
{
entryrecordfiles
,
entryrecordMovie
,
entryrecorddata
},
props
:
{
items
:
{
mesCode
Id
:
{
order
Id
:
{
type
:
Number
,
},
headerid
:
{
...
...
@@ -258,6 +258,7 @@ export default {
},
mounted
()
{
this
.
getmainorder
();
},
watch
:
{},
methods
:
{
...
...
@@ -269,12 +270,12 @@ export default {
// this.$refs.orderqcrecord1.onqcpage()
},
getmainorder
()
{
let
mesCodeId
=
this
.
items
.
mesCode
Id
;
let
orderId
=
this
.
items
.
order
Id
;
let
headerid
=
this
.
items
.
headerid
;
let
routingType
=
this
.
items
.
routingType
;
let
url01
=
`
${
PlanUrl
}
/orderexecute/getorderproductandequip?orderId=`
+
mesCode
Id
+
order
Id
+
`&headerid=`
+
headerid
+
`&routingType=`
+
...
...
@@ -311,6 +312,7 @@ export default {
console
.
log
(
err
);
});
},
onPageChanged
(
page_index
)
{
this
.
pageindex
=
page_index
;
this
.
onqcpage
();
...
...
pages/qc/dataTrace/components/reviewCount.vue
View file @
6f24cdd2
<
template
>
<div
class=
"reve_cont"
>
<Row>
<Col
span=
"4"
>
<Menu
:active-name=
"actNum"
ref=
"actNum"
class=
"menuBg"
@
on-select=
"openView"
:theme=
"themeBg"
>
<MenuItem
name=
"1"
replace
>
基本信息
</MenuItem>
<MenuItem
<Col
span=
"5"
>
<ul>
<li
:class=
"isactive == -1 ? 'addclass' : ''"
@
click=
"listData1"
>
基本信息
</li>
<li
v-for=
"(li, index) in nameList"
:key=
"index"
:name=
"index + 2
"
replace
@
click=
"listData2(li, index)
"
:class=
"isactive == index ? 'addclass' : ''"
>
{{
li
.
name
}}
</
MenuItem
>
</
Menu
>
</
li
>
</
ul
>
</Col>
<Col
span=
"
20
"
class=
"revieweBox"
>
<Col
span=
"
19
"
class=
"revieweBox"
>
<component
:is=
"detail"
:baseData=
"basicData"
...
...
@@ -29,8 +25,6 @@
@
on-ok=
"ok"
/>
<!--
<basicView
ref=
"basicView"
:baseData=
"basicData"
v-show=
"basicmodal"
/>
<mainView
ref=
"mainView"
:baseData=
"basicData"
v-show=
"mainmodal"
/>
-->
<!--
<dispatched
ref=
"dispatched"
:baseData=
"basicData"
v-show=
"dispatchedmodal"
/>
-->
</Col>
</Row>
...
...
@@ -39,15 +33,12 @@
<
script
>
import
service
from
"@/plugins/request"
;
import
basicView
from
"./basicView.vue"
;
import
mainView
from
"./mainView.vue"
;
import
dispatched
from
"./dispatched.vue"
;
//import dispatched from "./dispatched.vue";
export
default
{
components
:
{
basicView
,
mainView
,
dispatched
,
},
// components: {
// dispatched,
// },
props
:
{
basicData
:
null
,
actValue
:
{
...
...
@@ -55,18 +46,16 @@ export default {
default
:
1
,
},
},
created
()
{
this
.
detail
=
()
=>
import
(
"./basicView"
);
this
.
openView
(
this
.
actNum
);
},
data
()
{
return
{
items
:
{
mesCode
Id
:
this
.
basicData
.
id
,
order
Id
:
this
.
basicData
.
id
,
headerid
:
0
,
routingType
:
0
,
craftData
:
{},
},
isactive
:
-
1
,
nameList
:
[],
detail
:
null
,
actNum
:
"1"
,
...
...
@@ -82,35 +71,43 @@ export default {
mainexecuteid
:
0
,
};
},
created
()
{
this
.
isactive
=
-
1
;
this
.
detail
=
()
=>
import
(
"./basicView"
);
},
mounted
()
{
this
.
actNum
=
"1"
;
//
this.actNum = "1";
this
.
loaddata
(
this
.
basicData
.
id
);
},
methods
:
{
listData1
()
{
this
.
items
.
orderId
=
this
.
basicData
.
id
;
this
.
isactive
=
-
1
;
this
.
detail
=
()
=>
import
(
"./basicView"
);
},
listData2
(
e
,
index
)
{
// console.log(e)
this
.
items
.
orderId
=
this
.
basicData
.
id
;
this
.
items
.
craftData
=
e
;
this
.
items
.
headerid
=
e
.
id
;
this
.
items
.
routingType
=
e
.
routingType
;
this
.
isactive
=
index
;
this
.
detail
=
()
=>
import
(
"./mainView"
);
},
loaddata
(
pamasId
)
{
this
.
basicmodal
=
true
;
this
.
mainmodal
=
false
;
// this.dispatchedmodal= false;
// console.warn(pamasId) 获取主工艺信息 10030
let
url
=
`
${
technologyUrl
}
orderrouting/getordersheaderinfo?orderId=`
+
pamasId
;
if
(
pamasId
)
{
service
.
get
(
`
${
url
}
`
).
then
((
response
)
=>
{
console
.
log
(
response
);
if
(
response
.
result
.
length
>
0
)
{
this
.
nameList
=
response
.
result
;
if
(
response
.
result
[
0
])
{
this
.
$refs
.
mainView
.
craftData
=
response
.
result
[
0
];
//工艺信息
// this.headerid = response.result[0].id;
// this.routingType = response.result[0].routingType;
this
.
getmainorder
(
pamasId
);
}
if
(
response
.
result
[
1
])
{
this
.
$refs
.
dispatched
.
craftData
=
response
.
result
[
1
];
// this.diHeaderid = response.result[1].id;
// this.diRoutingType = response.result[1].routingType;
this
.
getdisorder
(
pamasId
);
}
}
else
{
console
.
log
(
"获取工艺信息为空."
);
...
...
@@ -120,114 +117,20 @@ export default {
});
}
},
// 获取产品号和设备id orderexecute/getorderproductandequip 10050
// getmainorder(pamasId) {
// let headerid = this.headerid;
// let routingType = this.routingType;
// let url01 =
// `${PlanUrl}/orderexecute/getorderproductandequip?orderId=` +
// pamasId +
// `&headerid=` +
// headerid +
// `&routingType=` +
// routingType;
// service
// .get(`${url01}`)
// .then((res) => {
// if (res.success) {
// if (res.result.equipids) {
// let equipids = res.result.equipids;
// this.mainexecuteid = res.result.executeid;
// this.$refs.mainView.getlistall(equipids);
// this.$refs.mainView.getqc(this.mainexecuteid);
// let bandleList = res.result.productCode;
// let codeList = []; // 编号List
// bandleList.map((item, index) => {
// codeList.push(item.productcodes);
// });
// // this.$refs.mainView.mainCodeList = codeList;
// console.warn(codeList);
// } else {
// console.log("获取主工艺设备信息数据为空.");
// }
// } else {
// console.log("获取主工艺设备信息数据失败.");
// }
// })
// .catch((err) => {
// console.log(err);
// });
// },
// getdisorder(pamasId) {
// let diHeaderid = this.diHeaderid;
// let diRoutingType = this.diRoutingType;
// let url02 =
// `${PlanUrl}/orderexecute/getorderproductandequip?orderId=` +
// pamasId +
// `&headerid=` +
// diHeaderid +
// `&routingType=` +
// diRoutingType;
// service
// .get(`${url02}`)
// .then((res) => {
// if (res.success) {
// if (res.result.equipids) {
// let equipids = res.result.equipids;
// this.disexecuteid = res.result.executeid;
// this.$refs.dispatched.getlistall(equipids);
// this.$refs.dispatched.getqc(this.disexecuteid);
// let bandleList = res.result.productCode;
// let boardList = []; // 板次List
// bandleList.map((item, index) => {
// boardList.push(item.boardNumber);
// });
// this.$refs.dispatched.disCodeList = boardList;
// console.warn(boardList);
// } else {
// console.log("获取专业工艺信息数据为空.");
// }
// } else {
// console.log("获取专业工艺信息数据失败.");
// }
// })
// .catch((err) => {
// console.log(err);
// });
// },
// 更换左侧
openView
(
v
)
{
console
.
log
(
v
);
if
(
v
==
1
)
{
this
.
detail
=
()
=>
import
(
"./basicView"
);
// this.this.basicmodal = true;
// this.mainmodal = false;
}
else
{
let
i
=
v
-
2
;
this
.
nameList
.
forEach
((
e
,
index
)
=>
{
if
(
i
==
index
)
{
this
.
items
.
craftData
=
e
;
this
.
items
.
headerid
=
e
.
id
;
this
.
items
.
routingType
=
e
.
routingType
;
}
});
this
.
detail
=
()
=>
import
(
"./mainView"
);
// this.$refs.mainView.getqc(this.mainexecuteid);
}
cancel
()
{
this
.
detail
=
null
;
},
ok
()
{
this
.
detail
=
null
;
},
cancel
()
{},
ok
()
{},
},
watch
:
{
basicData
:
{
handler
(
v
,
o
)
{
this
.
loaddata
(
v
.
id
);
if
(
v
)
{
this
.
actNum
==
"1"
;
this
.
openView
(
this
.
actNum
);
this
.
items
.
orderId
=
v
;
}
},
deep
:
true
,
...
...
@@ -236,7 +139,27 @@ export default {
};
</
script
>
<
style
scoped
>
<
style
scoped
lang=
"less"
>
.reve_cont {
ul {
height: 630px;
border-right: 1px solid #eee;
overflow: auto;
li {
height: 35px;
line-height: 35px;
padding: 0 15px;
cursor: pointer;
}
}
.addclass {
height: 35px;
line-height: 35px;
background-color: #f0faff;
color: #2d8cf0;
border-right: 2px solid #2d8cf0;
}
}
.menuBg {
background: none;
height: 630px;
...
...
pages/qc/dataTrace/index.vue
View file @
6f24cdd2
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment