367 lines
		
	
	
		
			9.5 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
			
		
		
	
	
			367 lines
		
	
	
		
			9.5 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
| <template>
 | ||
|   <section class="personal-signature">
 | ||
|     <ai-list v-if="!showPhonePage">
 | ||
|       <ai-title slot="title" title="个人签名" :isShowBottomBorder="false"/>
 | ||
|       <template #custom>
 | ||
|         <div class="signaturePane">
 | ||
|           <div class="signatureCard" v-for="(op,i) in signatures" :key="i">
 | ||
|             <div class="default" v-if="op.isDefault==1">默认</div>
 | ||
|             <div class="body">
 | ||
|               <el-image :src="`data:image/png;base64,${op.signSealData}`"/>
 | ||
|             </div>
 | ||
|             <div class="footer">
 | ||
|               <el-button type="text" :disabled="op.isDefault==1" @click.stop="handleSetDefault(op.id)">设为默认</el-button>
 | ||
|               <hr/>
 | ||
|               <el-button type="text" :disabled="op.isDefault==1||op.signType>0" @click.stop="handleDelete(op.id)">删除
 | ||
|               </el-button>
 | ||
|             </div>
 | ||
|           </div>
 | ||
|           <div class="signatureCard add" @click="dialog=true">
 | ||
|             <ai-icon icon="iconAdd" size="32px"/>
 | ||
|             <span>点击添加签名</span>
 | ||
|           </div>
 | ||
|         </div>
 | ||
|       </template>
 | ||
|     </ai-list>
 | ||
|     <ai-dialog :visible.sync="dialog" v-bind="dialogConf" @onConfirm="handleSubmit"
 | ||
|                @closed="form={},drawPlaceholder=true,qrCode=null,showQRCode=false,getSignatures()">
 | ||
|       <ai-drawer v-if="hasAuthed" :seal.sync="sealData" ref="aiDrawer">
 | ||
|         <template #tools>
 | ||
|           <el-popover trigger="manual" v-model="showQRCode">
 | ||
|             <el-image :src="qrCode"/>
 | ||
|             <div class="writeInPhone" slot="reference" @click.stop="showQR">
 | ||
|               <ai-icon icon="iconEwm"/>
 | ||
|               <span>手机签名</span>
 | ||
|             </div>
 | ||
|           </el-popover>
 | ||
|         </template>
 | ||
|       </ai-drawer>
 | ||
|       <el-form size="small" :model="form" ref="authForm" :rules="rules" class="authZone" v-else label-suffix=":"
 | ||
|                label-width="100px">
 | ||
|         <el-alert type="warning" title="第一次添加个人签名,需先进行实名认证" show-icon :closable="false"/>
 | ||
|         <el-form-item label="姓名" prop="personName">
 | ||
|           <el-input v-model="form.personName" clearable placeholder="姓名"/>
 | ||
|         </el-form-item>
 | ||
|         <el-form-item label="身份证号" prop="idNumber">
 | ||
|           <el-input v-model="form.idNumber" clearable placeholder="身份证号"/>
 | ||
|         </el-form-item>
 | ||
|         <el-form-item label="手机号码" prop="signPhone">
 | ||
|           <el-input v-model="form.signPhone" clearable placeholder="手机号码"/>
 | ||
|         </el-form-item>
 | ||
|       </el-form>
 | ||
|     </ai-dialog>
 | ||
|     <draw-in-phone v-if="showPhonePage"/>
 | ||
|   </section>
 | ||
| </template>
 | ||
| 
 | ||
| <script>
 | ||
| import {mapState} from "vuex";
 | ||
| import DrawInPhone from "./drawInPhone";
 | ||
| import {ID} from "dui/lib/js/utils";
 | ||
| 
 | ||
| export default {
 | ||
|   name: "AppPersonalSignature",
 | ||
|   label: "个人签名",
 | ||
|   components: {DrawInPhone},
 | ||
|   provide() {
 | ||
|     return {
 | ||
|       signature: this
 | ||
|     }
 | ||
|   },
 | ||
|   props: {
 | ||
|     instance: Function,
 | ||
|     dict: Object,
 | ||
|     permissions: Function
 | ||
|   },
 | ||
|   computed: {
 | ||
|     ...mapState(['user']),
 | ||
|     hasAuthed() {
 | ||
|       return this.signatures.length > 0
 | ||
|     },
 | ||
|     dialogConf() {
 | ||
|       return this.hasAuthed ? {
 | ||
|         title: "手写签名",
 | ||
|         width: '720px'
 | ||
|       } : {
 | ||
|         title: "实名认证",
 | ||
|         width: '520px'
 | ||
|       }
 | ||
|     },
 | ||
|     rules() {
 | ||
|       return {
 | ||
|         personName: [{required: true, message: "请填写姓名"}],
 | ||
|         signPhone: [
 | ||
|           {required: true, message: "请填写手机号码"},
 | ||
|           {pattern: /^1[3456789]\d{9}$/, message: "手机号码格式有误"}
 | ||
|         ],
 | ||
|         idNumber: [
 | ||
|           {required: true, message: "请填写身份证号码"},
 | ||
|           {validator: (r, v, cb) => cb(ID.check(v) ? undefined : "身份证号码格式有误")}
 | ||
|         ],
 | ||
|       }
 | ||
|     }
 | ||
|   },
 | ||
|   data() {
 | ||
|     return {
 | ||
|       signatures: [],
 | ||
|       dialog: false,
 | ||
|       form: {},
 | ||
|       sealData: null,
 | ||
|       qrCode: null,
 | ||
|       showQRCode: false,
 | ||
|       showPhonePage: false,
 | ||
|       loading: false,
 | ||
|     }
 | ||
|   },
 | ||
|   created() {
 | ||
|     if (this.$route.query.userId && this.$route.hash == "#phone") {
 | ||
|       this.showPhonePage = true
 | ||
|     } else {
 | ||
|       this.getSignatures()
 | ||
|     }
 | ||
|   },
 | ||
|   methods: {
 | ||
|     getSignatures() {
 | ||
|       this.instance.post("/app/syssignaccount/list", null, {
 | ||
|         params: {
 | ||
|           size: 999
 | ||
|         }
 | ||
|       }).then(res => {
 | ||
|         if (res?.data) {
 | ||
|           this.signatures = res.data.records
 | ||
|         }
 | ||
|       })
 | ||
|     },
 | ||
|     handleSubmit() {
 | ||
|       if (this.loading) return
 | ||
|       if (this.hasAuthed && this.$refs['aiDrawer'].drawPlaceholder) return this.$message.error("请签名")
 | ||
|       this.loading = true
 | ||
|       if (this.hasAuthed) {
 | ||
|         let sealData = this.sealData?.replace(/data:image\/png;base64,/, '')
 | ||
|         sealData && this.instance({
 | ||
|           url: '/app/syssignaccount/upload-sealdata',
 | ||
|           headers: {"Content-Type": "application/json"},
 | ||
|           method: 'post',
 | ||
|           params: {userId: this.user.info.id},
 | ||
|           data: sealData
 | ||
|         }).then(res => {
 | ||
|           this.loading = false
 | ||
|           if (res?.code == 0) {
 | ||
|             this.dialog = false
 | ||
|             this.$message.success("添加成功!")
 | ||
|             this.getSignatures()
 | ||
|           }
 | ||
|         }).catch(() => {
 | ||
|           this.loading = false
 | ||
|         })
 | ||
|       } else {
 | ||
|         this.$refs.authForm.validate(v => {
 | ||
|           if (v) {
 | ||
|             this.instance.post("/app/syssignaccount/register", {
 | ||
|               signPhone: this.form.signPhone,
 | ||
|               signType: 1,
 | ||
|               userType: 0,
 | ||
|               registerInfo: {...this.form},
 | ||
|               style: {personTemplateType: 'RECTANGLE', sealColor: 'RED'}
 | ||
|             }).then(res => {
 | ||
|               this.loading = false
 | ||
|               if (res?.code == 0) {
 | ||
|                 this.dialog = false
 | ||
|                 this.$message.success("认证成功!")
 | ||
|                 this.getSignatures()
 | ||
|               }
 | ||
|             }).catch(() => {
 | ||
|               this.loading = false
 | ||
|             })
 | ||
|           }
 | ||
|         })
 | ||
|       }
 | ||
|     },
 | ||
|     handleSetDefault(id) {
 | ||
|       this.$confirm("是否设置该签名为默认签名?").then(() => {
 | ||
|         this.instance.post("/app/syssignaccount/default", null, {params: {id, listType: 0}}).then(res => {
 | ||
|           if (res?.code == 0) {
 | ||
|             this.$message.success("设置成功!")
 | ||
|             this.getSignatures()
 | ||
|           }
 | ||
|         }).catch(() => 0)
 | ||
|       })
 | ||
|     },
 | ||
|     handleDelete(ids) {
 | ||
|       this.$confirm("是否删除该签名?").then(() => {
 | ||
|         this.instance.post("/app/syssignaccount/delete", null, {params: {ids}}).then(res => {
 | ||
|           if (res?.code == 0) {
 | ||
|             this.$message.success("删除成功!")
 | ||
|             this.getSignatures()
 | ||
|           }
 | ||
|         }).catch(() => 0)
 | ||
|       })
 | ||
|     },
 | ||
|     showQR() {
 | ||
|       if (!this.qrCode) {
 | ||
|         let url = `${location.href}?userId=${this.user.info.id}#phone`
 | ||
|         this.instance.post("/app/syssignaccount/draw-qrcode", null, {
 | ||
|           params: {url}
 | ||
|         }).then(res => {
 | ||
|           if (res?.data) {
 | ||
|             this.showQRCode = true
 | ||
|             this.qrCode = res.data
 | ||
|           }
 | ||
|         })
 | ||
|       } else {
 | ||
|         this.showQRCode = !this.showQRCode
 | ||
|       }
 | ||
|     }
 | ||
|   }
 | ||
| }
 | ||
| </script>
 | ||
| 
 | ||
| <style lang="scss" scoped>
 | ||
| .personal-signature {
 | ||
|   height: 100%;
 | ||
|   background: #f3f6f9;
 | ||
|   overflow: auto;
 | ||
| 
 | ||
|   :deep( .signaturePane ){
 | ||
|     display: flex;
 | ||
|     gap: 16px;
 | ||
|     flex-wrap: wrap;
 | ||
|     padding: 16px;
 | ||
| 
 | ||
|     .signatureCard {
 | ||
|       width: 290px;
 | ||
|       height: 258px;
 | ||
|       background: #FFFFFF;
 | ||
|       border-radius: 4px;
 | ||
|       position: relative;
 | ||
|       display: flex;
 | ||
|       flex-direction: column;
 | ||
|       overflow: hidden;
 | ||
| 
 | ||
|       &.add {
 | ||
|         justify-content: center;
 | ||
|         align-items: center;
 | ||
|         color: #666666;
 | ||
|         cursor: pointer;
 | ||
| 
 | ||
|         .AiIcon {
 | ||
|           width: 32px;
 | ||
|           height: 32px;
 | ||
|           font-size: 32px;
 | ||
|         }
 | ||
| 
 | ||
|         & > span {
 | ||
|           font-size: 12px;
 | ||
|           line-height: 16px;
 | ||
|         }
 | ||
|       }
 | ||
| 
 | ||
|       .default {
 | ||
|         position: absolute;
 | ||
|         width: 56px;
 | ||
|         height: 24px;
 | ||
|         background: #3573FF;
 | ||
|         border-radius: 0 0 4px 0;
 | ||
|         top: 0;
 | ||
|         left: 0;
 | ||
|         text-align: center;
 | ||
|         line-height: 24px;
 | ||
|         font-size: 12px;
 | ||
|         color: #FFF;
 | ||
|       }
 | ||
| 
 | ||
|       .body {
 | ||
|         min-height: 0;
 | ||
|         flex: 1;
 | ||
|         display: flex;
 | ||
|         justify-content: center;
 | ||
|         align-items: center;
 | ||
|         padding: 25px;
 | ||
|         pointer-events: none;
 | ||
| 
 | ||
|         .el-image {
 | ||
|           width: 100%;
 | ||
|           height: 100%
 | ||
|         }
 | ||
|       }
 | ||
| 
 | ||
|       .footer {
 | ||
|         flex-shrink: 0;
 | ||
|         height: 40px;
 | ||
|         background: rgba(#30426F, .5);
 | ||
|         display: flex;
 | ||
|         align-items: center;
 | ||
|         padding: 8px 0;
 | ||
|         box-sizing: border-box;
 | ||
| 
 | ||
|         hr {
 | ||
|           height: 100%;
 | ||
|           border-color: rgba(#fff, .5);
 | ||
|         }
 | ||
| 
 | ||
|         & > .el-button {
 | ||
|           flex: 1;
 | ||
|           color: #fff;
 | ||
| 
 | ||
|           &[disabled] {
 | ||
|             color: rgba(#fff, .5);
 | ||
|           }
 | ||
|         }
 | ||
|       }
 | ||
|     }
 | ||
|   }
 | ||
|   :deep( .writeInPhone ){
 | ||
|     position: absolute;
 | ||
|     width: 100px;
 | ||
|     height: 32px;
 | ||
|     background: rgba(#000, .5);
 | ||
|     border-radius: 16px;
 | ||
|     display: flex;
 | ||
|     align-items: center;
 | ||
|     justify-content: center;
 | ||
|     gap: 4px;
 | ||
|     color: rgba(#fff, .6);
 | ||
|     cursor: pointer;
 | ||
|     left: 16px;
 | ||
|     top: 16px;
 | ||
| 
 | ||
|     .AiIcon {
 | ||
|       width: auto;
 | ||
|       height: auto;
 | ||
|     }
 | ||
| 
 | ||
|     &:hover {
 | ||
|       color: #fff;
 | ||
|     }
 | ||
|   }
 | ||
|   :deep( .ai-dialog__wrapper ){
 | ||
|     .ai-dialog__content--wrapper {
 | ||
|       padding-right: 0 !important;
 | ||
|     }
 | ||
| 
 | ||
|     .el-dialog__body {
 | ||
|       padding: 24px 0;
 | ||
|     }
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
|     .authZone {
 | ||
|       padding: 0 16px 24px;
 | ||
|       width: 100%;
 | ||
|       box-sizing: border-box;
 | ||
|       display: flex;
 | ||
|       flex-direction: column;
 | ||
|       gap: 24px;
 | ||
| 
 | ||
|       .el-alert {
 | ||
|         border: 1px solid #FF8822;
 | ||
|       }
 | ||
| 
 | ||
|       .el-form-item {
 | ||
|         margin-bottom: 0;
 | ||
|       }
 | ||
|     }
 | ||
|   }
 | ||
| }
 | ||
| </style>
 |