clay : 添加签名,评分两个组件

This commit is contained in:
clay 2023-02-25 19:56:47 +08:00
parent a59157a525
commit 219d33b07e
17 changed files with 15337 additions and 494 deletions

File diff suppressed because it is too large Load Diff

View File

@ -21,6 +21,7 @@
"signature_pad": "^3.0.0-beta.4",
"trim-canvas": "^0.1.2",
"vue": "^2.6.11",
"vue-esign": "^1.1.4",
"vue-router": "^3.4.3",
"vuedraggable": "^2.24.1",
"vuex": "^3.5.1"

View File

@ -91,8 +91,7 @@
<el-radio-button label="E">编辑</el-radio-button>
<el-radio-button label="R">查看</el-radio-button>
</el-radio-group>
<!--todo 表单渲染-->
<form-render-view v-if="viewFormVisibleRender" ref="form" :form-items="forms" v-model="formData" :is-preview="true" :model="formPreviewModel"/>
<form-render-view v-if="viewFormVisibleRender" ref="form" :form-items="forms" v-model="formValue" :is-preview="true" :model="formPreviewModel"/>
</w-dialog>
</el-container>
</template>
@ -109,7 +108,7 @@ export default {
components: {draggable, FormComponentConfig, FormDesignRender, FormRenderView},
data() {
return {
formData: {},
// formData: {},
libSelect: 0,
viewFormVisible: false,
viewFormVisibleRender: true,
@ -205,8 +204,8 @@ export default {
this.formValue=this.$refs.form.value
})
for (const key in this.formValue) {
if(this.formValue[key]!=undefined){
this.formValue[key]=[]
if(this.formValue[key]!==undefined){
this.formValue[key]=undefined
}
}
},

View File

@ -30,7 +30,6 @@ export default {
return this.$store.state.parentMap;
},
dom() {
console.log(this.$store.state.design)
return this.$store.state.design.process;
},
viewer(){

View File

@ -14,16 +14,17 @@ let Location = () => import('./components/Location.vue')
let MoneyInput = () => import('./components/MoneyInput.vue')
let DeptPicker = () => import('./components/DeptPicker.vue')
let UserPicker = () => import('./components/UserPicker.vue')
let SignPanel = () => import('./components/SignPannel.vue')
let RatePicker = () => import('./components/RatePicker.vue')
let SpanLayout = () => import('./components/SpanLayout.vue')
let TableList = () => import('./components/TableList.vue')
let SignPanel = () => import('./components/SignPanel.vue')
export default {
//基础组件
TextInput, NumberInput, AmountInput, TextareaInput, SelectInput, MultipleSelect,
DateTime, DateTimeRange, UserPicker, DeptPicker,
DateTime, DateTimeRange, UserPicker, DeptPicker,RatePicker,
//高级组件
Description, FileUpload, ImageUpload, MoneyInput, Location, SignPanel,
SpanLayout, TableList
SpanLayout, TableList,
}

View File

@ -6,6 +6,7 @@ export const ValueType = {
date: 'Date',
user: 'User',
dept: 'Dept',
star: 'star',
dateRange: 'DateRange'
}
@ -179,6 +180,22 @@ export const baseComponents = [
multiple: false
}
},
{
title: '评分',
name: 'RatePicker',
icon: 'el-icon-star-off',
value: '',
valueType: ValueType.star,
props: {
color: '#f0a732',
max: 5,
required: false,
enablePrint: true,
showScore: true,
enableHalf: true,
placeholder: undefined,
}
},
{
title: '说明文字',
name: 'Description',
@ -210,7 +227,20 @@ export const baseComponents = [
maxSize: 0, //最大条数为0则不限制
columns:[] //列设置
}
}
},
{
title: '签名',
name: 'SignPanel',
icon: 'el-icon-edit',
value: [],
valueType: ValueType.string,
props: {
required: false,
enablePrint: true,
isCrop: true,
lineColor: '#ff0000',
}
},
]
}
]

View File

