From 7298d5354963a88643a543b51b90192dc9fc934c Mon Sep 17 00:00:00 2001 From: doum <doum> Date: 星期四, 11 九月 2025 18:43:14 +0800 Subject: [PATCH] 最新版本541200007 --- admin/src/components/business/OperaMemberWindow.vue | 392 +++++++++++++++++++++++++++++++++++++++++++++++-------- 1 files changed, 331 insertions(+), 61 deletions(-) diff --git a/admin/src/components/business/OperaMemberWindow.vue b/admin/src/components/business/OperaMemberWindow.vue index df26e7c..b7b678a 100644 --- a/admin/src/components/business/OperaMemberWindow.vue +++ b/admin/src/components/business/OperaMemberWindow.vue @@ -1,56 +1,106 @@ <template> - <GlobalWindow - :title="title" - width="60%" - :visible.sync="visible" - :confirm-working="isWorking" - @confirm="confirm" - > - <el-form :model="form" ref="form" :rules="rules"> - <el-form-item label="濮撳悕" prop="name"> - <el-input v-model="form.name" placeholder="璇疯緭鍏ュ鍚�" v-trim/> - </el-form-item> - <el-form-item label="鎵�灞炵粍缁�" prop="companyId"> - <el-cascader - v-model="form.company" - :options="department" - @change="handleChangeCompany" - :show-all-levels="false" - clearable - filterable - :props="departprops" - ></el-cascader> - <div style="font-size: 12px;color: #F56C6C" > - 娉細浠呮敮鎸侀�夋嫨 銆恵{companyType ===0?'鐩稿叧鏂圭粍缁�':'鍐呴儴缁勭粐'}}銆� - </div> - </el-form-item> - <el-form-item label="鎵嬫満鍙�" prop="phone"> - <el-input v-model="form.phone" placeholder="璇疯緭鍏ユ墜鏈哄彿" v-trim/> - <div style="color: #F56C6C;font-size: 12px">娉細鍛樺伐鎵嬫満鍙峰皢浣滀负骞冲彴鐧诲綍璐﹀彿锛屽垵濮嬪瘑鐮佷负绯荤粺榛樿瀵嗙爜閰嶇疆椤�</div> - </el-form-item> - <el-form-item label="韬唤璇佸彿" prop="idcardNo" v-if="form.id ==null"> - <el-input v-model="form.idcardNo" placeholder="璇疯緭鍏ヨ韩浠借瘉鍙�" v-trim/> - </el-form-item> - <el-form-item label="淇敼韬唤璇佸彿" prop="idcardNoNew" v-if="form.id !=null"> - <el-input v-model="form.idcardNoNew" placeholder="鍙慨鏀硅韩浠借瘉鍙�" v-trim/> - <div style="font-size: 12px" v-if="form.id !=null"> - 娉細褰撳墠韬唤璇佸彿涓�<span style="color: #F56C6C">銆恵{form.idcardDecode}}銆�</span>锛屽闇�淇敼锛岃鍦ㄨ緭鍏ユ爮濉啓鏂扮殑韬唤璇佸彿! - </div> - </el-form-item> - <el-form-item label="宸ュ彿" prop="code"> - <el-input v-model="form.code" placeholder="璇疯緭鍏ュ憳宸ュ伐鍙�" v-trim/> - </el-form-item> - <el-form-item label="浜鸿劯鐓х墖" prop="faceImgFull" > - <UploadFaceImg - :file="{ 'imgurlfull': form.faceImgFull, 'imgurl': form.faceImg }" - :uploadData="uploadData" - @uploadSuccess="uploadAvatarSuccess" - @uploadEnd="isUploading = false" - @uploadBegin="isUploading = true" - /> - </el-form-item> -</el-form> -</GlobalWindow> + <GlobalWindow :title="title" width="60%" :visible.sync="visible" :confirm-working="isWorking" @confirm="confirm"> + <el-form :model="form" ref="form" :rules="rules"> + <el-form-item label="濮撳悕" prop="name"> + <el-input v-model="form.name" placeholder="璇疯緭鍏ュ鍚�" v-trim /> + </el-form-item> + <el-form-item label="鎵�灞炵粍缁�" prop="companyId"> +<!-- <el-cascader v-model="form.company" :options="department" @change="handleChangeCompany" :show-all-levels="false" + clearable filterable :props="departprops"></el-cascader>--> +<!-- <el-select v-model="form.companyId" clearable filterable placeholder="璇烽�夋嫨">--> +<!-- <template v-for="item in companyList">--> +<!-- <el-option :key="item.id" :label="item.companyNamePath" :value="item.id">--> +<!-- </el-option>--> +<!-- </template>--> +<!-- </el-select>--> + <treeselect + v-model="form.companyId" + placeholder="璇烽�夋嫨" + :options="treeData" + :normalizer="normalizeOptions" + :default-expand-level="1" + noChildrenText="娌℃湁瀛愰�夐」" + noOptionsText="娌℃湁鍙�夐」" + noResultsText="娌℃湁鍖归厤鐨勭粨鏋�" /> + <div style="font-size: 12px;color: #F56C6C"> + 娉細浠呮敮鎸侀�夋嫨 銆恵{ companyType === 0 ? '鐩稿叧鏂圭粍缁�' : '鍐呴儴缁勭粐' }}銆� + </div> + </el-form-item> + <el-form-item label="閫夋嫨宀椾綅锛�" prop="positionId"> + <el-select v-model="form.positionId" clearable filterable placeholder="璇烽�夋嫨"> + <el-option v-for="item in positionList" :key="item.id" :label="item.name" :value="item.id"> + </el-option> + </el-select> + </el-form-item> + <el-form-item label="鎵嬫満鍙�" prop="phone"> + <el-input v-model="form.phone" placeholder="璇疯緭鍏ユ墜鏈哄彿" v-trim /> + <div style="color: #F56C6C;font-size: 12px">娉細鍛樺伐鎵嬫満鍙峰皢浣滀负骞冲彴鐧诲綍璐﹀彿锛屽垵濮嬪瘑鐮佷负绯荤粺榛樿瀵嗙爜閰嶇疆椤�</div> + </el-form-item> + <el-form-item label="韬唤璇佸彿" v-if="form.id == null"> + <el-input v-model="form.idcardNo" placeholder="璇疯緭鍏ヨ韩浠借瘉鍙�" v-trim /> + </el-form-item> + <el-form-item label="淇敼韬唤璇佸彿" v-if="form.id != null"> + <el-input v-model="form.idcardNoNew" placeholder="鍙慨鏀硅韩浠借瘉鍙�" v-trim /> + <div style="font-size: 12px" v-if="form.id != null"> + 娉細褰撳墠韬唤璇佸彿涓�<span style="color: #F56C6C">銆恵{ form.idcardDecode }}銆�</span>锛屽闇�淇敼锛岃鍦ㄨ緭鍏ユ爮濉啓鏂扮殑韬唤璇佸彿! + </div> + </el-form-item> + <el-form-item label="宸ュ彿" prop="code"> + <el-input v-model="form.code" placeholder="璇疯緭鍏ュ憳宸ュ伐鍙�" v-trim /> + </el-form-item> + <el-form-item label="鍏ヨ亴鏃ユ湡" prop="jobDate"> + <el-date-picker v-model="form.jobDate" value-format="yyyy-MM-dd" type="date"> + </el-date-picker> + </el-form-item> +<!-- <el-form-item label="鏄惁鍏氬憳" prop="isDangyuan"> + <el-radio-group v-model="form.isDangyuan"> + <el-radio :label="0">闈炲厷鍛�</el-radio> + <el-radio :label="1">鍏氬憳</el-radio> + </el-radio-group> + </el-form-item>--> + <el-form-item label="浜鸿劯鐓х墖" prop="faceImgFull"> + <div class="upload_wrap"> + <UploadFaceImg :file="{ 'imgurlfull': form.faceImgFull, 'imgurl': form.faceImg }" :uploadData="uploadData" + @uploadSuccess="uploadAvatarSuccess" @uploadEnd="isUploading = false" @uploadBegin="isUploading = true" /> + <div class="content"> + <div>1銆佽閫夋嫨娴呰壊鎴栦腑鎬ц儗鏅紝浣跨敤鍧囧寑鍏夌嚎鎷嶇収銆�</div> + <div>2銆佽淇濇寔闈㈤儴姝e闀滃ご锛屽嬁閬尅闈㈤儴锛屼繚鎸佷腑绔嬭〃鎯呫��</div> + <div>3銆佽閬垮厤鍚庢湡淇浘锛岀‘淇濅汉鑴歌疆寤撴竻鏅般�佸畬鏁达紝灏藉彲鑳藉噺灏戦潪鑴搁儴鍐呭鍗犳瘮銆�</div> + </div> + </div> + </el-form-item> + <el-form-item> + <div><el-button type="primary" @click="openCamera">閲囬泦</el-button></div> + </el-form-item> + </el-form> + <!-- --> + <el-dialog title="鎷嶆憚" :visible.sync="paisheModal" width="760px" :close-on-click-modal="false" + :close-on-press-escape="false" append-to-body @close="closeCamera"> + <video v-show="isShowCamera" id="videoCamera" :width="videoWidth" :height="videoHeight" /> + <canvas v-show="!isShowCamera" id="canvasCamera" style="display: none" :width="videoWidth" + :height="videoHeight" /> + <span slot="footer"> + <div> + <el-button @click="closeCamera">鍙栨秷</el-button> + <el-button v-show="blobFileCamera" type="primary" @click="resetCamera">閲嶆媿</el-button> + <el-button v-show="blobFileCamera" :loading="cameraLoading" type="primary" + @click="enterCamera">寮�濮嬭鍓�</el-button> + <el-button v-show="!blobFileCamera" type="primary" @click="setImage">鎷嶆憚</el-button> + </div> + </span> + </el-dialog> + <!-- --> + <el-dialog append-to-body :close-on-click-modal="false" title="涓婁紶鍥剧墖" :visible.sync="isShowCropper" width="1000px" + class="icon-dialog-wrapper dialong-com-style"> + <ImageCropper ref="iconShot" v-if="isShowCropper" :imgSrc="blobFileCamera"> + </ImageCropper> + <span slot="footer" class="dialog-footer"> + <el-button v-if="loading">鍙� 娑�</el-button> + <el-button v-else @click="isShowCropper = false">鍙� 娑�</el-button> + <el-button :loading="loading" type="primary" @click="uploadIcon">纭� 瀹�</el-button> + </span> + </el-dialog> + </GlobalWindow> </template> <script> @@ -58,13 +108,27 @@ import GlobalWindow from '@/components/common/GlobalWindow' import UploadAvatarImage from '@/components/common/UploadAvatarImage' import UploadFaceImg from '@/components/common/UploadFaceImg' -import {checkMobile, validIdCardNo, validIdCardNoNew} from '@/utils/form' +import ImageCropper from '@/components/common/ImageCropper' +import { checkMobile, validIdCardNo, validIdCardNoNew } from '@/utils/form' +import { allList } from '@/api/business/position' +import { upload } from '@/api/system/common' +import {companyGetList} from "@/api/business/company"; export default { name: 'OperaCompanyWindow', extends: BaseOpera, - components: { GlobalWindow, UploadAvatarImage,UploadFaceImg }, - data () { + components: { GlobalWindow, UploadAvatarImage, UploadFaceImg, ImageCropper }, + data() { return { + isShowCamera: false, + paisheModal: false, + cameraLoading: false, + videoWidth: 700, + videoHeight: 525, + mediaStreamCamera: '', + blobFileCamera: '', + isShowCropper: false, + loading: false, + // 浠ヤ笂鏄媿鎽� uploadData: { folder: 'member' }, @@ -73,8 +137,10 @@ value: 'id', checkStrictly: true }, - companyType:0, + companyType: 0, department: [], + positionList: [], + companyList: [], // 琛ㄥ崟鏁版嵁 form: { id: null, @@ -90,8 +156,12 @@ idcardType: 0, phone: '', faceImg: '', + jobDate: null, + isDangyuan: 0, + positionId: null, faceImgFull: '' }, + treeData: [], // 楠岃瘉瑙勫垯 rules: { name: [{ required: true, message: '璇疯緭鍏ュ憳宸ュ鍚�', trigger: 'blur' }], @@ -102,14 +172,158 @@ } } }, - created () { + created() { this.config({ api: '/business/member.js', 'field.id': 'id' }) }, methods: { - handleChangeCompany (value) { + // 瑙勮寖鍖栭�夐」鏁版嵁鐨勬柟娉� + normalizeOptions(node) { + // node: 鍘熷鐨勯�夐」鏁版嵁 + // 鍦ㄨ繖閲屾牴鎹渶瑕佽繘琛岄�夐」鏁版嵁鐨勮鑼冨寲鎿嶄綔锛屽苟杩斿洖瑙勮寖鍖栧悗鐨勯�夐」鏁版嵁 + // 渚嬪锛屽彲浠ュ皢鍘熷鐨勯�夐」鏁版嵁杞崲涓虹鍚堟彃浠惰姹傜殑缁撴瀯 + if (node.childList && !node.childList.length) { + // 鍘绘帀children=[]鐨刢hildren灞炴�� + delete node.childList; + } + return { + id: node.id, + label: node.name, + children: node.childList, + }; + }, + getCompany() { + companyGetList({ + model: {type:this.companyType } , + capacity: 10000, + page: 1, + }).then(res => { + this.companyList = res.records || [] + + }) + }, + openCamera() { + this.paisheModal = true + this.isShowCamera = true + this.blobFileCamera = '' + const that = this + this.$nextTick(() => { + var mediaOpts = { audio: false, video: true } + navigator.mediaDevices + .getUserMedia(mediaOpts) + .then(function (stream) { + that.mediaStreamCamera = stream + const video = document.querySelector('#videoCamera') + if ('srcObject' in video) { + video.srcObject = stream + } else { + video.src = + (window.URL && window.URL.createObjectURL(stream)) || stream + } + video.play() + }) + .catch(function (err) { + console.log(err) + }) + }) + }, + // 閲嶆媿 + resetCamera() { + this.isShowCamera = true + this.blobFileCamera = '' + this.openCamera() + }, + // 鍏抽棴鐩告満 + closeCamera() { + this.mediaStreamCamera.getVideoTracks().forEach(function (track) { + track.stop() + }) + this.paisheModal = false + }, + // 鐐瑰嚮鎷嶆憚 + setImage() { + const that = this + this.blobFileCamera = '' + that.isShowCamera = false + const video = document.querySelector('#videoCamera') + const canvas = document.querySelector('#canvasCamera') + canvas + .getContext('2d') + .drawImage(video, 0, 0, that.videoWidth, that.videoHeight) + this.mediaStreamCamera.getVideoTracks().forEach(function (track) { + track.stop() + }) + const dataurl = canvas.toDataURL('image/jpg') + // this.blobFileCamera = that.base64ToFile(dataurl, 'camera') + this.blobFileCamera = dataurl + }, + // 纭鎷嶆憚 + enterCamera() { + this.isShowCropper = true + this.paisheModal = false + this.isShowCamera = true + }, + uploadIcon () { + // 鑾峰彇瑁佸壀鍚庣殑鍥剧墖 + this.$refs.iconShot.getImagecropper().getCropBlob((fileData) => { // 鑾峰彇褰撳墠瑁佸壀濂界殑鏁版嵁 + // 娉ㄦ鏃剁殑data鏄竴涓狟lob鏁版嵁锛岄儴鍒嗘帴鍙f帴鏀剁殑鏄疐ile杞寲鐨凢ormData鏁版嵁 + console.log(fileData) + const formData = new FormData() + + formData.append('folder', 'member') + formData.append( + 'file', + fileData + ) + this.loading = true + upload(formData).then(res => { + this.loading = false + console.log(res) + // this.file.imgurl = res.imgaddr + // this.file.imgurlfull = res.url + this.$message.success('涓婁紶鎴愬姛') + // this.imageSrc = res.url + // this.updateImg = false + this.form.faceImg = res.imgaddr + this.form.faceImgFull = res.url + this.isShowCropper = false + // this.$emit('uploadSuccess', { imgurl: res.imgaddr, imgurlfull: res.url, name: res.originname }) + // this.$emit('uploadEnd') + }, () => { + this.loading = false + }) + }) + }, + base64ToFile(base64, fileName) { + // 灏哹ase64鎸夌収 , 杩涜鍒嗗壊 灏嗗墠缂� 涓庡悗缁唴瀹瑰垎闅斿紑 + const data = base64.split(',') + // 鍒╃敤姝e垯琛ㄨ揪寮� 浠庡墠缂�涓幏鍙栧浘鐗囩殑绫诲瀷淇℃伅锛坕mage/png銆乮mage/jpeg銆乮mage/webp绛夛級 + const type = data[0].match(/:(.*?);/)[1] + // 浠庡浘鐗囩殑绫诲瀷淇℃伅涓� 鑾峰彇鍏蜂綋鐨勬枃浠舵牸寮忓悗缂�锛坧ng銆乯peg銆亀ebp锛� + const suffix = type.split('/')[1] + // 浣跨敤atob()瀵筨ase64鏁版嵁杩涜瑙g爜 缁撴灉鏄竴涓枃浠舵暟鎹祦 浠ュ瓧绗︿覆鐨勬牸寮忚緭鍑� + const bstr = window.atob(data[1]) + // 鑾峰彇瑙g爜缁撴灉瀛楃涓茬殑闀垮害 + let n = bstr.length + // 鏍规嵁瑙g爜缁撴灉瀛楃涓茬殑闀垮害鍒涘缓涓�涓瓑闀跨殑鏁村舰鏁板瓧鏁扮粍 + // 浣嗗湪鍒涘缓鏃� 鎵�鏈夊厓绱犲垵濮嬪�奸兘涓� 0 + const u8arr = new Uint8Array(n) + // 灏嗘暣褰㈡暟缁勭殑姣忎釜鍏冪礌濉厖涓鸿В鐮佺粨鏋滃瓧绗︿覆瀵瑰簲浣嶇疆瀛楃鐨刄TF-16 缂栫爜鍗曞厓 + while (n--) { + // charCodeAt()锛氳幏鍙栫粰瀹氱储寮曞瀛楃瀵瑰簲鐨� UTF-16 浠g爜鍗曞厓 + u8arr[n] = bstr.charCodeAt(n) + } + // 鍒╃敤鏋勯�犲嚱鏁板垱寤篎ile鏂囦欢瀵硅薄 + // new File(bits, name, options) + const file = new File([u8arr], `${fileName}.${suffix}`, { + type: type + }) + // 灏咶ile鏂囦欢瀵硅薄杩斿洖缁欐柟娉曠殑璋冪敤鑰� + return file + }, + handleChangeCompany(value) { if (this.form.company && this.form.company.length > 1) { this.form.companyId = this.form.company[this.form.company.length - 1] } @@ -119,11 +333,32 @@ * @title 绐楀彛鏍囬 * @target 缂栬緫鐨勫璞� */ - open (title, target, depart,companyType) { + open(title, target, depart, companyType) { this.title = title this.department = depart this.visible = true + this.form = { + id: null, + name: '', + type: '', + company: [], + code: '', + idcardNo: '', + idcardNoNew: '', + linkName: '', + idcardDecode: '', + companyId: null, + idcardType: 0, + phone: '', + faceImg: '', + jobDate: null, + isDangyuan: 0, + positionId: null, + faceImgFull: '' + } this.companyType = companyType + this.getCompany() + this.getPositionList() // 鏂板缓 if (target == null) { this.$nextTick(() => { @@ -131,6 +366,8 @@ this.form[this.configData['field.id']] = null this.form.company = [] }) + + this.getCompany() return } // 缂栬緫 @@ -140,7 +377,7 @@ this.form[key] = target[key] this.form.idcardNo = '' } - this.form.company =[] + this.form.company = [] if (target.companyId && target.companyPath) { var array = target.companyPath.split('/') array.forEach(item => { @@ -151,11 +388,44 @@ } }) }, + getPositionList() { + allList({}) + .then(res => { + this.positionList = res + }) + }, // 涓婁紶鍥剧墖 - uploadAvatarSuccess (file) { + uploadAvatarSuccess(file) { this.form.faceImg = file.imgurl this.form.faceImgFull = file.imgurlfull } } } </script> +<style lang="scss" scoped> +.upload_wrap { + display: flex; + align-items: center; + + .avatar-uploader { + display: flex; + align-items: center; + justify-content: center; + } + + ::v-deep .avatar { + max-width: 90px; + max-height: 90px; + } + + .content { + display: flex; + flex-direction: column; + justify-content: center; + font-size: 12px; + color: #999999; + margin-left: 12px; + line-height: 24px; + } +} +</style> -- Gitblit v1.9.3