hookehuyr

✨ feat: 电子签名验证功能优化

1 <!-- 1 <!--
2 * @Date: 2022-09-06 16:29:31 2 * @Date: 2022-09-06 16:29:31
3 * @LastEditors: hookehuyr hookehuyr@gmail.com 3 * @LastEditors: hookehuyr hookehuyr@gmail.com
4 - * @LastEditTime: 2022-09-07 15:58:45 4 + * @LastEditTime: 2022-09-07 16:50:16
5 * @FilePath: /data-table/src/components/SignField/index.vue 5 * @FilePath: /data-table/src/components/SignField/index.vue
6 * @Description: 电子签名控件 6 * @Description: 电子签名控件
7 --> 7 -->
8 <template> 8 <template>
9 <div class="sign-page"> 9 <div class="sign-page">
10 - <div class="label">{{ item.label }}<span v-if="item.required">&nbsp;*</span></div> 10 + <div class="label">{{ item.label }}{{ valid }}<span v-if="item.required">&nbsp;*</span></div>
11 <div style="padding: 1rem; position: relative;"> 11 <div style="padding: 1rem; position: relative;">
12 <!-- <div style="padding: 1rem; position: relative; height: 150px; background-color: #FCFCFC;border: 1px solid #EAEAEA; border-radius: 5px;"> --> 12 <!-- <div style="padding: 1rem; position: relative; height: 150px; background-color: #FCFCFC;border: 1px solid #EAEAEA; border-radius: 5px;"> -->
13 <vue-esign ref="esign" class="sign-wrapper" style="" :isCrop="isCrop" :lineWidth="lineWidth" 13 <vue-esign ref="esign" class="sign-wrapper" style="" :isCrop="isCrop" :lineWidth="lineWidth"
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
33 <van-button type="danger" block @click="handleReset">删除签名</van-button> 33 <van-button type="danger" block @click="handleReset">删除签名</van-button>
34 </div> 34 </div>
35 </div> 35 </div>
36 + <div v-if="show_empty" class="van-field__error-message" style="padding: 0 1rem 1rem 1rem;">电子签名不能为空</div>
36 </div> 37 </div>
37 </template> 38 </template>
38 39
...@@ -54,12 +55,15 @@ const lineColor = ref('#000000') ...@@ -54,12 +55,15 @@ const lineColor = ref('#000000')
54 const bgColor = ref('#FCFCFC') 55 const bgColor = ref('#FCFCFC')
55 const isCrop = ref(false) 56 const isCrop = ref(false)
56 const show_control = ref(true) 57 const show_control = ref(true)
58 +const image_url = ref('')
59 +const show_empty = ref(false)
57 60
58 const handleReset = () => { 61 const handleReset = () => {
59 // 清空画板 62 // 清空画板
60 esign.value.reset(); 63 esign.value.reset();
61 show_control.value = true; 64 show_control.value = true;
62 // 删除可能存在的签名 65 // 删除可能存在的签名
66 + image_url.value = ''
63 props.item.value = { key: 'sign', value: '' }; 67 props.item.value = { key: 'sign', value: '' };
64 emit('active', props.item.value) 68 emit('active', props.item.value)
65 } 69 }
...@@ -87,7 +91,9 @@ const handleGenerate = () => { ...@@ -87,7 +91,9 @@ const handleGenerate = () => {
87 // 保存图片 91 // 保存图片
88 const { data } = await saveFileAPI({ filekey, hash, format: image_info.format, height: image_info.height, width: image_info.width }); 92 const { data } = await saveFileAPI({ filekey, hash, format: image_info.format, height: image_info.height, width: image_info.width });
89 props.item.value = { key: 'sign', value: data.src}; 93 props.item.value = { key: 'sign', value: data.src};
94 + image_url.value = data.src;
90 show_control.value = false; 95 show_control.value = false;
96 + show_empty.value = false;
91 emit('active', props.item.value) 97 emit('active', props.item.value)
92 } 98 }
93 } 99 }
...@@ -117,16 +123,41 @@ const dataURLtoFile = (dataurl, filename) => { ...@@ -117,16 +123,41 @@ const dataURLtoFile = (dataurl, filename) => {
117 const show_sign = ref(true); 123 const show_sign = ref(true);
118 const startSign = () => { 124 const startSign = () => {
119 show_sign.value = false; 125 show_sign.value = false;
126 + show_empty.value = false;
120 } 127 }
121 const cancelSign = () => { 128 const cancelSign = () => {
122 show_sign.value = true; 129 show_sign.value = true;
130 + show_empty.value = false;
123 handleReset() 131 handleReset()
124 } 132 }
133 +
134 +const validSign = () => {
135 + // 必填项 未生成签名
136 + if (props.item.required && !image_url.value) {
137 + show_empty.value = true;
138 + } else {
139 + show_empty.value = false;
140 + }
141 + return !show_empty.value
142 +}
143 +
144 +defineExpose({ validSign });
125 </script> 145 </script>
126 146
147 +<!-- <script>
148 +export default {
149 + methods: {
150 + validSign () {
151 + console.warn(0);
152 + }
153 + }
154 +}
155 +</script> -->
156 +
157 +
127 <style lang="less" scoped> 158 <style lang="less" scoped>
128 .sign-page { 159 .sign-page {
129 - padding-bottom: 1rem; 160 + // padding-bottom: 1rem;
130 .label { 161 .label {
131 padding: 1rem 1rem 0 1rem; 162 padding: 1rem 1rem 0 1rem;
132 font-size: 0.9rem; 163 font-size: 0.9rem;
...@@ -156,5 +187,9 @@ const cancelSign = () => { ...@@ -156,5 +187,9 @@ const cancelSign = () => {
156 transform: translate(-50%, -50%); 187 transform: translate(-50%, -50%);
157 } 188 }
158 } 189 }
190 +
191 + .control-sign {
192 + padding-bottom: 1rem;
193 + }
159 } 194 }
160 </style> 195 </style>
......
1 <!-- 1 <!--
2 * @Date: 2022-07-18 10:22:22 2 * @Date: 2022-07-18 10:22:22
3 * @LastEditors: hookehuyr hookehuyr@gmail.com 3 * @LastEditors: hookehuyr hookehuyr@gmail.com
4 - * @LastEditTime: 2022-09-07 16:02:34 4 + * @LastEditTime: 2022-09-07 16:47:28
5 * @FilePath: /data-table/src/views/index.vue 5 * @FilePath: /data-table/src/views/index.vue
6 * @Description: 首页 6 * @Description: 首页
7 --> 7 -->
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
11 <div class="table-box"> 11 <div class="table-box">
12 <van-form @submit="onSubmit"> 12 <van-form @submit="onSubmit">
13 <van-cell-group> 13 <van-cell-group>
14 - <component v-for="(item, index) in mockData" :key="index" :is="item.component" :item="item" @active="onActive" /> 14 + <component :ref="item.component_props.name" v-for="(item, index) in mockData" :key="index" :is="item.component" :item="item" @active="onActive" />
15 </van-cell-group> 15 </van-cell-group>
16 <div style="margin: 16px;"> 16 <div style="margin: 16px;">
17 <van-button round block type="primary" native-type="submit"> 17 <van-button round block type="primary" native-type="submit">
...@@ -35,17 +35,17 @@ onMounted(() => { ...@@ -35,17 +35,17 @@ onMounted(() => {
35 table_cover.value = 'https://fastly.jsdelivr.net/npm/@vant/assets/cat.jpeg' 35 table_cover.value = 'https://fastly.jsdelivr.net/npm/@vant/assets/cat.jpeg'
36 table_title.value = '这是一个表单的描述' 36 table_title.value = '这是一个表单的描述'
37 mockData.value = [ 37 mockData.value = [
38 - { 38 + // {
39 - key: 'phone', 39 + // key: 'phone',
40 - value: '', 40 + // value: '',
41 - label: '手机号', 41 + // label: '手机号',
42 - placeholder: '请输入手机号', 42 + // placeholder: '请输入手机号',
43 - component: '', 43 + // component: '',
44 - component_props: { 44 + // component_props: {
45 - name: 'phone' 45 + // name: 'phone'
46 - }, 46 + // },
47 - required: true, 47 + // required: true,
48 - }, 48 + // },
49 { 49 {
50 key: 'username', 50 key: 'username',
51 value: 'test', 51 value: 'test',
...@@ -147,6 +147,7 @@ onMounted(() => { ...@@ -147,6 +147,7 @@ onMounted(() => {
147 component_props: { 147 component_props: {
148 name: 'sign', 148 name: 'sign',
149 }, 149 },
150 + required: true,
150 }, 151 },
151 // { 152 // {
152 // key: 'city', 153 // key: 'city',
...@@ -186,18 +187,33 @@ onMounted(() => { ...@@ -186,18 +187,33 @@ onMounted(() => {
186 createComponentType(mockData.value) 187 createComponentType(mockData.value)
187 }) 188 })
188 189
190 +const sign = ref(null);
191 +
189 const onSubmit = (values) => { 192 const onSubmit = (values) => {
190 // 合并自定义字段到提交表单字段 193 // 合并自定义字段到提交表单字段
191 postData.value = _.assign(postData.value, values); 194 postData.value = _.assign(postData.value, values);
192 - console.warn(postData.value); 195 + // console.warn(postData.value);
193 // console.warn(mockData.value); 196 // console.warn(mockData.value);
197 + // 检查非表单输入项
198 + if (validOther()) { // 通过验证
199 + console.warn('通过验证');
200 + } else {
201 + console.warn('不通过验证');
202 + }
194 }; 203 };
204 +
195 const onActive = (item) => { 205 const onActive = (item) => {
196 // 返回自定义字段 206 // 返回自定义字段
197 if (item.key === 'sign') { 207 if (item.key === 'sign') {
198 postData.value['sign'] = item.value 208 postData.value['sign'] = item.value
199 } 209 }
200 } 210 }
211 +
212 +const validOther = () => {
213 + // 检查电子签名输入项
214 + const flag = sign.value[0].validSign();
215 + return flag;
216 +}
201 </script> 217 </script>
202 218
203 <style lang="less" scoped> 219 <style lang="less" scoped>
......