@ -1,6 +1,9 @@
<template>
<div>
<el-form label-width="90px" v-if="form.name !== 'SpanLayout'">
<el-form-item label="表单ID">
<el-input size="small" clearable v-model="form.id" disabled/>
</el-form-item>
<el-form-item label="表单名称">
<el-input size="small" clearable v-model="form.title"/>
</el-form-item>
@ -14,7 +17,6 @@
</el-form>
<el-empty v-else description="当前组件不支持配置"></el-empty>
</div>
</template>
<script>
@ -33,6 +35,8 @@ import MoneyInput from './config/MoneyInputConfig.vue'
import DeptPicker from './config/OrgPickerConfig.vue'
import UserPicker from './config/OrgPickerConfig.vue'
import TableList from './config/TableListConfig.vue'
import SignPanel from './config/SignPanelConfig.vue'
import RatePicker from './config/RatePickerConfig.vue'
export default {
name: "FormComponentConfig",
@ -51,7 +55,9 @@ export default {
MoneyInput,
DeptPicker,
UserPicker,
TableList
TableList,
SignPanel,
RatePicker
},
props:{},
computed:{

View File

@ -36,7 +36,7 @@ export default {
rules: {},
}
},
mounted() {
created() {
this.loadFormConfig(this.formItems)
},
computed: {
@ -51,6 +51,7 @@ export default {
},
methods: {
validate(call) {
console.log("我被触发了")
let success = true
this.$refs.form.validate(valid => {
success = valid

View File

@ -1,5 +1,5 @@
<template>
<el-form ref="form" class="process-form" label-position="top" :model="_value">
<el-form class="process-form" label-position="top" :rules="rules" :model="_value">
<div v-for="(item, index) in formItems" :key="item.name + index">
<el-form-item v-if="item.name !== 'SpanLayout' && item.name !== 'Description'"
:prop="item.id" :label="item.title">
@ -30,19 +30,24 @@ export default {
return {}
}
},
model:{
model: {
type: String,
default:() => {
default: () => {
return "R"
}
},
isPreview:{
isPreview: {
type: Boolean,
default:() => {
default: () => {
return false
}
}
},
data() {
return {
rules: {},
}
},
computed: {
_value: {
get() {
@ -53,7 +58,7 @@ export default {
}
}
},
mounted() {
created() {
this.loadFormConfig(this.formItems)
},
methods: {
@ -63,9 +68,18 @@ export default {
this.loadFormConfig(item.props.items)
} else {
this.$set(this._value, item.id, this.value[item.id])
if (this.isPreview){
if (this.isPreview) {
this.$set(item, 'perm', this.model)
}
if (item.perm === 'E') {
if (item.props.required) {
this.$set(this.rules, item.id, [{
type: item.valueType === 'Array' ? 'array' : undefined,
required: true,
message: `请填写${item.title}`, trigger: 'blur'
}])
}
}
}
})
}
@ -78,6 +92,7 @@ export default {
margin: 15px 0;
padding: 10px 10px 1px 10px;
background: #fff;
/deep/ .el-form-item__label {
padding: 0 0;
}
@ -86,6 +101,7 @@ export default {
padding-left: 5px;
line-height: 30px;
}
/deep/ .el-form-item {
margin-bottom: 10px;
}

View File

@ -0,0 +1,79 @@
<template>
<div>
<template v-if="mode === 'DESIGN'">
<el-rate
disabled
:show-score="showScore"
:allow-half="enableHalf"
:text-color="color"
text-color="#ff9900"
score-template="{value}">
</el-rate>
<p>{{ placeholder }}</p>
</template>
<template v-else>
<template v-if="perm === 'E'">
<el-rate
v-model="_value"
:show-score="showScore"
:allow-half="enableHalf"
:text-color="color"
score-template="{value}">
</el-rate>
<p>{{ placeholder }}</p>
</template>
<template v-else-if="perm === 'R'">
<el-rate
v-model="_value"
disabled
:show-score="showScore"
:allow-half="enableHalf"
:text-color="color"
score-template="{value}">
</el-rate>
</template>
</template>
</div>
</template>
<script>
import componentMinxins from '../ComponentMinxins'
export default {
mixins: [componentMinxins],
name: "RatePicker",
props: {
value: {
type: Number,
default: 0
},
perm: {
type: String,
default: 'E'
},
color: {
type: String,
default: '#f0a732'
},
placeholder: {
type: String,
default: '请打分!'
},
enableHalf: {
type: Boolean,
default: true
},
showScore: {
type: Boolean,
default: true
},
}
}
</script>
<style scoped>
</style>

View File

@ -0,0 +1,114 @@
<template>
<div>
<template v-if="mode === 'DESIGN'">
<el-icon class="el-icon-location-information"/>
请签名
</template>
<template v-else>
<template v-if="perm === 'E'">
<div v-if="!_value">
<el-button icon="el-icon-edit" @click="doSign">请签字</el-button>
</div>
<div v-else>
<div>
<el-image fit="contain" class="sign-border-preview" style="width: 200px; height: 100px" @click="doSign"
:src="_value"/>
</div>
<div>
点击签名重签
</div>
</div>
</template>
<template v-else-if="perm === 'R'">
<div v-if="_value">
<el-image fit="contain" style="width: 200px; height: 100px" :src="_value"/>
</div>
<div>
请签名
</div>
</template>
</template>
<el-dialog title="请使用鼠标签字" width="800px" :visible.sync="sign.open" @close="signClose" append-to-body>
<div class="sign-border">
<vue-esign v-if="sign.open" ref="sign" :width="800" :height="300" :isCrop="isCrop"
:lineWidth="sign.lineWidth" :lineColor="sign.lineColor"
:bgColor.sync="sign.bgColor"/>
</div>
<div slot="footer">
<el-button size="mini" @click="signClose">取消</el-button>
<el-button size="mini" type="primary" @click="handleGenerate">确认</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import vueEsign from 'vue-esign'
import componentMinxins from '../ComponentMinxins'
export default {
mixins: [componentMinxins],
name: "SignPanel",
components: {vueEsign},
props: {
value: {
type: String,
default: null
},
perm: {
type: String,
default: 'E'
},
isCrop: {
type: Boolean,
default: false
},
lineColor: {
type: String,
default: '#000000'
}
},
data() {
return {
sign: {
open: false,
lineWidth: 6,
bgColor: '',
}
}
},
methods: {
signClose() {
this.sign.open = false
this.$refs.sign.reset()
},
doSign() {
this.sign.open = true
},
handleGenerate() {
this.$refs.sign.generate().then(res => {
this._value = res
this.sign.open = false
}).catch(err => {
alert(err) // 'Not Signned'
})
}
}
}
</script>
<style scoped>
.sign-border {
border: 1px dashed #2b2b2b;
}
.sign-border-preview {
border: 1px solid #ffffff;
}
.sign-border-preview:hover {
border: 1px dashed #1989fa;
}
</style>

View File

@ -1,18 +0,0 @@
<template>
</template>
<script>
export default {
name: "SignPannel",
components: {},
data() {
return {}
},
methods: {}
}
</script>
<style scoped>
</style>

View File

@ -0,0 +1,39 @@
<template>
<div>
<el-form-item label="提示文字">
<el-input size="small" v-model="value.placeholder" placeholder="请设置提示语"/>
</el-form-item>
<el-form-item label="最大分值">
<el-input-number size="small" :min="1" v-model="value.max" />
</el-form-item>
<el-form-item label="允许半分">
<el-switch v-model="value.enableHalf"></el-switch>
</el-form-item>
<el-form-item label="显示分值">
<el-switch v-model="value.showScore"></el-switch>
</el-form-item>
</div>
</template>
<script>
export default {
name: "RatePickerConfig",
components: {},
props:{
value:{
type: Object,
default: ()=>{
return {}
}
}
},
data() {
return {}
},
methods: {}
}
</script>
<style scoped>
</style>

View File

@ -0,0 +1,30 @@
<template>
<div>
<el-form-item label="是否裁剪">
<el-switch v-model="value.isCrop"></el-switch>
</el-form-item>
</div>
</template>
<script>
export default {
name: "SignPanelConfig",
components: {},
props:{
value:{
type: Object,
default: ()=>{
return {}
}
}
},
data() {
return {}
},
methods: {}
}
</script>
<style scoped>
</style>

View File

@ -109,44 +109,52 @@ export default {
for (let operation of this.operationList) {
let state = operation.state
let type = operation.operation
//
if (state === 'create') {
this.$set(operation, "icon", "el-icon-check")
this.$set(operation, "color", "#0bbd87")
this.$set(operation,"remark",operation.userInfo.name)
this.$set(operation, "remark", operation.userInfo.name)
}
//
if (state === 'agree') {
this.$set(operation, "icon", "el-icon-check")
this.$set(operation, "color", "#0bbd87")
this.$set(operation,"remark",operation.userInfo.name + ' (已同意)')
this.$set(operation, "remark", operation.userInfo.name + ' (已同意)')
}
//
if (state === 'process') {
this.$set(operation, "icon", "el-icon-loading")
this.$set(operation, "color", "#f78f5f")
this.$set(operation,"remark",operation.userInfo.name + ' (处理中)')
this.$set(operation, "remark", operation.userInfo.name + ' (处理中)')
}
//
if (type === 'cc') {
this.$set(operation, "icon", "el-icon-s-promotion")
this.$set(operation, "color", "#3395f8")
this.$set(operation,"remark",operation.userInfo.name + ' (抄送成功)')
this.$set(operation, "remark", operation.userInfo.name + ' (抄送成功)')
}
//
if (state === 'comment') {
this.$set(operation, "icon", "el-icon-chat-dot-round")
this.$set(operation, "color", "#0bbd87")
this.$set(operation,"remark",operation.userInfo.name + ' (添加了评论)')
this.$set(operation, "remark", operation.userInfo.name + ' (添加了评论)')
}
//
if (state === 'refuse' && type === 'comment') {
this.$set(operation, "icon", "el-icon-chat-dot-round")
this.$set(operation, "color", "#f56c6c")
this.$set(operation,"remark",operation.userInfo.name + ' (填写拒绝理由)')
this.$set(operation, "remark", operation.userInfo.name + ' (填写拒绝理由)')
}
//
if (state === 'refuse' && type === 'opinion') {
this.$set(operation, "icon", "el-icon-close")
this.$set(operation, "color", "#f56c6c")
this.$set(operation, "remark", operation.userInfo.name + ' (拒绝)')
}
}
},
methods: {
//
getAttachmentList(attachments, image) {
let result = [];
for (let attachment of attachments) {

View File

@ -2,7 +2,7 @@
<div v-loading="loading" class="initiate_process">
<div v-if="!loading" style="min-width: 338px;">
<!--渲染表单-->
<form-render class="process-form" ref="form" :form-items="processDefinition.formItems" v-model="formData"/>
<form-render class="process-form" ref="initiateForm" :form-items="processDefinition.formItems" v-model="formData"/>
</div>
<div style="display: flex;justify-content: center;flex-direction: column;min-width: 1036px;">
<span style="font-size: 18px;text-align: center;padding-top: 20px;">审批流程</span>
@ -64,7 +64,6 @@ export default {
methods: {
loadProcessDefinitionInfo(processDefinitionKey) {
getInitiateInfo(processDefinitionKey).then(res => {
console.log(res);
let processDefinition = res.data;
this.processDefinition = processDefinition;
//
@ -75,7 +74,8 @@ export default {
});
},
validate(call) {
this.$refs.form.validate(call);
console.log("我被调用了")
this.$refs.initiateForm.validate(call);
}
}
};

View File

@ -130,7 +130,6 @@ export default {
this.openItemDl = false
this.$message.success(res.msg)
this.$refs.disposalTask.getList()
})
} else {
this.$message.warning("请完善表单😥")