Showing
2 changed files
with
68 additions
and
17 deletions
| 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"> *</span></div> | 10 | + <div class="label">{{ item.label }}{{ valid }}<span v-if="item.required"> *</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> | ... | ... |
-
Please register or login to post a comment