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 |  278 ++++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 252 insertions(+), 26 deletions(-)

diff --git a/admin/src/components/business/OperaMemberWindow.vue b/admin/src/components/business/OperaMemberWindow.vue
index c38445d..b7b678a 100644
--- a/admin/src/components/business/OperaMemberWindow.vue
+++ b/admin/src/components/business/OperaMemberWindow.vue
@@ -5,13 +5,28 @@
         <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-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-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>
@@ -34,18 +49,15 @@
         <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 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.radio" @input="isDangyuan">
-            <el-radio :label="0">闈炲厷鍛�</el-radio>
-            <el-radio :label="1">鍏氬憳</el-radio>
-          </el-radio-group>
-        </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"
@@ -57,7 +69,37 @@
           </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>
 
@@ -66,14 +108,27 @@
 import GlobalWindow from '@/components/common/GlobalWindow'
 import UploadAvatarImage from '@/components/common/UploadAvatarImage'
 import UploadFaceImg from '@/components/common/UploadFaceImg'
+import ImageCropper from '@/components/common/ImageCropper'
 import { checkMobile, validIdCardNo, validIdCardNoNew } from '@/utils/form'
-import { allList   } from '@/api/business/position'
+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'
       },
@@ -85,6 +140,7 @@
       companyType: 0,
       department: [],
       positionList: [],
+      companyList: [],
       // 琛ㄥ崟鏁版嵁
       form: {
         id: null,
@@ -105,6 +161,7 @@
         positionId: null,
         faceImgFull: ''
       },
+      treeData: [],
       // 楠岃瘉瑙勫垯
       rules: {
         name: [{ required: true, message: '璇疯緭鍏ュ憳宸ュ鍚�', trigger: 'blur' }],
@@ -115,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]
       }
@@ -132,12 +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.positionList()
+      this.getCompany()
+      this.getPositionList()
       // 鏂板缓
       if (target == null) {
         this.$nextTick(() => {
@@ -145,6 +366,8 @@
           this.form[this.configData['field.id']] = null
           this.form.company = []
         })
+
+        this.getCompany()
         return
       }
       // 缂栬緫
@@ -165,14 +388,14 @@
         }
       })
     },
-    getPositionList () {
+    getPositionList() {
       allList({})
         .then(res => {
           this.positionList = res
         })
     },
     // 涓婁紶鍥剧墖
-    uploadAvatarSuccess (file) {
+    uploadAvatarSuccess(file) {
       this.form.faceImg = file.imgurl
       this.form.faceImgFull = file.imgurlfull
     }
@@ -180,19 +403,22 @@
 }
 </script>
 <style lang="scss" scoped>
-.upload_wrap{
+.upload_wrap {
   display: flex;
   align-items: center;
-  .avatar-uploader{
+
+  .avatar-uploader {
     display: flex;
     align-items: center;
     justify-content: center;
   }
-  ::v-deep .avatar{
+
+  ::v-deep .avatar {
     max-width: 90px;
     max-height: 90px;
   }
-  .content{
+
+  .content {
     display: flex;
     flex-direction: column;
     justify-content: center;

--
Gitblit v1.9.3