Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
H
horse
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
向伟
horse
Commits
c0b88b7e
Commit
c0b88b7e
authored
Nov 25, 2021
by
罗超
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
1
parent
4c99e7ee
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
1333 additions
and
737 deletions
+1333
-737
customRight.vue
src/components/common/customRight.vue
+770
-547
fileUpload.vue
src/components/common/fileUpload.vue
+156
-69
customerSetup.vue
src/pages/customer/customerSetup.vue
+22
-6
getters.ts
src/store/modules/user/getters.ts
+3
-0
state.ts
src/store/modules/user/state.ts
+1
-0
common.ts
src/utils/common.ts
+0
-115
upload.ts
src/utils/upload.ts
+381
-0
No files found.
src/components/common/customRight.vue
View file @
c0b88b7e
This diff is collapsed.
Click to expand it.
src/components/common/fileUpload.vue
View file @
c0b88b7e
<
template
>
<
template
>
<div>
<div>
<template
v-if=
"!data.isShowEdit"
>
<template
v-if=
"!data.isShowEdit"
>
<q-input
filled
bg-color=
"myInput"
@
focus=
"data.isShowEdit
=
true"
label=
"请输入跟进记录"
/>
<q-input
filled
bg-color=
"myInput"
@
focus=
"data.isShowEdit
=
true"
label=
"请输入跟进记录"
/>
</
template
>
</
template
>
<
template
v-else
>
<
template
v-else
>
<div
class=
"editer_input"
>
<div
class=
"editer_input"
>
<q-input
v-model=
"text"
style=
"50px"
maxlength=
"1000"
type=
"textarea"
placeholder=
"请填写跟进记录"
/>
<q-input
v-model=
"msg.Remark"
maxlength=
"1000"
type=
"textarea"
placeholder=
"请填写跟进记录"
/>
<!--
<div></div>
-->
<div
class=
"file_box"
>
<div
class=
"img_list"
>
<div
v-for=
"(e,i) in msg.ImageList"
:key=
"i"
class=
"img_box"
>
<img
:src=
"e"
class=
"img"
/>
<q-icon
name=
"cancel"
color=
"primary"
class=
"del_icon"
@
click=
"delImg(i)"
/>
</div>
</div>
<div
class=
"file_list"
>
<div
v-for=
"(e,i) in msg.FileList"
:key=
"i"
class=
"flex items-center file_box"
>
<div
class=
"flex items-center"
>
附件:
<span
style=
"color:#333"
>
{{
e
.
FileName
}}
</span>
(
{{
e
.
size
}}
)
</div>
<div
class=
"del_btn"
@
click=
"delFile(i)"
>
删除
</div>
</div>
</div>
</div>
<div
class=
"file_Space"
>
<div
class=
"file_Space"
>
<div
style=
"display:flex;align-items:center;"
>
<div
style=
"display:flex;align-items:center;"
>
<div>
<div>
<a-upload
v-model:file-list=
"data.imageList"
name=
"file"
:multiple=
"true"
<a-upload
action=
"https://www.mocky.io/v2/5cc8019d300000980a055e76"
@
change=
"uploadImg"
>
accept=
"image/*"
v-model:file-list=
"data.imageList"
name=
"file"
:multiple=
"true"
:show-upload-list=
"false"
:customRequest=
"customUploadImg"
>
<i
style=
"font-size:25px;cursor:pointer;"
class=
"iconfont icon-picture"
></i>
<i
style=
"font-size:25px;cursor:pointer;"
class=
"iconfont icon-picture"
></i>
</a-upload>
</a-upload>
</div>
</div>
<div
style=
"margin-left:8px;"
>
<div
style=
"margin-left:8px;"
>
<a-upload
v-model:file-list=
"data.fileList"
name=
"file"
:multiple=
"true"
<a-upload
action=
"https://www.mocky.io/v2/5cc8019d300000980a055e76"
@
change=
"handleChange"
>
v-model:file-list=
"data.fileList"
name=
"file"
:multiple=
"true"
:show-upload-list=
"false"
:customRequest=
"customUploadFile"
>
<i
style=
"font-size:20px;cursor:pointer;"
class=
"iconfont icon-paperclip"
></i>
<i
style=
"font-size:20px;cursor:pointer;"
class=
"iconfont icon-paperclip"
></i>
</a-upload>
</a-upload>
</div>
</div>
</div>
</div>
<div>
<div>
<q-btn
color=
"myInput"
text-color=
"#000"
size=
"sm"
@
click=
"data.isShowEdit=false"
label=
"取消"
/>
<q-btn
<q-btn
color=
"primary"
style=
"margin-left:10px;"
size=
"sm"
label=
"确定"
/>
color=
"myInput"
text-color=
"#000"
size=
"sm"
@
click=
"data.isShowEdit = false"
label=
"取消"
/>
<q-btn
color=
"primary"
style=
"margin-left:10px;"
size=
"sm"
@
click=
"save"
label=
"确定"
/>
</div>
</div>
</div>
</div>
</div>
</div>
...
@@ -32,76 +66,129 @@
...
@@ -32,76 +66,129 @@
</div>
</div>
</template>
</template>
<
script
lang=
"ts"
>
<
script
lang=
"ts"
>
import
{
import
{
reactive
,
reactive
,
}
from
'vue'
inject
// import message from '@/utils/messag
e'
}
from
'vu
e'
//
import customer2 from '@/api/customer2'
import
customer2
from
'@/api/customer2'
export
default
{
import
massage
from
"@/utils/message"
setup
()
{
import
{
UploadSelfFile
}
from
'@/utils/upload'
interface
dataParam
{
interface
dataParam
{
[
key
:
string
]:
any
[
key
:
string
]:
any
}
}
interface
FileItem
{
export
default
{
uid
:
string
;
setup
(
props
,
ctx
)
{
name
?:
string
;
let
msg
=
reactive
<
dataParam
>
({
status
?:
string
;
CustomerId
:
inject
(
'CustomerId'
),
response
?:
string
;
Remark
:
""
,
url
?:
string
;
ImageList
:
[],
}
FileList
:
[]
interface
FileInfo
{
})
file
:
FileItem
;
const
data
=
reactive
<
dataParam
>
({
fileList
:
FileItem
[];
}
const
data
=
reactive
<
dataParam
>
({
isShowEdit
:
false
,
isShowEdit
:
false
,
fileList
:
[],
fileList
:
[],
imageList
:
[]
imageList
:
[]
})
})
const
uploadImg
=
(
info
:
FileInfo
)
=>
{
let
customUploadImg
=
(
file
)
=>
{
if
(
info
.
file
.
status
!==
'uploading'
)
{
UploadSelfFile
(
'/horse'
,
file
.
file
,
(
res
)
=>
{
console
.
log
(
info
.
file
,
info
.
fileList
);
msg
.
ImageList
.
push
(
res
.
FileUrl
)
})
}
let
customUploadFile
=
(
file
)
=>
{
UploadSelfFile
(
'/horse'
,
file
.
file
,
(
res
)
=>
{
msg
.
FileList
.
push
({
FileName
:
res
.
FileName
,
FileUrl
:
res
.
FileUrl
,
size
:
res
.
Size
})
})
}
const
delImg
=
(
i
)
=>
{
msg
.
ImageList
.
splice
(
i
,
1
)
}
const
delFile
=
(
i
)
=>
{
msg
.
FileList
.
splice
(
i
,
1
)
}
const
save
=
()
=>
{
customer2
.
setCustomerTripFollowUpInfo
(
msg
).
then
((
res
)
=>
{
massage
.
successMsg
(
res
.
data
.
Message
)
msg
.
Remark
=
""
msg
.
ImageList
=
[]
msg
.
FileList
=
[]
ctx
.
emit
(
"success"
)
})
}
}
console
.
log
(
info
,
'info'
);
// if (info.file.status === 'done') {
// message.success(`${info.file.name} file uploaded successfully`);
// } else if (info.file.status === 'error') {
// message.error(`${info.file.name} file upload failed.`);
// }
};
// onMounted(() => {
// })
return
{
return
{
msg
,
data
,
data
,
uploadImg
customUploadImg
,
}
customUploadFile
,
delImg
,
delFile
,
UploadSelfFile
,
save
}
}
}
}
}
</
script
>
</
script
>
<
style
lang=
"scss"
>
<
style
lang=
"scss"
scoped
>
.editer_input
{
.editer_input
{
padding
:
5px
0
;
padding
:
5px
0
;
}
}
.myInput
{
.myInput
{
background-color
:
#f6f6f6
!
important
;
background-color
:
#f6f6f6
!
important
;
}
}
.file_box
{
margin-top
:
5px
;
.img_list
{
display
:
flex
;
flex-wrap
:
wrap
;
.img_box
{
width
:
40px
;
height
:
40px
;
margin
:
10px
;
.file_Space
{
position
:
relative
;
.img
{
width
:
100%
;
height
:
100%
;
overflow
:
hidden
;
object-fit
:
cover
;
}
.del_icon
{
font-size
:
18px
;
position
:
absolute
;
top
:
0
;
right
:
0
;
transform
:
translate
(
50%
,
-50%
);
}
}
}
.file_list
{
.file_box
{
font-size
:
14px
;
color
:
#9696a6
;
.del_btn
{
margin-left
:
10px
;
padding-left
:
5px
;
border-left
:
1px
solid
var
(
--
q-primary
);
color
:
var
(
--
q-primary
);
cursor
:
pointer
;
}
}
}
}
.file_Space
{
display
:
flex
;
display
:
flex
;
justify-content
:
space-between
;
justify-content
:
space-between
;
margin-top
:
10px
;
margin-top
:
10px
;
align-items
:
center
;
align-items
:
center
;
}
}
.q-field__control
{
.q-field__control
{
background-color
:
#f6f6f6
!
important
;
background-color
:
#f6f6f6
!
important
;
}
}
.q-field--filled
.q-field__control
:hover:before
{
.q-field--filled
.q-field__control
:hover:before
{
opacity
:
0
;
opacity
:
0
;
}
}
</
style
>
</
style
>
src/pages/customer/customerSetup.vue
View file @
c0b88b7e
<
template
>
<
template
>
<div
class=
"q-pa-md"
>
<div
class=
"q-pa-md"
>
<q-page
padding
style=
"background: #FFF;border-radius: 10px;"
>
<q-page
padding
class=
"page"
:style-fn=
"myTweak(640)"
>
<q-tabs
<q-tabs
v-model=
"tab"
v-model=
"tab"
dense
dense
...
@@ -16,12 +16,12 @@
...
@@ -16,12 +16,12 @@
<q-tab
name=
"clue"
label=
"线索分配规则"
/>
<q-tab
name=
"clue"
label=
"线索分配规则"
/>
<q-tab
name=
"phase"
label=
"客户阶段"
/>
<q-tab
name=
"phase"
label=
"客户阶段"
/>
</q-tabs>
</q-tabs>
<div
class=
"container fit"
>
<customer-Field
v-if=
"tab == 'field'"
></customer-Field>
<customer-Field
v-if=
"tab == 'field'"
></customer-Field>
<clue-rule
v-if=
"tab == 'clue'"
></clue-rule>
<clue-rule
v-if=
"tab == 'clue'"
></clue-rule>
<customer-phase
v-if=
"tab == 'phase'"
></customer-phase>
<customer-phase
v-if=
"tab == 'phase'"
></customer-phase>
<customerlabel
v-if=
"tab == 'label'"
></customerlabel>
<customerlabel
v-if=
"tab == 'label'"
></customerlabel>
</div>
</q-page>
</q-page>
</div>
</div>
</
template
>
</
template
>
...
@@ -48,15 +48,31 @@ export default defineComponent({
...
@@ -48,15 +48,31 @@ export default defineComponent({
},
},
setup
()
{
setup
()
{
let
tab
=
ref
<
string
>
(
'field'
)
let
tab
=
ref
<
string
>
(
'field'
)
if
(
router
.
currentRoute
.
value
.
query
&&
router
.
currentRoute
.
value
.
query
.
type
)
{
if
(
router
.
currentRoute
.
value
.
query
&&
router
.
currentRoute
.
value
.
query
.
type
)
{
tab
.
value
=
router
.
currentRoute
.
value
.
query
.
type
as
string
tab
.
value
=
router
.
currentRoute
.
value
.
query
.
type
as
string
}
}
let
myTweak
=
(
offset
)
=>
{
return
{
minHeight
:
offset
?
`calc(100vh -
${
offset
}
px)`
:
'100vh'
}
}
return
{
return
{
tab
,
tab
,
myTweak
}
}
}
}
})
})
</
script
>
</
script
>
<
style
lang=
"scss"
scoped
>
.page
{
background
:
#FFF
;
box-sizing
:
border-box
;
border-radius
:
10px
;
}
.container
{
box-sizing
:
border-box
;
overflow
:
scroll
;
}
</
style
>
\ No newline at end of file
src/store/modules/user/getters.ts
View file @
c0b88b7e
...
@@ -14,6 +14,9 @@ const userGetter = {
...
@@ -14,6 +14,9 @@ const userGetter = {
const
userInfo
=
store
.
state
.
user
.
userDetail
const
userInfo
=
store
.
state
.
user
.
userDetail
return
userInfo
return
userInfo
},
},
getLoginUserInfo
()
{
return
store
.
state
.
user
.
loginUserInfo
}
}
}
type
UserGetter
=
typeof
userGetter
type
UserGetter
=
typeof
userGetter
...
...
src/store/modules/user/state.ts
View file @
c0b88b7e
...
@@ -18,6 +18,7 @@ const state = {
...
@@ -18,6 +18,7 @@ const state = {
roleId
:
0
,
roleId
:
0
,
userAvatar
:
''
userAvatar
:
''
},
},
loginUserInfo
:{},
currentTeamRoleId
:
0
,
// 当前所选择的团队用户所具有的权限
currentTeamRoleId
:
0
,
// 当前所选择的团队用户所具有的权限
currentProjectRoleId
:
0
,
// 当前所选择的项目用户所具有的权限
currentProjectRoleId
:
0
,
// 当前所选择的项目用户所具有的权限
menuList
:
[]
menuList
:
[]
...
...
src/utils/common.ts
deleted
100644 → 0
View file @
4c99e7ee
import
{
Loading
}
from
'quasar'
interface
itemParams
{
[
propName
:
string
]:
any
}
/**
* 配置相关
*/
export
function
CommonConfig
()
{
return
{
FileConfig
:
{
FileUrl
:
'http://192.168.10.214:8130'
,
//本地服务器文件预览地址
UploadUrl
:
"http://192.168.10.214:8120"
,
//本地上传文件地址
}
}
}
/**
* 上传文件
*/
export
function
UploadSelfFile
(
path
,
file
,
callback
,
configObj
)
{
//用户登录缓存
const
cacheInfo
:
itemParams
=
JSON
.
parse
(
window
.
localStorage
[
"loginUserInfo"
]);
//上传配置
let
uploadConfig
:
itemParams
=
{};
if
(
cacheInfo
&&
cacheInfo
.
data
&&
cacheInfo
.
data
.
UploadConfig
)
{
uploadConfig
=
cacheInfo
.
data
.
UploadConfig
;
}
//获取文件扩展名
// const index:string = file.name.lastIndexOf(".");
// let suffix:string = file.name.substr(index);
// const MyDate:any = new Date()
// var timestamp1 = Date.parse(MyDate) + "_" + (Math.ceil(Math.random() * 1000));
const
str
=
'/Test'
;
const
newPath
=
"/EduSystem"
+
str
+
'/Upload/'
+
path
;
const
uploadLoadding
=
Loading
;
uploadLoadding
.
show
({
message
:
'正在上传文件,请稍后...'
})
if
(
uploadConfig
)
{
switch
(
uploadConfig
.
StoreType
)
{
//上传文件到腾讯云
// case 1:
// newPath += "/" + timestamp1 + "" + suffix;
// UploadFileToTencent(uploadConfig, newPath, file, uploadLoadding, callback);
// break;
// //上传文件到阿里云
// case 2:
// newPath += "/" + timestamp1 + "" + suffix;
// UploadFileToALi(uploadConfig, newPath, file, uploadLoadding, callback);
// break;
//上传文件到自己文件服务器
case
3
:
UploadFileToSystem
(
uploadConfig
,
newPath
,
file
,
uploadLoadding
,
callback
,
configObj
);
break
;
}
}
}
/**
* 上传文件到本地文件系统
*/
export
function
UploadFileToSystem
(
uploadConfig
,
fileFullPath
,
fileObj
,
uploadLoadding
,
successCall
,
configObj
)
{
const
fileConfig
:
itemParams
=
CommonConfig
();
const
locationName
:
string
=
window
.
location
.
hostname
;
if
(
locationName
.
indexOf
(
'localhost'
)
!==
-
1
)
{
uploadConfig
.
UploadDomain
=
fileConfig
.
FileConfig
.
UploadUrl
;
uploadConfig
.
CustomDomain
=
fileConfig
.
FileConfig
.
FileUrl
;
}
let
url
=
uploadConfig
.
UploadDomain
+
"/Upload?filePath="
+
fileFullPath
;
if
(
configObj
)
{
//是否转换图片
if
(
configObj
.
isTrans
&&
configObj
.
isTrans
==
1
)
{
url
+=
"&isTrans=1"
}
if
(
configObj
.
isCreateCover
&&
configObj
.
isCreateCover
==
1
)
{
url
+=
"&isCreateCover=1"
}
}
const
formData
=
new
FormData
()
formData
.
append
(
'myfile'
,
fileObj
)
const
xhr
=
new
XMLHttpRequest
()
xhr
.
onload
=
function
()
{
uploadLoadding
.
hide
();
const
jsonObj
:
itemParams
=
JSON
.
parse
(
xhr
.
responseText
);
if
(
jsonObj
.
StatusCode
===
1
&&
successCall
)
{
const
tempArray
:
any
=
[];
if
(
jsonObj
.
OtherFile
&&
jsonObj
.
OtherFile
.
length
>
0
)
{
jsonObj
.
OtherFile
.
forEach
(
item
=>
{
tempArray
.
push
(
uploadConfig
.
CustomDomain
+
item
);
})
}
const
uploadResult
:
itemParams
=
{
Code
:
1
,
FileName
:
fileObj
.
name
,
FileUrl
:
uploadConfig
.
CustomDomain
+
jsonObj
.
FilePath
,
VideoCoverImg
:
uploadConfig
.
CustomDomain
+
jsonObj
.
VideoCoverImg
,
ExtFile
:
tempArray
}
if
(
successCall
)
{
successCall
(
uploadResult
);
}
}
}
xhr
.
open
(
'post'
,
url
,
true
)
xhr
.
send
(
formData
)
}
// export function UploadFileToTencent(){
// }
// export function UploadFileToALi(){
// }
\ No newline at end of file
src/utils/upload.ts
0 → 100644
View file @
c0b88b7e
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment