Commit f78c1fda authored by sixiaofeng's avatar sixiaofeng

二维码生成图片下载/通讯录生成

parent a339d625
......@@ -3853,6 +3853,11 @@
"safe-buffer": "^5.0.1"
}
},
"base64-arraybuffer": {
"version": "0.2.0",
"resolved": "https://registry.nlark.com/base64-arraybuffer/download/base64-arraybuffer-0.2.0.tgz",
"integrity": "sha1-S5RPrAGRqlkHr+LYyZnMxXzoD0U="
},
"base64-js": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
......@@ -5416,6 +5421,14 @@
"timsort": "^0.3.0"
}
},
"css-line-break": {
"version": "2.0.1",
"resolved": "https://registry.nlark.com/css-line-break/download/css-line-break-2.0.1.tgz?cache=0&sync_timestamp=1628083299735&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fcss-line-break%2Fdownload%2Fcss-line-break-2.0.1.tgz",
"integrity": "sha1-PcdMLtXrZCEUgCgZMkdXkCQ+czg=",
"requires": {
"base64-arraybuffer": "^0.2.0"
}
},
"css-loader": {
"version": "1.0.1",
"resolved": "https://registry.nlark.com/css-loader/download/css-loader-1.0.1.tgz",
......@@ -8398,6 +8411,15 @@
}
}
},
"html2canvas": {
"version": "1.3.2",
"resolved": "https://registry.nlark.com/html2canvas/download/html2canvas-1.3.2.tgz",
"integrity": "sha1-lRzIOIo86Tn9rAITEAfuKBJK/Cc=",
"requires": {
"css-line-break": "2.0.1",
"text-segmentation": "^1.0.2"
}
},
"htmlparser2": {
"version": "6.1.0",
"resolved": "https://registry.nlark.com/htmlparser2/download/htmlparser2-6.1.0.tgz",
......@@ -14309,6 +14331,14 @@
}
}
},
"text-segmentation": {
"version": "1.0.2",
"resolved": "https://registry.nlark.com/text-segmentation/download/text-segmentation-1.0.2.tgz",
"integrity": "sha1-H4KPoUqhAcEU3tG9o1un3MF8mFg=",
"requires": {
"utrie": "^1.0.1"
}
},
"text-table": {
"version": "0.2.0",
"resolved": "https://registry.npm.taobao.org/text-table/download/text-table-0.2.0.tgz",
......@@ -14961,6 +14991,21 @@
"integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=",
"dev": true
},
"utrie": {
"version": "1.0.1",
"resolved": "https://registry.nlark.com/utrie/download/utrie-1.0.1.tgz?cache=0&sync_timestamp=1628857080382&other_urls=https%3A%2F%2Fregistry.nlark.com%2Futrie%2Fdownload%2Futrie-1.0.1.tgz",
"integrity": "sha1-4VUjXry93ImuCSYatudzzmFAGy8=",
"requires": {
"base64-arraybuffer": "^1.0.1"
},
"dependencies": {
"base64-arraybuffer": {
"version": "1.0.1",
"resolved": "https://registry.nlark.com/base64-arraybuffer/download/base64-arraybuffer-1.0.1.tgz",
"integrity": "sha1-h70TUlYm20qYOOAKUIwrc+/PNIw="
}
}
},
"uuid": {
"version": "3.4.0",
"resolved": "https://registry.nlark.com/uuid/download/uuid-3.4.0.tgz",
......@@ -15121,6 +15166,12 @@
"vue-style-loader": "^4.1.0"
}
},
"vue-qr": {
"version": "2.5.0",
"resolved": "https://registry.nlark.com/vue-qr/download/vue-qr-2.5.0.tgz",
"integrity": "sha1-K5OPjUw9B+r55JMbcU4y98oVtd0=",
"dev": true
},
"vue-ref": {
"version": "2.0.0",
"resolved": "https://registry.npm.taobao.org/vue-ref/download/vue-ref-2.0.0.tgz",
......
......@@ -19,6 +19,7 @@
"core-js": "^3.6.5",
"dsbridge": "^3.1.4",
"enc-utils": "^3.0.0",
"html2canvas": "^1.3.2",
"mockjs": "^1.1.0",
"register-service-worker": "^1.7.1",
"secp256k1": "^4.0.2",
......@@ -49,11 +50,13 @@
"eslint-plugin-vue": "^6.2.2",
"less": "^3.0.4",
"less-loader": "^5.0.0",
"moment": "^2.29.1",
"node-sass": "^4.14.1",
"postcss": "^7.0.36",
"sass-loader": "^7.3.1",
"tailwindcss": "npm:@tailwindcss/postcss7-compat@^2.2.9",
"typescript": "~4.1.5",
"vue-qr": "^2.5.0",
"vue-template-compiler": "^2.6.11"
}
}
......@@ -61,11 +61,6 @@ const team = [{
parentId: 0,
id: 3,
name: '运营部',
// children: [{
// parentId: 3,
// id: 31,
// name: '运营子部门',
// }]
}]
}]
......
import { Role } from '@/service/moudles/service.dto'
// 员工信息
export interface Staff {
"email": string,
"entId": string,
"joinTime": number,
"phone": string,
"leaderId": string,
"name": string,
"position": string,
"role": Role,
"depId": string,
"depName": string,
"entName": string,
"id": string,
"workplace": string
}
// 通讯录
export interface Contacts {
[key: string]: Array<Staff>
}
\ No newline at end of file
src/assets/icons/y-chat33.png

670 Bytes | W: | H:

src/assets/icons/y-chat33.png

5.6 KB | W: | H:

src/assets/icons/y-chat33.png
src/assets/icons/y-chat33.png
src/assets/icons/y-chat33.png
src/assets/icons/y-chat33.png
  • 2-up
  • Swipe
  • Onion skin
src/assets/icons/y-downlode.png

360 Bytes | W: | H:

src/assets/icons/y-downlode.png

2.42 KB | W: | H:

src/assets/icons/y-downlode.png
src/assets/icons/y-downlode.png
src/assets/icons/y-downlode.png
src/assets/icons/y-downlode.png
  • 2-up
  • Swipe
  • Onion skin
src/assets/icons/y-weixin.png

576 Bytes | W: | H:

src/assets/icons/y-weixin.png

4.61 KB | W: | H:

src/assets/icons/y-weixin.png
src/assets/icons/y-weixin.png
src/assets/icons/y-weixin.png
src/assets/icons/y-weixin.png
  • 2-up
  • Swipe
  • Onion skin
......@@ -24,6 +24,7 @@
<div class="flex py-3 items-center justify-between">
<slot name="prefix" />
<div class="flex justify-between flex-1" :class="contentClass">
<div v-if="required" class="text-color-primary mr-0.5">*</div>
<div v-if="checkIfEmpty(title)" class="title flex-shrink-0 mr-4" :class="getClass">{{ title }}</div>
<!-- 输入框 -->
<template v-if="type === 'input'">
......@@ -33,7 +34,9 @@
:value="value"
:placeholder="placeholder"
@input="handleInput"
:class="classInput"
@blur="handleBlur"
@focus="handleFocus"
:class="inputClass"
>
</template>
<template v-else>
......@@ -52,6 +55,10 @@
class-name="h-5 w-1 ml-auto flex-shrink-0 ml-1.5"
/>
</div>
<div
class="text-text-warning text-sm pb-1.5 text-right"
v-if="isError"
>{{ errorMessage }}</div>
</div>
</template>
......@@ -90,14 +97,33 @@ export default Vue.extend({
type: String,
default: 'items-center'
},
required: {
type: Boolean,
default: false
},
errorMsg: String,
value: String,
label: String,
content: String
content: String,
validator: Function
},
name: 'CCell',
data() {
return {
isError: false,
errorMessage: ''
}
},
computed: {
getClass(): string {
return `${this.titleColor || ''} ${this.titleClass || '' }`
},
inputClass() {
if (this.isError) {
return `${this.classInput} text-text-warning`
} else {
return `${this.classInput}`
}
}
},
methods: {
......@@ -105,12 +131,34 @@ export default Vue.extend({
this.$emit('click')
},
checkIfEmpty(string: string) {
return string && string.replace(/(^\s*)|(\s*$)/g, '') !== ''
if (typeof string === 'undefined') return false
return string.replace(/(^\s*)|(\s*$)/g, '') !== ''
},
handleInput(e: InputEvent) {
const value = (e.target as HTMLInputElement).value
this.$emit('input', value)
},
handleBlur(e: InputEvent) {
const value = (e.target as HTMLInputElement).value
if (this.required && !this.checkIfEmpty(value)) {
this.isError = true
this.errorMessage = this.errorMsg || '值不能为空'
this.$emit('input', '')
return
}
if (typeof this.validator === 'function') {
this.validator(value, (x: Error) => {
if (typeof x !== 'undefined') {
this.isError = true
this.errorMessage = x.message
}
})
}
},
handleFocus() {
this.isError = false
this.errorMessage = ''
}
}
})
</script>
......
<template>
<div class="mb-px rounded">
<div class="px-4 bg-white mb-px text-sm text-text-secondary py-2 h-9 flex items-center" @click="clickItem">
<div v-if="required" class="text-color-primary mr-0.5">*</div>
<div class="title flex items-center">
<slot name="prefix" />
<div class="">{{ title }}</div>
......@@ -34,6 +35,10 @@ export default Vue.extend({
title: {
type: String,
default: '标题'
},
required: {
type: Boolean,
default: false
}
},
name: 'CCell',
......@@ -42,8 +47,9 @@ export default Vue.extend({
this.$emit('click')
},
checkIfEmpty(string: string) {
return string && string.replace(/(^\s*)|(\s*$)/g, '') !== ''
}
if (typeof string === 'undefined') return false
return string.replace(/(^\s*)|(\s*$)/g, '') !== ''
},
}
})
</script>
......
......@@ -98,7 +98,8 @@ export default Vue.extend({
},
methods: {
checkIfEmpty(string: string) {
return string && string.replace(/(^\s*)|(\s*$)/g, '') !== ''
if (typeof string === 'undefined') return false
return string.replace(/(^\s*)|(\s*$)/g, '') !== ''
},
handleInput(e: InputEvent) {
const value = (e.target as HTMLInputElement).value
......
......@@ -9,12 +9,12 @@ import utils from '@/util'
import service from './service'
import dsbridge from 'dsbridge'
import { Dialog, Toast, Notify }from 'vant'
Vue.config.productionTip = false
Vue.config.productionTip = false
Vue.use(Dialog).use(Toast).use(Notify)
Vue.use(utils).use(service)
Vue.prototype.$dsbridge = dsbridge
new Vue({
router,
store,
......
export enum Role {
TEAM_LEDER = 0,
SUPER_ADMIN = 1,
CLIENT_MANAGER = 2,
COMMOM_MEMBER = 3
}
export enum Apply {
PENDING = 0,
REJECT = 1,
PASS = 2
}
// 企业
export interface AcceptJoinDTO{
"expiration": number,
......@@ -84,7 +96,7 @@ export interface ChangeDepDTO {
export interface ChangeRoleDTO {
"id": string,
"role": 1 | 2 | 3, // 1:超级管理员;2:客户管理员;3:普通人员
"role": Role, // 1:超级管理员;2:客户管理员;3:普通人员
"entId": string
}
......@@ -128,12 +140,12 @@ export interface JoinApplyDTO {
"joinTime": number,
"phone": string,
"position": string,
"status": 1 | 2
"status": Apply
}
export interface QuitApplyDTO {
"applyId": string,
"status": 1 | 2
"status": Apply
}
export interface SubmitJoinApplyDTO {
......
......@@ -7,11 +7,15 @@ Vue.use(Vuex)
export default new Vuex.Store({
state: {
enterpriseInfo: undefined
enterpriseInfo: undefined,
acceptJoin: undefined
},
mutations: {
setEnterpriseInfo(state, payload) {
state.enterpriseInfo = payload
},
setAcceptJoin(state, payload) {
state.acceptJoin = payload
}
},
actions: {
......
......@@ -12,7 +12,8 @@ enum BridgeMethods{
SCAN_CODE="scanCode",
OPEN_COMPANY_USER_INFO = 'openCompanyUserInfo',
Back='back',
GEN_JOIN_FORM= 'genJoinForm'
GEN_JOIN_FORM= 'genJoinForm',
SIGN='sign'
}
/**
......@@ -76,6 +77,18 @@ export function scanCode(){
return data
}
/**
* 接受邀请验签hash
* @returns
*/
export function getSign(obj: object){
let data = dsbridge.call(BridgeMethods.SIGN,{
...obj
},(res)=>{
return res
})
return data
}
// /**
// * 提交
......
import Mock from 'mockjs'
import {strChineseFirstPY} from './strChineseFirstPY'
import { oMultiDiff } from './oMultiDiff'
import { Staff } from '@/Interface'
//参数,中文字符串
//返回值:拼音首字母串数组
export function makePy(str:string) {
if(typeof(str) != "string") {
throw new Error("函数makePy需要字符串类型参数!")
}
var arrResult = new Array(); //保存中间结果的数组
for(var i = 0, len = str.length; i < len; i++) {
//获得unicode码
var ch = str.charAt(i)
//检查该unicode码是否在处理范围之内,在则返回该码对映汉字的拼音首字母,不在则调用其它函数处理
arrResult.push(checkCh(ch))
}
//处理arrResult,返回所有可能的拼音首字母串数组
return mkRslt(arrResult)
}
function checkCh(ch: string) {
const uni = ch.charCodeAt(0)
//如果不在汉字处理范围之内,返回原字符,也可以调用自己的处理函数
if(uni > 40869 || uni < 19968) {
return ch //dealWithOthers(ch)
}
//检查是否是多音字,是按多音字处理,不是就直接在strChineseFirstPY字符串中找对应的首字母
return(oMultiDiff[uni] ? oMultiDiff[uni] : (strChineseFirstPY.charAt(uni - 19968)))
}
function mkRslt(arr: Array<string>) {
let arrRslt = ['']
for(let i = 0, len = arr.length; i < len; i++) {
const str = arr[i]
const strlen = str.length
if(strlen == 1) {
for(let k = 0; k < arrRslt.length; k++) {
arrRslt[k] += str
}
} else {
const tmpArr = arrRslt.slice(0)
arrRslt = []
for(let k = 0; k < strlen; k++) {
//复制一个相同的arrRslt
var tmp = tmpArr.slice(0)
//把当前字符str[k]添加到每个元素末尾
for(let j = 0; j < tmp.length; j++) {
tmp[j] += str.charAt(k)
}
//把复制并修改后的数组连接到arrRslt上
arrRslt = arrRslt.concat(tmp)
}
}
}
return arrRslt
}
//两端去空格函数
export function trim (str: string) {
return str.replace(/(^\s*)|(\s*$)/g, "")
}
let arr = []
interface Contact {
[key: string]: Array<Staff>
}
export const contacts: Contact = {}
for (let i=0; i<=10; i++) {
const person: Staff = {
email: Mock.mock('@email'),
entId: 'string',
joinTime: 111,
phone: Mock.mock('@id'),
leaderId: Mock.mock('@id'),
name: Mock.mock('@cname'),
position: 'string',
role: Mock.mock({"number|0-6": 0}).number,
depId: Mock.mock('@id'),
depName: 'string',
entName: 'string',
id: Mock.mock('@id'),
workplace: 'string'
}
arr.push(person)
}
arr.forEach(item => {
const firstPy = makePy(item.name)[0].slice(0,1).toUpperCase()
if (typeof contacts[firstPy] === 'undefined') {
contacts[firstPy] = [item]
} else {
contacts[firstPy].push(item)
}
})
// const keys = Object.keys(list).sort()
// export const contacts:Contact = {}
// console.log(keys, 'keys')
//此处收录了375个多音字
interface MultiDiff {
[key: string]: any
}
export const oMultiDiff: MultiDiff = {
"19969": "DZ",
"19975": "WM",
"19988": "QJ",
"20048": "YL",
"20056": "SC",
"20060": "NM",
"20094": "QG",
"20127": "QJ",
"20167": "QC",
"20193": "YG",
"20250": "KH",
"20256": "ZC",
"20282": "SC",
"20285": "QJG",
"20291": "TD",
"20314": "YD",
"20340": "NE",
"20375": "TD",
"20389": "YJ",
"20391": "CZ",
"20415": "PB",
"20446": "YS",
"20447": "SQ",
"20608": "KG",
"20854": "QJ",
"20857": "ZC",
"20911": "PF",
"20504": "TC",
"20985": "AW",
"21032": "PB",
"21048": "XQ",
"21049": "SC",
"21089": "YS",
"21119": "JC",
"21242": "SB",
"21273": "SC",
"21305": "YP",
"21306": "QO",
"21330": "ZC",
"21333": "SDC",
"21345": "QK",
"21378": "CA",
"21397": "SC",
"21414": "XS",
"21442": "SC",
"21477": "JG",
"21480": "TD",
"21484": "ZS",
"21494": "YX",
"21505": "YX",
"21512": "HG",
"21523": "XH",
"21537": "PB",
"21542": "PF",
"21549": "KH",
"21571": "E",
"21574": "DA",
"21588": "TD",
"21589": "O",
"21618": "ZC",
"21621": "KHA",
"21632": "ZJ",
"21654": "KG",
"21679": "LKG",
"21683": "KH",
"21710": "A",
"21719": "YH",
"21734": "WOE",
"21769": "A",
"21780": "WN",
"21804": "XH",
"21834": "A",
"21899": "ZD",
"21903": "RN",
"21908": "WO",
"21939": "ZC",
"21956": "SA",
"21964": "YA",
"21970": "TD",
"22003": "A",
"22031": "JG",
"22040": "XS",
"22060": "ZC",
"22066": "ZC",
"22079": "MH",
"22129": "XJ",
"22179": "XA",
"22237": "NJ",
"22244": "TD",
"22280": "JQ",
"22300": "YH",
"22313": "XW",
"22331": "YQ",
"22343": "YJ",
"22351": "PH",
"22395": "DC",
"22412": "TD",
"22484": "PB",
"22500": "PB",
"22534": "ZD",
"22549": "DH",
"22561": "PB",
"22612": "TD",
"22771": "KQ",
"22831": "HB",
"22841": "JG",
"22855": "QJ",
"22865": "XQ",
"23013": "ML",
"23081": "WM",
"23487": "SX",
"23558": "QJ",
"23561": "YW",
"23586": "YW",
"23614": "YW",
"23615": "SN",
"23631": "PB",
"23646": "ZS",
"23663": "ZT",
"23673": "YG",
"23762": "TD",
"23769": "ZS",
"23780": "QJ",
"23884": "QK",
"24055": "XH",
"24113": "DC",
"24162": "ZC",
"24191": "GA",
"24273": "QJ",
"24324": "NL",
"24377": "TD",
"24378": "QJ",
"24439": "PF",
"24554": "ZS",
"24683": "TD",
"24694": "WE",
"24733": "LK",
"24925": "TN",
"25094": "ZG",
"25100": "XQ",
"25103": "XH",
"25153": "PB",
"25170": "PB",
"25179": "KG",
"25203": "PB",
"25240": "ZS",
"25282": "FB",
"25303": "NA",
"25324": "KG",
"25341": "ZY",
"25373": "WZ",
"25375": "XJ",
"25384": "A",
"25457": "A",
"25528": "SD",
"25530": "SC",
"25552": "TD",
"25774": "ZC",
"25874": "ZC",
"26044": "YW",
"26080": "WM",
"26292": "PB",
"26333": "PB",
"26355": "ZY",
"26366": "CZ",
"26397": "ZC",
"26399": "QJ",
"26415": "ZS",
"26451": "SB",
"26526": "ZC",
"26552": "JG",
"26561": "TD",
"26588": "JG",
"26597": "CZ",
"26629": "ZS",
"26638": "YL",
"26646": "XQ",
"26653": "KG",
"26657": "XJ",
"26727": "HG",
"26894": "ZC",
"26937": "ZS",
"26946": "ZC",
"26999": "KJ",
"27099": "KJ",
"27449": "YQ",
"27481": "XS",
"27542": "ZS",
"27663": "ZS",
"27748": "TS",
"27784": "SC",
"27788": "ZD",
"27795": "TD",
"27812": "O",
"27850": "PB",
"27852": "MB",
"27895": "SL",
"27898": "PL",
"27973": "QJ",
"27981": "KH",
"27986": "HX",
"27994": "XJ",
"28044": "YC",
"28065": "WG",
"28177": "SM",
"28267": "QJ",
"28291": "KH",
"28337": "ZQ",
"28463": "TL",
"28548": "DC",
"28601": "TD",
"28689": "PB",
"28805": "JG",
"28820": "QG",
"28846": "PB",
"28952": "TD",
"28975": "ZC",
"29100": "A",
"29325": "QJ",
"29575": "SL",
"29602": "FB",
"30010": "TD",
"30044": "CX",
"30058": "PF",
"30091": "YSP",
"30111": "YN",
"30229": "XJ",
"30427": "SC",
"30465": "SX",
"30631": "YQ",
"30655": "QJ",
"30684": "QJG",
"30707": "SD",
"30729": "XH",
"30796": "LG",
"30917": "PB",
"31074": "NM",
"31085": "JZ",
"31109": "SC",
"31181": "ZC",
"31192": "MLB",
"31293": "JQ",
"31400": "YX",
"31584": "YJ",
"31896": "ZN",
"31909": "ZY",
"31995": "XJ",
"32321": "PF",
"32327": "ZY",
"32418": "HG",
"32420": "XQ",
"32421": "HG",
"32438": "LG",
"32473": "GJ",
"32488": "TD",
"32521": "QJ",
"32527": "PB",
"32562": "ZSQ",
"32564": "JZ",
"32735": "ZD",
"32793": "PB",
"33071": "PF",
"33098": "XL",
"33100": "YA",
"33152": "PB",
"33261": "CX",
"33324": "BP",
"33333": "TD",
"33406": "YA",
"33426": "WM",
"33432": "PB",
"33445": "JG",
"33486": "ZN",
"33493": "TS",
"33507": "QJ",
"33540": "QJ",
"33544": "ZC",
"33564": "XQ",
"33617": "YT",
"33632": "QJ",
"33636": "XH",
"33637": "YX",
"33694": "WG",
"33705": "PF",
"33728": "YW",
"33882": "SR",
"34067": "WM",
"34074": "YW",
"34121": "QJ",
"34255": "ZC",
"34259": "XL",
"34425": "JH",
"34430": "XH",
"34485": "KH",
"34503": "YS",
"34532": "HG",
"34552": "XS",
"34558": "YE",
"34593": "ZL",
"34660": "YQ",
"34892": "XH",
"34928": "SC",
"34999": "QJ",
"35048": "PB",
"35059": "SC",
"35098": "ZC",
"35203": "TQ",
"35265": "JX",
"35299": "JX",
"35782": "SZ",
"35828": "YS",
"35830": "E",
"35843": "TD",
"35895": "YG",
"35977": "MH",
"36158": "JG",
"36228": "QJ",
"36426": "XQ",
"36466": "DC",
"36710": "JC",
"36711": "ZYG",
"36767": "PB",
"36866": "SK",
"36951": "YW",
"37034": "YX",
"37063": "XH",
"37218": "ZC",
"37325": "ZC",
"38063": "PB",
"38079": "TD",
"38085": "QY",
"38107": "DC",
"38116": "TD",
"38123": "YD",
"38224": "HG",
"38241": "XTC",
"38271": "ZC",
"38415": "YE",
"38426": "KH",
"38461": "YD",
"38463": "AE",
"38466": "PB",
"38477": "XJ",
"38518": "YT",
"38551": "WK",
"38585": "ZC",
"38704": "XS",
"38739": "LJ",
"38761": "GJ",
"38808": "SQ",
"39048": "JG",
"39049": "XJ",
"39052": "HG",
"39076": "CZ",
"39271": "XT",
"39534": "TD",
"39552": "TD",
"39584": "PB",
"39647": "SB",
"39730": "LG",
"39748": "TPB",
"40109": "ZQ",
"40479": "ND",
"40516": "HG",
"40536": "HG",
"40583": "QJ",
"40765": "YQ",
"40784": "QJ",
"40840": "YK",
"40863": "QJG"
}
\ No newline at end of file
This diff is collapsed.
import moment from 'moment'
export function formatDate(date: Date, type: string = 'YYYY-MM-DD HH:mm:ss') {
return moment(date).format(type)
}
\ No newline at end of file
......@@ -2,7 +2,7 @@
<!-- 添加部门 -->
<main-page
left-arrow
@click-left="$router.push('/team')"
@click-left="$router.go(-1)"
>
<div class="pt-14 px-4">
<input-cell
......@@ -21,7 +21,11 @@
/>
</group-cell>
<group-cell class="mt-4" title="所属团队">
<c-cell dot title="杭州复杂美科技有限公司" />
<c-cell
dot
title="杭州复杂美科技有限公司"
@click="$router.push('/team/select-team')"
/>
</group-cell>
<c-button round class="mt-10">
确定
......
......@@ -15,18 +15,23 @@
error-msg="姓名不能为空"
/>
<input-cell
required
v-model="position"
:limit="10"
label="职位"
placeholder="请输入职位"
error-msg="职位不能为空"
/>
<!-- 手机号/员工编号/入职时间 -->
<c-cell
<c-cell
required
title="手机号"
v-model="tel"
v-model="phone"
placeholder="请输入手机号"
error-msg="手机号码不能为空"
class="mt-4"
type="input"
:validator="checkPhone"
/>
<c-cell
title="员工编号"
......@@ -36,6 +41,7 @@
/>
<c-cell
dot
required
v-model="date"
title="入职时间"
:content="date"
......@@ -45,13 +51,14 @@
v-model="show"
:round="false"
color="#4F62C1"
@confirm="onConfirm"
:show-confirm="false"
@confirm="selectJoinTime"
:show-confirm="true"
:style="{ height:'100%'}"
/>
<!-- 选择部门 -->
<group-cell
dot
required
class="mt-4" title="所属部门"
@click="$router.push('/team/select-team')"
>
......@@ -59,7 +66,7 @@
</group-cell>
<!--按钮-->
<div class="fixed bottom-0 left-0 w-full px-4 py-1.5 bg-common-bg">
<c-button @click="$router.push('/team/two-code')">
<c-button @click="generateQrCode">
生成邀请二维码
</c-button>
</div>
......@@ -71,8 +78,12 @@
<script lang="ts">
import Vue from 'vue'
import { Calendar } from 'vant';
Vue.use(Calendar);
import { Calendar } from 'vant'
import {AcceptJoinDTO} from '@/service/moudles/service.dto'
import {trim} from '@/util/Contact'
Vue.use(Calendar)
export default Vue.extend({
name: 'AddMember',
components: {
......@@ -83,20 +94,40 @@ export default Vue.extend({
'group-cell': () => import('@/components/common/group-cell.vue')
},
created() {
this.depId = (this.$route.query.teamId || '') as string
// this.depId = (this.$route.query.teamId || '') as string
},
data() {
return {
// "expiration": number,
// "inviterId": string,
// "name": string,
// "oaServer": string,
// "depId": string,
// "entId": string,
// "hash": string,
joinTime: new Date().getTime(),
// "position": string
name: '',//姓名
position:'',
tel: '',//电话号码
phone: '',//电话号码
digit: '',//员工编号
date: '请选择入职时间',//入职时间
show:false,//日期弹窗
depId: ''
depId: '123'
}
},
methods: {
validatePhone(val: string) {
const reg = /^1[3456789]\d{9}$/
return reg.test(val)
},
checkPhone(value: any, callback: Function) {
if (!this.validatePhone(value)) {
callback(new Error('手机号码格式有误,请重新输入'))
} else {
callback()
}
},
handleClickLeft() {
this.$router.go(-1)
},
......@@ -104,12 +135,38 @@ export default Vue.extend({
//获取日期
return `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()}`;
},
onConfirm(date:Date) {
//日期
this.show = false;
this.date = this.formatDate(date);
// 入职日期
selectJoinTime(date:Date) {
this.joinTime = new Date(date).getTime()
this.show = false
this.date = this.formatDate(date)
},
generateQrCode() {
if (!this.validatePhone(this.phone) || trim(this.name) === '' || trim(this.position) === '' || this.joinTime === 0 || trim(this.depId) === '') {
this.$toast('请检查输入内容')
return
}
this.$dialog.confirm({
title: '提示',
message: '确定保存该成员信息,并生成成员信息二维码邀请该成员加入团队?',
// confirmButtonText: '解散'
}).then(() => {
const data = {
expiration: 1,
inviterId: "inviterId",
name: this.name,
oaServer: "oaServer",
depId: this.depId,
entId: "entId",
hash: "hash",
joinTime: this.joinTime,
phone: this.phone,
position: this.position
}
this.$store.commit('setAcceptJoin', data)
this.$router.push('/team/two-code')
}).catch(() => {})
}
}
})
</script>
......
......@@ -8,17 +8,17 @@
/>
<div class="ml-3">{{ member.name }}</div>
<div
v-if="member.isDirector || member.isLeader"
v-if="[0, 1].indexOf(member.role) > -1"
class="tag ml-1.5 text-xs text-white px-1 py-0.5 bg-color-primary rounded"
>
{{ member.isLeader ? '负责人' : '主管'}}
{{ tagName(member)}}
</div>
</div>
</template>
<script lang="ts">
import Vue from 'vue'
import { Member } from '@/DTO'
import { Staff } from '@/Interface'
export default Vue.extend({
components:{
......@@ -35,8 +35,22 @@ export default Vue.extend({
}
},
methods: {
handleClick(member: Member) {
handleClick(member: Staff) {
this.$emit('click', member)
},
tagName(member: Staff) {
let role = ''
switch (member.role) {
case 0:
role = '负责人'
break
case 1:
role = '管理员'
break
default:
role = ''
}
return role
}
}
})
......
......@@ -45,13 +45,13 @@
<!-- 成员 -->
<div class="members">
<div
v-for="(value, key) in contacts"
v-for="(value, key) in list"
:key="key"
:ref="key"
>
<div class="text-text-secondary py-1 sticky top-12 bg-white z-10">{{ key }}</div>
<div
v-for="(member, index) in contacts[key]"
v-for="(member, index) in list[key]"
:key="index"
class="flex items-center"
>
......@@ -86,8 +86,8 @@
<script lang="ts">
import Vue from 'vue'
import { Person } from '@/DTO'
import { Member } from '@/DTO'
import { Staff, Contacts } from '@/Interface'
import { Role } from '@/service/moudles/service.dto'
export default Vue.extend({
props: {
......@@ -121,25 +121,32 @@ export default Vue.extend({
}
},
mounted() {
window.addEventListener('scroll', this.debounce(this.scrollHandler, 200))
window.addEventListener('scroll', this.scrollHandler)
},
beforeDestroy() {
window.removeEventListener('scroll', this.debounce(this.scrollHandler, 200))
window.removeEventListener('scroll', this.scrollHandler)
},
computed: {
leaders() {
let arr: Array<Person> = []
let arr: Array<Staff> = []
for (const key in this.contacts) {
arr = arr.concat(this.contacts[key])
}
return arr.filter(item => item.isLeader || item.isDirector).sort((a, b) => Number(b.isLeader) - Number(a.isLeader))
return arr.filter(item => item.role === Role.TEAM_LEDER || item.role === Role.SUPER_ADMIN ).sort((a, b) => b.role - a.role)
},
navs() {
let arr: Array<string> = []
for (let key in this.contacts) {
arr.push(key)
}
return arr
return arr.sort()
},
list() {
const obj: Contacts = {}
this.navs.forEach(nav => {
obj[nav] = this.contacts[nav]
})
return obj
}
},
methods: {
......@@ -149,9 +156,6 @@ export default Vue.extend({
if (timer !== null) {
clearTimeout(timer)
}
// timer = setTimeout(() => {
// fn()
// }, delay)
}
},
scrollHandler() {
......@@ -172,14 +176,14 @@ export default Vue.extend({
const top = div.getBoundingClientRect().top
document.documentElement.scrollTop = this.scrollTop + top - 48
},
clickMember(member: Member) {
clickMember(member: Staff) {
if(this.radio) {
this.handleCheck(member)
return
}
this.$emit('click-member', member)
},
handleCheck(member: Member) {
handleCheck(member: Staff) {
let arr = Array.from(this.checked)
const index = arr.findIndex(id => id === member.id)
if (index > -1) {
......
<template>
<!-- 选择部门 -->
<div class="select-team">
<main-page left-arrow @click-left="$router.push('/team')">
<main-page left-arrow @click-left="$router.go(-1)">
<template slot="right">
<app-icon
type="png"
......
......@@ -55,10 +55,12 @@
<script lang="ts">
import Vue from 'vue'
import { team, contacts } from '@/DTO'
import { team } from '@/DTO'
import { Member } from '@/DTO'
import {useLocalStorageState} from 'ahooks-vue'
import { getUserInfo } from '@/util/Bridge'
import { contacts } from '@/util/Contact'
export default Vue.extend({
name: 'TeamFrame',
components: {
......@@ -69,13 +71,6 @@ export default Vue.extend({
'c-button': () => import('@/components/common/c-button.vue'),
'switch-cell': () => import('@/components/common/switch-cell.vue')
},
created() {
// console.log(Mock, 'mock')
this.showRadio = this.$route.query.showRadio === '1'
},
mounted(){
useLocalStorageState('USER_INFO',getUserInfo())
},
data() {
return {
title: '导航',
......@@ -83,14 +78,37 @@ export default Vue.extend({
contacts,
checkedMemberId: [],
showRadio: false,
ifContainChildDep: true
ifContainChildDep: true,
enterpriseInfo: {}
}
},
created() {
// console.log(Mock, 'mock')
this.showRadio = this.$route.query.showRadio === '1'
},
mounted(){
useLocalStorageState('USER_INFO',getUserInfo())
// this.$service.enterprise.getEnterpriseInfo({
// id: '166910771849072640'
// }).then((res: any)=> {
// const {data} = res
// this.enterpriseInfo = data.data
// this.$store.commit('setEnterpriseInfo', data.data)
// })
this.getStaff()
},
methods: {
// handleClickLeft() {
// console.log('click left')
// this.$router.go(-1)
// },
// 获取成员
getStaff() {
this.$service.department.getSub({
parentId: '166910771849072641',
entId: '166910771849072640',
hasStaff: true,
isDirect: this.ifContainChildDep
}).then((res: any) => {
console.log(res.data, 'data')
})
},
clickMember(member: Member) {
this.$router.push(`/team/team-member/${member.id}`)
},
......
......@@ -55,6 +55,7 @@
<script lang="ts">
import Vue from 'vue'
import {getUserInfo} from '@/util/Bridge'
export default Vue.extend({
components:{
......@@ -69,14 +70,8 @@ export default Vue.extend({
enterpriseInfo: {}
}
},
mounted(){
this.$service.enterprise.getEnterpriseInfo({
id: '166910771849072640'
}).then((res: any)=> {
const {data} = res
this.enterpriseInfo = data.data
this.$store.commit('setEnterpriseInfo', data.data)
})
mounted() {
console.log(getUserInfo(), 'pppp')
},
methods: {
editTeamName() {
......
......@@ -5,36 +5,45 @@
@click-left="handleClickLeft"
>
<div class="mx-4 pt-14">
<div class="shadow-md rounded overflow-hidden">
<div class="bg-color-primary-lighter text-center h-24 pt-6">
<div class="shadow-md rounded overflow-hidden" id="qrcode">
<div class="bg-color-primary text-center h-24 pt-6">
<div class="text-white flex-initial">{{msg1}}</div>
<div class="text-gray-300 flex-initial">团队号:{{msg2}}</div>
</div>
<div class="bg-white">
<div class="flex flex-row justify-around">
<div class="pt-7 w-1/2 px-5">
<van-image class="w-32 h-32"
<!-- <van-image class="w-32 h-32"
:src="require('@/assets/icons/y-code.png')"
/>
/> -->
<div class="w-32 h-32">
<vue-qr
:logoSrc="require('@/assets/icons/y-chat33.png')"
:text="qrCodeText"
:correct-level="3"
:margin="2"
:size="400"
/>
</div>
</div>
<div class="w-1/2 space-y-2 flex-col text-base text-left pt-7 px-4">
<div class="text-lg font-bold pb-1">张三</div>
<div >职位:产品经理</div>
<div class="text-lg font-bold pb-1">{{ joinInfo.name || '张三' }}</div>
<div >职位:{{ joinInfo.position }}</div>
<div >部门:产品设计部</div>
<div >2019-12-1</div>
<div >{{ formatDate(joinInfo.joinTime, 'YYYY-MM-DD') || '2021-09-05' }}</div>
</div>
</div>
<div class=" text-center text-gray-400 pb-8 pt-4">{{msg3}}</div>
</div>
</div>
<div class="flex justify-center pt-8 text-color-primary-lighter font-medium text-sm text-center px-7">
<div class="flex justify-center pt-8 text-color-primary font-medium text-sm text-center px-7">
<div class=" flex-initial mx-3">
<code-icon :path="require('@/assets/icons/y-chat33.png')" class-name="h-9 w-9"/> Chat33
</div>
<div class="flex-initial mx-3">
<code-icon :path="require('@/assets/icons/y-weixin.png')" class-name="h-9 w-9"/>微信
</div>
<div class="flex-initial mx-3">
<div class="flex-initial mx-3" @click="saveQrcode">
<code-icon :path="require('@/assets/icons/y-downlode.png')" class-name="h-9 w-9"/>保存
</div>
</div>
......@@ -46,30 +55,76 @@
<script lang="ts">
import Vue from 'vue'
import { Image } from 'vant';
Vue.use(Image);
import { Image } from 'vant'
import { formatDate } from '@/util/FormatDate'
import VueQr from 'vue-qr'
import html2canvas from 'html2canvas'
import { CanvasRenderer } from 'html2canvas/dist/types/render/canvas/canvas-renderer'
Vue.use(Image)
export default Vue.extend({
name: 'Two-code',
components: {
'main-page': () => import('@/layout/main-page.vue'),
'code-icon':()=>import('@/components/common/Icon.vue'),
'c-button': () => import('@/components/common/c-button.vue')
'c-button': () => import('@/components/common/c-button.vue'),
VueQr,
},
created() {
async created() {
// console.log(Mock, 'mock')
this.joinInfo = this.$store.state.acceptJoin || {}
this.qrCodeText = JSON.stringify(this.joinInfo)
this.dpr()
// this.drawCanvas()
},
data() {
return {
formatDate,
msg1:'团队名称',
msg2:'ABCDEF',
msg3:'扫描二维码加入我们chat33的团队'
msg3:'扫描二维码加入我们chat33的团队',
joinInfo: {},
qrCodeText:''
}
},
methods: {
handleClickLeft() {
this.$router.push('/team')
},
dpr() {
console.log(window.devicePixelRatio, 'pixel')
if (window.devicePixelRatio && window.devicePixelRatio > 1) {
return window.devicePixelRatio
}
return 1
},
async drawCanvas(selector: string) {
// 获取节点
const dom = document.getElementById(selector) as HTMLDivElement
// 获取节点高度
const {width, height} = dom?.getBoundingClientRect()
// 获取像素比
const scaleBy = this.dpr()
// 创建canvas
const canvas = document.createElement('canvas')
canvas.width = width * scaleBy
canvas.height = height * scaleBy
// canvas.style.width = `${width}px`
// canvas.style.height = `${height}px`
// const context = canvas.getContext('2d')
// context?.scale(1, 1)
return await html2canvas(dom, {canvas}).then(() => {
const url = canvas.toDataURL('image/png')
const a =document.createElement('a')
const event = new MouseEvent('click')
a.download = '邀请码'
a.href = url
a.dispatchEvent(event)
})
},
async saveQrcode() {
await this.drawCanvas('qrcode')
}
}
})
</script>
......
declare module 'vue-qr'
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment