Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
提交反馈
为 GitLab 提交贡献
登录
切换导航
I
iBiz企业中心
项目
项目
详情
动态
版本
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
iBiz企业套件
iBiz企业中心
提交
071449f5
提交
071449f5
编写于
6月 29, 2020
作者:
ibizdev
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
lab_gzf 发布系统代码
上级
3552bc38
变更
25
隐藏空白字符变更
内嵌
并排
正在显示
25 个修改的文件
包含
2405 行增加
和
57 行删除
+2405
-57
opportunity_en_US.ts
...c/locale/lanres/entities/opportunity/opportunity_en_US.ts
+24
-24
opportunity_zh_CN.ts
...c/locale/lanres/entities/opportunity/opportunity_zh_CN.ts
+24
-24
opportunity-info-abstract-base.tsx
...ortunity-info-abstract/opportunity-info-abstract-base.tsx
+129
-0
opportunity-info-abstract.html
.../opportunity-info-abstract/opportunity-info-abstract.html
+27
-0
opportunity-info-abstract.vue
...s/opportunity-info-abstract/opportunity-info-abstract.vue
+27
-0
opportunity-summary.vue
...c/pages/sales/opportunity-summary/opportunity-summary.vue
+1
-1
page-register.ts
app_CRM/src/pages/ungroup/central/page-register.ts
+1
-0
router.ts
app_CRM/src/pages/ungroup/central/router.ts
+45
-0
state.ts
app_CRM/src/store/modules/view-action/state.ts
+11
-0
abstract-info-dashboard-base.tsx
.../abstract-info-dashboard/abstract-info-dashboard-base.tsx
+267
-0
abstract-info-dashboard-model.ts
.../abstract-info-dashboard/abstract-info-dashboard-model.ts
+355
-0
abstract-info-dashboard-service.ts
...bstract-info-dashboard/abstract-info-dashboard-service.ts
+11
-0
abstract-info-dashboard.html
...nity/abstract-info-dashboard/abstract-info-dashboard.html
+68
-0
abstract-info-dashboard.vue
...unity/abstract-info-dashboard/abstract-info-dashboard.vue
+26
-0
abstract-info-form-base.tsx
...pportunity/abstract-info-form/abstract-info-form-base.tsx
+214
-0
abstract-info-form-model.ts
...pportunity/abstract-info-form/abstract-info-form-model.ts
+126
-0
abstract-info-form-service.ts
...ortunity/abstract-info-form/abstract-info-form-service.ts
+371
-0
abstract-info-form.html
...ts/opportunity/abstract-info-form/abstract-info-form.html
+93
-0
abstract-info-form.vue
...ets/opportunity/abstract-info-form/abstract-info-form.vue
+22
-0
view-opp-abs-portlet-base.tsx
...tunity/view-opp-abs-portlet/view-opp-abs-portlet-base.tsx
+156
-0
view-opp-abs-portlet-model.ts
...tunity/view-opp-abs-portlet/view-opp-abs-portlet-model.ts
+355
-0
view-opp-abs-portlet-service.ts
...nity/view-opp-abs-portlet/view-opp-abs-portlet-service.ts
+11
-0
view-opp-abs-portlet.html
...pportunity/view-opp-abs-portlet/view-opp-abs-portlet.html
+11
-0
view-opp-abs-portlet.vue
...opportunity/view-opp-abs-portlet/view-opp-abs-portlet.vue
+22
-0
h2_table.xml
...esscentral-core/src/main/resources/liquibase/h2_table.xml
+8
-8
未找到文件。
app_CRM/src/locale/lanres/entities/opportunity/opportunity_en_US.ts
浏览文件 @
071449f5
...
...
@@ -190,11 +190,9 @@ export default {
uiactions
:
{
},
},
produ
ctinfo_form
:
{
abstra
ctinfo_form
:
{
details
:
{
group1
:
"价目表信息"
,
druipart1
:
""
,
grouppanel1
:
"产品明细信息"
,
group1
:
"商机基本信息"
,
formpage1
:
"基本信息"
,
srfupdatedate
:
"更新时间"
,
srforikey
:
""
,
...
...
@@ -204,15 +202,25 @@ export default {
srfuf
:
""
,
srfdeid
:
""
,
srfsourcekey
:
""
,
pricelevelname
:
"价目表"
,
opportunityname
:
"商机名称"
,
parentcontactname
:
"联系人"
,
parentaccountname
:
"帐户"
,
purchasetimeframe
:
"购买时间范围"
,
transactioncurrencyname
:
"货币"
,
budgetamount
:
"预算金额"
,
purchaseprocess
:
"采购程序"
,
description
:
"说明"
,
currentsituation
:
"当前状况"
,
customerneed
:
"客户需求"
,
proposedsolution
:
"已拟定解决方案"
,
opportunityid
:
"商机"
,
},
uiactions
:
{
},
},
main
_form
:
{
productinfo
_form
:
{
details
:
{
group1
:
"
基本
信息"
,
group1
:
"
价目表
信息"
,
druipart1
:
""
,
grouppanel1
:
"产品明细信息"
,
formpage1
:
"基本信息"
,
...
...
@@ -224,30 +232,17 @@ export default {
srfuf
:
""
,
srfdeid
:
""
,
srfsourcekey
:
""
,
opportunityname
:
"商机名称"
,
parentcontactname
:
"联系人"
,
parentaccountname
:
"帐户"
,
purchasetimeframe
:
"购买时间范围"
,
transactioncurrencyname
:
"货币"
,
budgetamount
:
"预算金额"
,
purchaseprocess
:
"采购程序"
,
description
:
"说明"
,
currentsituation
:
"当前状况"
,
customerneed
:
"客户需求"
,
proposedsolution
:
"已拟定解决方案"
,
pricelevelname
:
"价目表"
,
parentcontactid
:
"联系人"
,
parentaccountid
:
"帐户"
,
transactioncurrencyid
:
"货币"
,
opportunityid
:
"商机"
,
pricelevelid
:
"价目表"
,
},
uiactions
:
{
},
},
abstractinfo
_form
:
{
main
_form
:
{
details
:
{
group1
:
"商机基本信息"
,
group1
:
"基本信息"
,
druipart1
:
""
,
grouppanel1
:
"产品明细信息"
,
formpage1
:
"基本信息"
,
srfupdatedate
:
"更新时间"
,
srforikey
:
""
,
...
...
@@ -268,7 +263,12 @@ export default {
currentsituation
:
"当前状况"
,
customerneed
:
"客户需求"
,
proposedsolution
:
"已拟定解决方案"
,
pricelevelname
:
"价目表"
,
parentcontactid
:
"联系人"
,
parentaccountid
:
"帐户"
,
transactioncurrencyid
:
"货币"
,
opportunityid
:
"商机"
,
pricelevelid
:
"价目表"
,
},
uiactions
:
{
},
...
...
app_CRM/src/locale/lanres/entities/opportunity/opportunity_zh_CN.ts
浏览文件 @
071449f5
...
...
@@ -189,11 +189,9 @@ export default {
uiactions
:
{
},
},
produ
ctinfo_form
:
{
abstra
ctinfo_form
:
{
details
:
{
group1
:
"价目表信息"
,
druipart1
:
""
,
grouppanel1
:
"产品明细信息"
,
group1
:
"商机基本信息"
,
formpage1
:
"基本信息"
,
srfupdatedate
:
"更新时间"
,
srforikey
:
""
,
...
...
@@ -203,15 +201,25 @@ export default {
srfuf
:
""
,
srfdeid
:
""
,
srfsourcekey
:
""
,
pricelevelname
:
"价目表"
,
opportunityname
:
"商机名称"
,
parentcontactname
:
"联系人"
,
parentaccountname
:
"帐户"
,
purchasetimeframe
:
"购买时间范围"
,
transactioncurrencyname
:
"货币"
,
budgetamount
:
"预算金额"
,
purchaseprocess
:
"采购程序"
,
description
:
"说明"
,
currentsituation
:
"当前状况"
,
customerneed
:
"客户需求"
,
proposedsolution
:
"已拟定解决方案"
,
opportunityid
:
"商机"
,
},
uiactions
:
{
},
},
main
_form
:
{
productinfo
_form
:
{
details
:
{
group1
:
"
基本
信息"
,
group1
:
"
价目表
信息"
,
druipart1
:
""
,
grouppanel1
:
"产品明细信息"
,
formpage1
:
"基本信息"
,
...
...
@@ -223,30 +231,17 @@ export default {
srfuf
:
""
,
srfdeid
:
""
,
srfsourcekey
:
""
,
opportunityname
:
"商机名称"
,
parentcontactname
:
"联系人"
,
parentaccountname
:
"帐户"
,
purchasetimeframe
:
"购买时间范围"
,
transactioncurrencyname
:
"货币"
,
budgetamount
:
"预算金额"
,
purchaseprocess
:
"采购程序"
,
description
:
"说明"
,
currentsituation
:
"当前状况"
,
customerneed
:
"客户需求"
,
proposedsolution
:
"已拟定解决方案"
,
pricelevelname
:
"价目表"
,
parentcontactid
:
"联系人"
,
parentaccountid
:
"帐户"
,
transactioncurrencyid
:
"货币"
,
opportunityid
:
"商机"
,
pricelevelid
:
"价目表"
,
},
uiactions
:
{
},
},
abstractinfo
_form
:
{
main
_form
:
{
details
:
{
group1
:
"商机基本信息"
,
group1
:
"基本信息"
,
druipart1
:
""
,
grouppanel1
:
"产品明细信息"
,
formpage1
:
"基本信息"
,
srfupdatedate
:
"更新时间"
,
srforikey
:
""
,
...
...
@@ -267,7 +262,12 @@ export default {
currentsituation
:
"当前状况"
,
customerneed
:
"客户需求"
,
proposedsolution
:
"已拟定解决方案"
,
pricelevelname
:
"价目表"
,
parentcontactid
:
"联系人"
,
parentaccountid
:
"帐户"
,
transactioncurrencyid
:
"货币"
,
opportunityid
:
"商机"
,
pricelevelid
:
"价目表"
,
},
uiactions
:
{
},
...
...
app_CRM/src/pages/sales/opportunity-info-abstract/opportunity-info-abstract-base.tsx
0 → 100644
浏览文件 @
071449f5
import
{
Subject
}
from
'rxjs'
;
import
{
EditViewBase
}
from
'@/studio-core'
;
import
OpportunityService
from
'@/service/opportunity/opportunity-service'
;
import
EditViewEngine
from
'@engine/view/edit-view-engine'
;
/**
* 商机编辑视图视图基类
*
* @export
* @class OpportunityInfo_AbstractBase
* @extends {EditViewBase}
*/
export
class
OpportunityInfo_AbstractBase
extends
EditViewBase
{
/**
* 实体服务对象
*
* @type {OpportunityService}
* @memberof OpportunityInfo_AbstractBase
*/
protected
appEntityService
:
OpportunityService
=
new
OpportunityService
;
/**
* 计数器服务对象集合
*
* @protected
* @type {Array<*>}
* @memberof OpportunityInfo_AbstractBase
*/
protected
counterServiceArray
:
Array
<
any
>
=
[];
/**
* 视图模型数据
*
* @protected
* @type {*}
* @memberof OpportunityInfo_AbstractBase
*/
protected
model
:
any
=
{
srfCaption
:
'entities.opportunity.views.info_abstract.caption'
,
srfTitle
:
'entities.opportunity.views.info_abstract.title'
,
srfSubTitle
:
'entities.opportunity.views.info_abstract.subtitle'
,
dataInfo
:
''
}
/**
* 容器模型
*
* @protected
* @type {*}
* @memberof OpportunityInfo_AbstractBase
*/
protected
containerModel
:
any
=
{
view_form
:
{
name
:
'form'
,
type
:
'FORM'
},
};
/**
* 视图唯一标识
*
* @protected
* @type {string}
* @memberof ViewBase
*/
protected
viewtag
:
string
=
'66b3d6f7e15711b61132066ba3a95f91'
;
/**
* 视图引擎
*
* @public
* @type {Engine}
* @memberof OpportunityInfo_AbstractBase
*/
public
engine
:
EditViewEngine
=
new
EditViewEngine
();
/**
* 引擎初始化
*
* @public
* @memberof OpportunityInfo_AbstractBase
*/
public
engineInit
():
void
{
this
.
engine
.
init
({
view
:
this
,
form
:
this
.
$refs
.
form
,
p2k
:
'0'
,
keyPSDEField
:
'opportunity'
,
majorPSDEField
:
'opportunityname'
,
isLoadDefault
:
true
,
});
}
/**
* form 部件 save 事件
*
* @param {*} [args={}]
* @param {*} $event
* @memberof OpportunityInfo_AbstractBase
*/
public
form_save
(
$event
:
any
,
$event2
?:
any
):
void
{
this
.
engine
.
onCtrlEvent
(
'form'
,
'save'
,
$event
);
}
/**
* form 部件 remove 事件
*
* @param {*} [args={}]
* @param {*} $event
* @memberof OpportunityInfo_AbstractBase
*/
public
form_remove
(
$event
:
any
,
$event2
?:
any
):
void
{
this
.
engine
.
onCtrlEvent
(
'form'
,
'remove'
,
$event
);
}
/**
* form 部件 load 事件
*
* @param {*} [args={}]
* @param {*} $event
* @memberof OpportunityInfo_AbstractBase
*/
public
form_load
(
$event
:
any
,
$event2
?:
any
):
void
{
this
.
engine
.
onCtrlEvent
(
'form'
,
'load'
,
$event
);
}
}
\ No newline at end of file
app_CRM/src/pages/sales/opportunity-info-abstract/opportunity-info-abstract.html
0 → 100644
浏览文件 @
071449f5
<studio-view-style2
viewName=
"opportunityinfo_abstract"
viewTitle=
"商机编辑视图"
class=
'deeditview opportunity-info-abstract'
>
<template
slot=
'title'
>
<span
class=
'caption-info'
>
{{$t(model.srfTitle)}}
</span>
</template>
<view
_form
:viewState=
"viewState"
:viewparams=
"viewparams"
:context=
"context"
:autosave=
"false"
:viewtag=
"viewtag"
:showBusyIndicator=
"true"
updateAction=
"Update"
removeAction=
"Remove"
loaddraftAction=
"GetDraft"
loadAction=
"Get"
createAction=
"Create"
WFSubmitAction=
""
WFStartAction=
""
style=
''
name=
"form"
ref=
'form'
@
save=
"form_save($event)"
@
remove=
"form_remove($event)"
@
load=
"form_load($event)"
@
closeview=
"closeView($event)"
>
</view
_form
>
</studio-view-style2>
\ No newline at end of file
app_CRM/src/pages/sales/opportunity-info-abstract/opportunity-info-abstract.vue
0 → 100644
浏览文件 @
071449f5
<
template
src=
"./opportunity-info-abstract.html"
/>
<script
lang=
'tsx'
>
import
{ Component } from 'vue-property-decorator';
import { VueLifeCycleProcessing } from '@/studio-core';
import { OpportunityInfo_AbstractBase } from './opportunity-info-abstract-base';
import view_form from '@widgets/opportunity/abstract-info-form/abstract-info-form.vue';
/**
* 商机编辑视图视图
*
* @export
* @class OpportunityInfo_Abstract
* @extends {OpportunityInfo_AbstractBase}
*/
@Component({
components: {
view_form,
},
beforeRouteEnter: (to: any, from: any, next: any) => {
next((vm: any) => {
vm.$store.commit('addCurPageViewtag', { route: to, viewtag: vm.viewtag });
});
}
})
@VueLifeCycleProcessing()
export default class OpportunityInfo_Abstract extends OpportunityInfo_AbstractBase { }
</script>
app_CRM/src/pages/sales/opportunity-summary/opportunity-summary.vue
浏览文件 @
071449f5
...
...
@@ -3,7 +3,7 @@
import
{ Component } from 'vue-property-decorator';
import { VueLifeCycleProcessing } from '@/studio-core';
import { OpportunitySummaryBase } from './opportunity-summary-base';
import view_dashboard from '@widgets/opportunity/
dashboard-dashboard/dashboard
-dashboard.vue';
import view_dashboard from '@widgets/opportunity/
abstract-info-dashboard/abstract-info
-dashboard.vue';
/**
* 商机概览视图
...
...
app_CRM/src/pages/ungroup/central/page-register.ts
浏览文件 @
071449f5
...
...
@@ -38,6 +38,7 @@ export const PageComponents = {
Vue
.
component
(
'product-edit-quick-create'
,
()
=>
import
(
'@pages/product/product-edit-quick-create/product-edit-quick-create.vue'
));
Vue
.
component
(
'campaign-info-manager'
,
()
=>
import
(
'@pages/marketing/campaign-info-manager/campaign-info-manager.vue'
));
Vue
.
component
(
'contact-info-abstract'
,
()
=>
import
(
'@pages/base/contact-info-abstract/contact-info-abstract.vue'
));
Vue
.
component
(
'opportunity-info-abstract'
,
()
=>
import
(
'@pages/sales/opportunity-info-abstract/opportunity-info-abstract.vue'
));
Vue
.
component
(
'list-contact-edit-view'
,
()
=>
import
(
'@pages/marketing/list-contact-edit-view/list-contact-edit-view.vue'
));
Vue
.
component
(
'campaign-grid-view'
,
()
=>
import
(
'@pages/marketing/campaign-grid-view/campaign-grid-view.vue'
));
Vue
.
component
(
'list-lead-by-list'
,
()
=>
import
(
'@pages/marketing/list-lead-by-list/list-lead-by-list.vue'
));
...
...
app_CRM/src/pages/ungroup/central/router.ts
浏览文件 @
071449f5
...
...
@@ -1079,6 +1079,51 @@ const router = new Router({
},
component
:
()
=>
import
(
'@pages/base/contact-info-abstract/contact-info-abstract.vue'
),
},
{
path
:
'accounts/:account?/contacts/:contact?/opportunities/:opportunity?/info_abstract/:info_abstract?'
,
meta
:
{
caption
:
'entities.opportunity.views.info_abstract.title'
,
info
:
''
,
parameters
:
[
{
pathName
:
'central'
,
parameterName
:
'central'
},
{
pathName
:
'accounts'
,
parameterName
:
'account'
},
{
pathName
:
'contacts'
,
parameterName
:
'contact'
},
{
pathName
:
'opportunities'
,
parameterName
:
'opportunity'
},
{
pathName
:
'info_abstract'
,
parameterName
:
'info_abstract'
},
],
requireAuth
:
true
,
},
component
:
()
=>
import
(
'@pages/sales/opportunity-info-abstract/opportunity-info-abstract.vue'
),
},
{
path
:
'contacts/:contact?/opportunities/:opportunity?/info_abstract/:info_abstract?'
,
meta
:
{
caption
:
'entities.opportunity.views.info_abstract.title'
,
info
:
''
,
parameters
:
[
{
pathName
:
'central'
,
parameterName
:
'central'
},
{
pathName
:
'contacts'
,
parameterName
:
'contact'
},
{
pathName
:
'opportunities'
,
parameterName
:
'opportunity'
},
{
pathName
:
'info_abstract'
,
parameterName
:
'info_abstract'
},
],
requireAuth
:
true
,
},
component
:
()
=>
import
(
'@pages/sales/opportunity-info-abstract/opportunity-info-abstract.vue'
),
},
{
path
:
'opportunities/:opportunity?/info_abstract/:info_abstract?'
,
meta
:
{
caption
:
'entities.opportunity.views.info_abstract.title'
,
info
:
''
,
parameters
:
[
{
pathName
:
'central'
,
parameterName
:
'central'
},
{
pathName
:
'opportunities'
,
parameterName
:
'opportunity'
},
{
pathName
:
'info_abstract'
,
parameterName
:
'info_abstract'
},
],
requireAuth
:
true
,
},
component
:
()
=>
import
(
'@pages/sales/opportunity-info-abstract/opportunity-info-abstract.vue'
),
},
{
path
:
'accounts/:account?/contacts/:contact?/listcontacts/:listcontact?/editview/:editview?'
,
meta
:
{
...
...
app_CRM/src/store/modules/view-action/state.ts
浏览文件 @
071449f5
...
...
@@ -183,6 +183,8 @@ export const viewstate: any = {
viewaction
:
''
,
viewdatachange
:
false
,
refviews
:
[
'66b3d6f7e15711b61132066ba3a95f91'
,
'c74c14188b89f72079643170a83c25f5'
,
],
},
{
...
...
@@ -622,6 +624,15 @@ export const viewstate: any = {
'9107350fc58a1dba2785d2f5da8afec8'
,
],
},
{
viewtag
:
'66b3d6f7e15711b61132066ba3a95f91'
,
viewmodule
:
'Sales'
,
viewname
:
'OpportunityInfo_Abstract'
,
viewaction
:
''
,
viewdatachange
:
false
,
refviews
:
[
],
},
{
viewtag
:
'688201ee5642d41628dbf4deba002d17'
,
viewmodule
:
'Base'
,
...
...
app_CRM/src/widgets/opportunity/abstract-info-dashboard/abstract-info-dashboard-base.tsx
0 → 100644
浏览文件 @
071449f5
import
{
Prop
,
Provide
,
Emit
,
Model
}
from
'vue-property-decorator'
;
import
{
Subject
,
Subscription
}
from
'rxjs'
;
import
{
Watch
,
MainControlBase
}
from
'@/studio-core'
;
import
OpportunityService
from
'@/service/opportunity/opportunity-service'
;
import
AbstractInfoService
from
'./abstract-info-dashboard-service'
;
import
UtilService
from
'@/utilservice/util-service'
;
/**
* dashboard部件基类
*
* @export
* @class MainControlBase
* @extends {AbstractInfoDashboardBase}
*/
export
class
AbstractInfoDashboardBase
extends
MainControlBase
{
/**
* 建构部件服务对象
*
* @type {AbstractInfoService}
* @memberof AbstractInfoDashboardBase
*/
public
service
:
AbstractInfoService
=
new
AbstractInfoService
({
$store
:
this
.
$store
});
/**
* 实体服务对象
*
* @type {OpportunityService}
* @memberof AbstractInfoDashboardBase
*/
public
appEntityService
:
OpportunityService
=
new
OpportunityService
({
$store
:
this
.
$store
});
/**
* 应用实体名称
*
* @protected
* @type {string}
* @memberof AbstractInfoDashboardBase
*/
protected
appDeName
:
string
=
'opportunity'
;
/**
* 是否支持看板定制
*
* @public
* @type {(boolean)}
* @memberof AbstractInfo
*/
@
Prop
()
public
isEnableCustomized
!
:
boolean
;
/**
* 是否已有看板定制
*
* @public
* @type {(boolean)}
* @memberof AbstractInfo
*/
public
isHasCustomized
:
boolean
=
false
;
/**
* 模型数据
*
* @public
* @type {(*)}
* @memberof AbstractInfo
*/
public
modelDta
:
any
;
/**
* modleId
*
* @type {string}
* @memberof AbstractInfo
*/
public
modelId
:
string
=
"dashboard_opportunity_abstractinfo"
;
/**
* 建构功能服务对象
*
* @type {UtilService}
* @memberof AbstractInfo
*/
public
utilService
:
UtilService
=
new
UtilService
();
/**
* 功能服务名称
*
* @type {string}
* @memberof AbstractInfo
*/
public
utilServiceName
:
string
=
""
;
/**
* 获取多项数据
*
* @returns {any[]}
* @memberof AbstractInfo
*/
public
getDatas
():
any
[]
{
return
[];
}
/**
* 获取单项树
*
* @returns {*}
* @memberof AbstractInfo
*/
public
getData
():
any
{
return
{};
}
/**
* vue 生命周期
*
* @memberof AbstractInfo
*/
public
created
()
{
this
.
afterCreated
();
}
/**
* 执行created后的逻辑
*
* @memberof AbstractInfo
*/
public
afterCreated
(){
if
(
this
.
viewState
)
{
this
.
viewStateEvent
=
this
.
viewState
.
subscribe
(({
tag
,
action
,
data
})
=>
{
if
(
!
Object
.
is
(
tag
,
this
.
name
))
{
return
;
}
if
(
Object
.
is
(
'load'
,
action
))
{
this
.
loadModel
();
}
});
}
}
/**
* 动态设计水平列数
*
* @memberof AbstractInfo
*/
public
layoutColNum
:
number
=
12
;
/**
* 动态设计单元格高度,80px
*
* @memberof AbstractInfo
*/
public
layoutRowH
:
number
=
80
;
/**
* 通知状态
*
* @memberof AbstractInfo
*/
public
notifyState
(){
this
.
$nextTick
(()
=>
{
if
(
this
.
isHasCustomized
)
{
if
(
this
.
modelDta
&&
this
.
modelDta
.
length
>
0
)
{
this
.
modelDta
.
forEach
((
item
:
any
)
=>
{
this
.
viewState
.
next
({
tag
:
item
.
portletCodeName
,
action
:
"load"
,
data
:
JSON
.
parse
(
JSON
.
stringify
(
this
.
viewparams
))
});
});
}
}
else
{
if
(
this
.
viewState
)
{
const
refs
:
any
=
this
.
$refs
;
Object
.
keys
(
refs
).
forEach
((
name
:
string
)
=>
{
this
.
viewState
.
next
({
tag
:
name
,
action
:
"load"
,
data
:
JSON
.
parse
(
JSON
.
stringify
(
this
.
viewparams
))
});
});
}
}
})
}
/**
* 加载布局与数据模型
*
* @memberof AbstractInfo
*/
public
loadModel
(){
if
(
this
.
isEnableCustomized
){
this
.
utilService
.
getService
(
this
.
utilServiceName
).
then
((
service
:
any
)
=>
{
service
.
loadModelData
(
JSON
.
parse
(
JSON
.
stringify
(
this
.
context
)),{
modelid
:
this
.
modelId
,
utilServiceName
:
this
.
utilServiceName
}).
then
((
res
:
any
)
=>
{
if
(
res
&&
res
.
status
==
200
){
const
data
:
any
=
res
.
data
;
if
(
data
&&
data
.
length
>
0
){
this
.
isHasCustomized
=
true
;
this
.
modelDta
=
data
;
this
.
$forceUpdate
();
}
else
{
this
.
isHasCustomized
=
false
;
}
this
.
notifyState
();
}
else
{
console
.
error
(
"加载面板模型异常"
);
this
.
isHasCustomized
=
false
;
this
.
notifyState
();
}
}).
catch
((
error
:
any
)
=>
{
console
.
error
(
"加载面板模型异常"
);
console
.
error
(
error
);
this
.
isHasCustomized
=
false
;
this
.
notifyState
();
});
})
}
else
{
this
.
notifyState
();
}
}
/**
* 处理私人定制按钮
*
* @memberof AbstractInfo
*/
public
handleClick
(){
const
view
:
any
=
{
viewname
:
'app-portal-design'
,
title
:
'面板设计'
,
width
:
1600
,
placement
:
'DRAWER_RIGHT'
}
const
viewparam
:
any
=
{
modelid
:
this
.
modelId
,
utilServiceName
:
this
.
utilServiceName
,
appdeName
:
'Opportunity'
}
const
appdrawer
=
this
.
$appdrawer
.
openDrawer
(
view
,
JSON
.
parse
(
JSON
.
stringify
(
this
.
context
)),
viewparam
);
appdrawer
.
subscribe
((
result
:
any
)
=>
{
if
(
Object
.
is
(
result
.
ret
,
'OK'
)){
this
.
loadModel
();
}
});
}
/**
* vue 生命周期
*
* @memberof AbstractInfo
*/
public
destroyed
()
{
this
.
afterDestroy
();
}
/**
* 执行destroyed后的逻辑
*
* @memberof AbstractInfo
*/
public
afterDestroy
()
{
if
(
this
.
viewStateEvent
)
{
this
.
viewStateEvent
.
unsubscribe
();
}
}
}
\ No newline at end of file
app_CRM/src/widgets/opportunity/abstract-info-dashboard/abstract-info-dashboard-model.ts
0 → 100644
浏览文件 @
071449f5
/**
* AbstractInfo 部件模型
*
* @export
* @class AbstractInfoModel
*/
export
default
class
AbstractInfoModel
{
/**
* 获取数据项集合
*
* @returns {any[]}
* @memberof AbstractInfoModel
*/
public
getDataItems
():
any
[]
{
return
[
{
name
:
'decisionmaker'
,
},
{
name
:
'totallineitemamount'
,
},
{
name
:
'processid'
,
},
{
name
:
'discountpercentage'
,
},
{
name
:
'pricingerrorcode'
,
},
{
name
:
'totalamount'
,
},
{
name
:
'totaltax_base'
,
},
{
name
:
'totaltax'
,
},
{
name
:
'updateman'
,
},
{
name
:
'estimatedvalue_base'
,
},
{
name
:
'presentfinalproposal'
,
},
{
name
:
'developproposal'
,
},
{
name
:
'opportunityratingcode'
,
},
{
name
:
'totalamount_base'
,
},
{
name
:
'totalamountlessfreight'
,
},
{
name
:
'description'
,
},
{
name
:
'identifycompetitors'
,
},
{
name
:
'updatedate'
,
},
{
name
:
'sendthankyounote'
,
},
{
name
:
'totaldiscountamount_base'
,
},
{
name
:
'totallineitemdiscountamount'
,
},
{
name
:
'purchaseprocess'
,
},
{
name
:
'traversedpath'
,
},
{
name
:
'captureproposalfeedback'
,
},
{
name
:
'finaldecisiondate'
,
},
{
name
:
'stepid'
,
},
{
name
:
'resolvefeedback'
,
},
{
name
:
'budgetamount_base'
,
},
{
name
:
'owneridyominame'
,
},
{
name
:
'pursuitdecision'
,
},
{
name
:
'revenuesystemcalculated'
,
},
{
name
:
'scheduleproposalmeeting'
,
},
{
name
:
'closeprobability'
,
},
{
name
:
'utcconversiontimezonecode'
,
},
{
name
:
'presentproposal'
,
},
{
name
:
'schedulefollowup_prospect'
,
},
{
name
:
'statuscode'
,
},
{
name
:
'actualclosedate'
,
},
{
name
:
'confirminterest'
,
},
{
name
:
'customerid'
,
},
{
name
:
'salesstage'
,
},
{
name
:
'opportunity'
,
prop
:
'opportunityid'
,
},
{
name
:
'onholdtime'
,
},
{
name
:
'qualificationcomments'
,
},
{
name
:
'accountidyominame'
,
},
{
name
:
'schedulefollowup_qualify'
,
},
{
name
:
'participatesinworkflow'
,
},
{
name
:
'exchangerate'
,
},
{
name
:
'stepname'
,
},
{
name
:
'customerneed'
,
},
{
name
:
'importsequencenumber'
,
},
{
name
:
'completeinternalreview'
,
},
{
name
:
'evaluatefit'
,
},
{
name
:
'salesstagecode'
,
},
{
name
:
'identifypursuitteam'
,
},
{
name
:
'contactidyominame'
,
},
{
name
:
'initialcommunication'
,
},
{
name
:
'versionnumber'
,
},
{
name
:
'freightamount_base'
,
},
{
name
:
'teamsfollowed'
,
},
{
name
:
'proposedsolution'
,
},
{
name
:
'filedebrief'
,
},
{
name
:
'budgetamount'
,
},
{
name
:
'budgetstatus'
,
},
{
name
:
'discountamount_base'
,
},
{
name
:
'completefinalproposal'
,
},
{
name
:
'discountamount'
,
},
{
name
:
'customeridyominame'
,
},
{
name
:
'need'
,
},
{
name
:
'stageid'
,
},
{
name
:
'freightamount'
,
},
{
name
:
'actualvalue'
,
},
{
name
:
'ibizprivate'
,
},
{
name
:
'timezoneruleversionnumber'
,
},
{
name
:
'createdate'
,
},
{
name
:
'prioritycode'
,
},
{
name
:
'totallineitemamount_base'
,
},
{
name
:
'estimatedclosedate'
,
},
{
name
:
'currentsituation'
,
},
{
name
:
'actualvalue_base'
,
},
{
name
:
'customerpainpoints'
,
},
{
name
:
'totaldiscountamount'
,
},
{
name
:
'opportunityname'
,
},
{
name
:
'owneridtype'
,
},
{
name
:
'identifycustomercontacts'
,
},
{
name
:
'timeline'
,
},
{
name
:
'lastonholdtime'
,
},
{
name
:
'totalamountlessfreight_base'
,
},
{
name
:
'estimatedvalue'
,
},
{
name
:
'emailaddress'
,
},
{
name
:
'statecode'
,
},
{
name
:
'purchasetimeframe'
,
},
{
name
:
'createman'
,
},
{
name
:
'quotecomments'
,
},
{
name
:
'customeridtype'
,
},
{
name
:
'overriddencreatedon'
,
},
{
name
:
'ownerid'
,
},
{
name
:
'slaname'
,
},
{
name
:
'parentcontactid'
,
},
{
name
:
'campaignid'
,
},
{
name
:
'transactioncurrencyid'
,
},
{
name
:
'parentaccountid'
,
},
{
name
:
'pricelevelid'
,
},
{
name
:
'originatingleadid'
,
},
{
name
:
'slaid'
,
},
{
name
:
'originatingleadname'
,
},
{
name
:
'parentaccountname'
,
},
{
name
:
'campaignname'
,
},
{
name
:
'parentcontactname'
,
},
{
name
:
'transactioncurrencyname'
,
},
{
name
:
'pricelevelname'
,
},
]
}
}
\ No newline at end of file
app_CRM/src/widgets/opportunity/abstract-info-dashboard/abstract-info-dashboard-service.ts
0 → 100644
浏览文件 @
071449f5
import
{
Http
}
from
'@/utils'
;
import
ControlService
from
'@/widgets/control-service'
;
/**
* AbstractInfo 部件服务对象
*
* @export
* @class AbstractInfoService
*/
export
default
class
AbstractInfoService
extends
ControlService
{
}
\ No newline at end of file
app_CRM/src/widgets/opportunity/abstract-info-dashboard/abstract-info-dashboard.html
0 → 100644
浏览文件 @
071449f5
<div
class=
'dashboard'
>
<row
v-if=
"isEnableCustomized"
>
<app-build
@
handleClick=
"handleClick.apply(_self, arguments)"
></app-build>
</row>
<row
v-if=
"!isHasCustomized"
>
<i-col
:md=
"{ span: 24, offset: 0 }"
:lg=
"{ span: 18, offset: 0 }"
>
<card
class=
"portlet-card"
:bordered=
"false"
dis-hover
:padding=
"0"
>
<span>
<div
class=
'portlet-container summarydashboard-container1 '
:style=
"{}"
>
<row>
<i-col
:md=
"{ span: 24, offset: 0 }"
>
<div
class=
"portlet-without-title"
>
<card
class=
"portlet-card"
:bordered=
"false"
dis-hover
:padding=
"0"
>
<span>
<view
_dashboard_sysportlet1
:viewState=
"viewState"
:viewparams=
"viewparams"
:context=
"context"
name=
"dashboard_sysportlet1"
ref=
'dashboard_sysportlet1'
@
closeview=
"closeView($event)"
>
</view
_dashboard_sysportlet1
>
</span>
</card>
</div>
</i-col>
</row>
</div>
</span>
</card>
</i-col>
<i-col
:md=
"{ span: 24, offset: 0 }"
:lg=
"{ span: 6, offset: 0 }"
>
<card
class=
"portlet-card"
:bordered=
"false"
dis-hover
:padding=
"0"
>
<span>
<div
class=
'portlet-container summarydashboard-container2 '
:style=
"{}"
>
<row>
<i-col
:md=
"{ span: 24, offset: 0 }"
>
<div
class=
"portlet-without-title"
>
<card
class=
"portlet-card"
:bordered=
"false"
dis-hover
:padding=
"0"
>
<span>
<view
_dashboard_sysportlet2
:viewState=
"viewState"
:viewparams=
"viewparams"
:context=
"context"
name=
"dashboard_sysportlet2"
ref=
'dashboard_sysportlet2'
@
closeview=
"closeView($event)"
>
</view
_dashboard_sysportlet2
>
</span>
</card>
</div>
</i-col>
</row>
</div>
</span>
</card>
</i-col>
</row>
<row
v-if=
"isHasCustomized"
style=
"width: 100%;min-height: calc(100% - 40px);"
>
<div
class=
"portlet-container"
style=
"position: relative;width:100%;"
>
<template
v-for=
"(item, index) of modelDta"
>
<div
:key=
"index"
:style=
"{zIndex: 10, position: 'absolute', height: item.h*layoutRowH + 'px', width: `calc(100% / ${layoutColNum} * ${item.w})`,top: item.y*layoutRowH + 'px', left: `calc(100% / ${layoutColNum} * ${item.x})`}"
>
<component
:key=
"$util.createUUID()"
:is=
"item.componentName"
:name=
"item.portletCodeName"
:context=
"JSON.parse(JSON.stringify(context))"
:viewDefaultUsage=
"false"
:isAdaptiveSize=
"true"
:viewState=
"viewState"
></component>
</div>
</template>
</div>
</row>
</div>
\ No newline at end of file
app_CRM/src/widgets/opportunity/abstract-info-dashboard/abstract-info-dashboard.vue
0 → 100644
浏览文件 @
071449f5
<
template
src=
"./abstract-info-dashboard.html"
/>
<script
lang=
'tsx'
>
import
{ Component } from 'vue-property-decorator';
import { VueLifeCycleProcessing } from '@/studio-core';
import { AbstractInfoDashboardBase } from './abstract-info-dashboard-base';
import view_dashboard_sysportlet2 from '@widgets/opportunity/view-opp-pro-portlet/view-opp-pro-portlet.vue';
import view_dashboard_sysportlet1 from '@widgets/opportunity/view-opp-abs-portlet/view-opp-abs-portlet.vue';
/**
* dashboard部件
*
* @export
* @class AbstractInfoDashboard
* @extends {AbstractInfoDashboardBase}
*/
@Component({
components: {
view_dashboard_sysportlet2,
view_dashboard_sysportlet1,
}
})
@VueLifeCycleProcessing()
export default class AbstractInfoDashboard extends AbstractInfoDashboardBase { }
</script>
app_CRM/src/widgets/opportunity/abstract-info-form/abstract-info-form-base.tsx
0 → 100644
浏览文件 @
071449f5
import
{
Prop
,
Provide
,
Emit
,
Model
}
from
'vue-property-decorator'
;
import
{
Subject
,
Subscription
}
from
'rxjs'
;
import
{
Watch
,
EditFormControlBase
}
from
'@/studio-core'
;
import
OpportunityService
from
'@/service/opportunity/opportunity-service'
;
import
AbstractInfoService
from
'./abstract-info-form-service'
;
import
{
FormButtonModel
,
FormPageModel
,
FormItemModel
,
FormDRUIPartModel
,
FormPartModel
,
FormGroupPanelModel
,
FormIFrameModel
,
FormRowItemModel
,
FormTabPageModel
,
FormTabPanelModel
,
FormUserControlModel
}
from
'@/model/form-detail'
;
/**
* form部件基类
*
* @export
* @class EditFormControlBase
* @extends {AbstractInfoEditFormBase}
*/
export
class
AbstractInfoEditFormBase
extends
EditFormControlBase
{
/**
* 建构部件服务对象
*
* @type {AbstractInfoService}
* @memberof AbstractInfoEditFormBase
*/
public
service
:
AbstractInfoService
=
new
AbstractInfoService
({
$store
:
this
.
$store
});
/**
* 实体服务对象
*
* @type {OpportunityService}
* @memberof AbstractInfoEditFormBase
*/
public
appEntityService
:
OpportunityService
=
new
OpportunityService
({
$store
:
this
.
$store
});
/**
* 应用实体名称
*
* @protected
* @type {string}
* @memberof AbstractInfoEditFormBase
*/
protected
appDeName
:
string
=
'opportunity'
;
/**
* 表单数据对象
*
* @type {*}
* @memberof AbstractInfoEditFormBase
*/
public
data
:
any
=
{
srfupdatedate
:
null
,
srforikey
:
null
,
srfkey
:
null
,
srfmajortext
:
null
,
srftempmode
:
null
,
srfuf
:
null
,
srfdeid
:
null
,
srfsourcekey
:
null
,
opportunityname
:
null
,
parentcontactname
:
null
,
parentaccountname
:
null
,
purchasetimeframe
:
null
,
transactioncurrencyname
:
null
,
budgetamount
:
null
,
purchaseprocess
:
null
,
description
:
null
,
currentsituation
:
null
,
customerneed
:
null
,
proposedsolution
:
null
,
opportunityid
:
null
,
opportunity
:
null
,
};
/**
* 属性值规则
*
* @type {*}
* @memberof AbstractInfoEditFormBase
*/
public
rules
:
any
=
{
srfupdatedate
:
[
{
required
:
false
,
type
:
'string'
,
message
:
'更新时间 值不能为空'
,
trigger
:
'change'
},
{
required
:
false
,
type
:
'string'
,
message
:
'更新时间 值不能为空'
,
trigger
:
'blur'
},
],
srforikey
:
[
{
required
:
false
,
type
:
'string'
,
message
:
' 值不能为空'
,
trigger
:
'change'
},
{
required
:
false
,
type
:
'string'
,
message
:
' 值不能为空'
,
trigger
:
'blur'
},
],
srfkey
:
[
{
required
:
false
,
type
:
'string'
,
message
:
'商机 值不能为空'
,
trigger
:
'change'
},
{
required
:
false
,
type
:
'string'
,
message
:
'商机 值不能为空'
,
trigger
:
'blur'
},
],
srfmajortext
:
[
{
required
:
false
,
type
:
'string'
,
message
:
'商机名称 值不能为空'
,
trigger
:
'change'
},
{
required
:
false
,
type
:
'string'
,
message
:
'商机名称 值不能为空'
,
trigger
:
'blur'
},
],
srftempmode
:
[
{
required
:
false
,
type
:
'string'
,
message
:
' 值不能为空'
,
trigger
:
'change'
},
{
required
:
false
,
type
:
'string'
,
message
:
' 值不能为空'
,
trigger
:
'blur'
},
],
srfuf
:
[
{
required
:
false
,
type
:
'string'
,
message
:
' 值不能为空'
,
trigger
:
'change'
},
{
required
:
false
,
type
:
'string'
,
message
:
' 值不能为空'
,
trigger
:
'blur'
},
],
srfdeid
:
[
{
required
:
false
,
type
:
'string'
,
message
:
' 值不能为空'
,
trigger
:
'change'
},
{
required
:
false
,
type
:
'string'
,
message
:
' 值不能为空'
,
trigger
:
'blur'
},
],
srfsourcekey
:
[
{
required
:
false
,
type
:
'string'
,
message
:
' 值不能为空'
,
trigger
:
'change'
},
{
required
:
false
,
type
:
'string'
,
message
:
' 值不能为空'
,
trigger
:
'blur'
},
],
opportunityname
:
[
{
required
:
false
,
type
:
'string'
,
message
:
'商机名称 值不能为空'
,
trigger
:
'change'
},
{
required
:
false
,
type
:
'string'
,
message
:
'商机名称 值不能为空'
,
trigger
:
'blur'
},
],
parentcontactname
:
[
{
required
:
false
,
type
:
'string'
,
message
:
'联系人 值不能为空'
,
trigger
:
'change'
},
{
required
:
false
,
type
:
'string'
,
message
:
'联系人 值不能为空'
,
trigger
:
'blur'
},
],
parentaccountname
:
[
{
required
:
false
,
type
:
'string'
,
message
:
'帐户 值不能为空'
,
trigger
:
'change'
},
{
required
:
false
,
type
:
'string'
,
message
:
'帐户 值不能为空'
,
trigger
:
'blur'
},
],
purchasetimeframe
:
[
{
required
:
false
,
type
:
'string'
,
message
:
'购买时间范围 值不能为空'
,
trigger
:
'change'
},
{
required
:
false
,
type
:
'string'
,
message
:
'购买时间范围 值不能为空'
,
trigger
:
'blur'
},
],
transactioncurrencyname
:
[
{
required
:
false
,
type
:
'string'
,
message
:
'货币 值不能为空'
,
trigger
:
'change'
},
{
required
:
false
,
type
:
'string'
,
message
:
'货币 值不能为空'
,
trigger
:
'blur'
},
],
budgetamount
:
[
{
required
:
false
,
type
:
'number'
,
message
:
'预算金额 值不能为空'
,
trigger
:
'change'
},
{
required
:
false
,
type
:
'number'
,
message
:
'预算金额 值不能为空'
,
trigger
:
'blur'
},
],
purchaseprocess
:
[
{
required
:
false
,
type
:
'string'
,
message
:
'采购程序 值不能为空'
,
trigger
:
'change'
},
{
required
:
false
,
type
:
'string'
,
message
:
'采购程序 值不能为空'
,
trigger
:
'blur'
},
],
description
:
[
{
required
:
false
,
type
:
'string'
,
message
:
'说明 值不能为空'
,
trigger
:
'change'
},
{
required
:
false
,
type
:
'string'
,
message
:
'说明 值不能为空'
,
trigger
:
'blur'
},
],
currentsituation
:
[
{
required
:
false
,
type
:
'string'
,
message
:
'当前状况 值不能为空'
,
trigger
:
'change'
},
{
required
:
false
,
type
:
'string'
,
message
:
'当前状况 值不能为空'
,
trigger
:
'blur'
},
],
customerneed
:
[
{
required
:
false
,
type
:
'string'
,
message
:
'客户需求 值不能为空'
,
trigger
:
'change'
},
{
required
:
false
,
type
:
'string'
,
message
:
'客户需求 值不能为空'
,
trigger
:
'blur'
},
],
proposedsolution
:
[
{
required
:
false
,
type
:
'string'
,
message
:
'已拟定解决方案 值不能为空'
,
trigger
:
'change'
},
{
required
:
false
,
type
:
'string'
,
message
:
'已拟定解决方案 值不能为空'
,
trigger
:
'blur'
},
],
opportunityid
:
[
{
required
:
false
,
type
:
'string'
,
message
:
'商机 值不能为空'
,
trigger
:
'change'
},
{
required
:
false
,
type
:
'string'
,
message
:
'商机 值不能为空'
,
trigger
:
'blur'
},
],
}
/**
* 详情模型集合
*
* @type {*}
* @memberof AbstractInfoEditFormBase
*/
public
detailsModel
:
any
=
{
group1
:
new
FormGroupPanelModel
({
caption
:
'商机基本信息'
,
detailType
:
'GROUPPANEL'
,
name
:
'group1'
,
visible
:
true
,
isShowCaption
:
false
,
form
:
this
,
uiActionGroup
:
{
caption
:
''
,
langbase
:
'entities.opportunity.abstractinfo_form'
,
extractMode
:
'ITEM'
,
details
:
[]
}
}),
formpage1
:
new
FormPageModel
({
caption
:
'基本信息'
,
detailType
:
'FORMPAGE'
,
name
:
'formpage1'
,
visible
:
true
,
isShowCaption
:
true
,
form
:
this
}),
srfupdatedate
:
new
FormItemModel
({
caption
:
'更新时间'
,
detailType
:
'FORMITEM'
,
name
:
'srfupdatedate'
,
visible
:
true
,
isShowCaption
:
true
,
form
:
this
,
disabled
:
false
,
enableCond
:
0
}),
srforikey
:
new
FormItemModel
({
caption
:
''
,
detailType
:
'FORMITEM'
,
name
:
'srforikey'
,
visible
:
true
,
isShowCaption
:
true
,
form
:
this
,
disabled
:
false
,
enableCond
:
3
}),
srfkey
:
new
FormItemModel
({
caption
:
'商机'
,
detailType
:
'FORMITEM'
,
name
:
'srfkey'
,
visible
:
true
,
isShowCaption
:
true
,
form
:
this
,
disabled
:
false
,
enableCond
:
1
}),
srfmajortext
:
new
FormItemModel
({
caption
:
'商机名称'
,
detailType
:
'FORMITEM'
,
name
:
'srfmajortext'
,
visible
:
true
,
isShowCaption
:
true
,
form
:
this
,
disabled
:
false
,
enableCond
:
3
}),
srftempmode
:
new
FormItemModel
({
caption
:
''
,
detailType
:
'FORMITEM'
,
name
:
'srftempmode'
,
visible
:
true
,
isShowCaption
:
true
,
form
:
this
,
disabled
:
false
,
enableCond
:
3
}),
srfuf
:
new
FormItemModel
({
caption
:
''
,
detailType
:
'FORMITEM'
,
name
:
'srfuf'
,
visible
:
true
,
isShowCaption
:
true
,
form
:
this
,
disabled
:
false
,
enableCond
:
3
}),
srfdeid
:
new
FormItemModel
({
caption
:
''
,
detailType
:
'FORMITEM'
,
name
:
'srfdeid'
,
visible
:
true
,
isShowCaption
:
true
,
form
:
this
,
disabled
:
false
,
enableCond
:
3
}),
srfsourcekey
:
new
FormItemModel
({
caption
:
''
,
detailType
:
'FORMITEM'
,
name
:
'srfsourcekey'
,
visible
:
true
,
isShowCaption
:
true
,
form
:
this
,
disabled
:
false
,
enableCond
:
3
}),
opportunityname
:
new
FormItemModel
({
caption
:
'商机名称'
,
detailType
:
'FORMITEM'
,
name
:
'opportunityname'
,
visible
:
true
,
isShowCaption
:
true
,
form
:
this
,
disabled
:
false
,
enableCond
:
3
}),
parentcontactname
:
new
FormItemModel
({
caption
:
'联系人'
,
detailType
:
'FORMITEM'
,
name
:
'parentcontactname'
,
visible
:
true
,
isShowCaption
:
true
,
form
:
this
,
disabled
:
false
,
enableCond
:
3
}),
parentaccountname
:
new
FormItemModel
({
caption
:
'帐户'
,
detailType
:
'FORMITEM'
,
name
:
'parentaccountname'
,
visible
:
true
,
isShowCaption
:
true
,
form
:
this
,
disabled
:
false
,
enableCond
:
3
}),
purchasetimeframe
:
new
FormItemModel
({
caption
:
'购买时间范围'
,
detailType
:
'FORMITEM'
,
name
:
'purchasetimeframe'
,
visible
:
true
,
isShowCaption
:
true
,
form
:
this
,
disabled
:
false
,
enableCond
:
3
}),
transactioncurrencyname
:
new
FormItemModel
({
caption
:
'货币'
,
detailType
:
'FORMITEM'
,
name
:
'transactioncurrencyname'
,
visible
:
true
,
isShowCaption
:
true
,
form
:
this
,
disabled
:
false
,
enableCond
:
3
}),
budgetamount
:
new
FormItemModel
({
caption
:
'预算金额'
,
detailType
:
'FORMITEM'
,
name
:
'budgetamount'
,
visible
:
true
,
isShowCaption
:
true
,
form
:
this
,
disabled
:
false
,
enableCond
:
3
}),
purchaseprocess
:
new
FormItemModel
({
caption
:
'采购程序'
,
detailType
:
'FORMITEM'
,
name
:
'purchaseprocess'
,
visible
:
true
,
isShowCaption
:
true
,
form
:
this
,
disabled
:
false
,
enableCond
:
3
}),
description
:
new
FormItemModel
({
caption
:
'说明'
,
detailType
:
'FORMITEM'
,
name
:
'description'
,
visible
:
true
,
isShowCaption
:
true
,
form
:
this
,
disabled
:
false
,
enableCond
:
3
}),
currentsituation
:
new
FormItemModel
({
caption
:
'当前状况'
,
detailType
:
'FORMITEM'
,
name
:
'currentsituation'
,
visible
:
true
,
isShowCaption
:
true
,
form
:
this
,
disabled
:
false
,
enableCond
:
3
}),
customerneed
:
new
FormItemModel
({
caption
:
'客户需求'
,
detailType
:
'FORMITEM'
,
name
:
'customerneed'
,
visible
:
true
,
isShowCaption
:
true
,
form
:
this
,
disabled
:
false
,
enableCond
:
3
}),
proposedsolution
:
new
FormItemModel
({
caption
:
'已拟定解决方案'
,
detailType
:
'FORMITEM'
,
name
:
'proposedsolution'
,
visible
:
true
,
isShowCaption
:
true
,
form
:
this
,
disabled
:
false
,
enableCond
:
3
}),
opportunityid
:
new
FormItemModel
({
caption
:
'商机'
,
detailType
:
'FORMITEM'
,
name
:
'opportunityid'
,
visible
:
true
,
isShowCaption
:
true
,
form
:
this
,
disabled
:
false
,
enableCond
:
1
}),
};
}
\ No newline at end of file
app_CRM/src/widgets/opportunity/abstract-info-form/abstract-info-form-model.ts
0 → 100644
浏览文件 @
071449f5
/**
* AbstractInfo 部件模型
*
* @export
* @class AbstractInfoModel
*/
export
default
class
AbstractInfoModel
{
/**
* 获取数据项集合
*
* @returns {any[]}
* @memberof AbstractInfoModel
*/
public
getDataItems
():
any
[]
{
return
[
{
name
:
'srfwfmemo'
,
prop
:
'srfwfmemo'
,
dataType
:
'TEXT'
,
},
// 前端新增修改标识,新增为"0",修改为"1"或未设值
{
name
:
'srffrontuf'
,
prop
:
'srffrontuf'
,
dataType
:
'TEXT'
,
},
{
name
:
'srfupdatedate'
,
prop
:
'updatedate'
,
dataType
:
'DATETIME'
,
},
{
name
:
'srforikey'
,
},
{
name
:
'srfkey'
,
prop
:
'opportunityid'
,
dataType
:
'GUID'
,
},
{
name
:
'srfmajortext'
,
prop
:
'opportunityname'
,
dataType
:
'TEXT'
,
},
{
name
:
'srftempmode'
,
},
{
name
:
'srfuf'
,
},
{
name
:
'srfdeid'
,
},
{
name
:
'srfsourcekey'
,
},
{
name
:
'opportunityname'
,
prop
:
'opportunityname'
,
dataType
:
'TEXT'
,
},
{
name
:
'parentcontactname'
,
prop
:
'parentcontactname'
,
dataType
:
'PICKUPTEXT'
,
},
{
name
:
'parentaccountname'
,
prop
:
'parentaccountname'
,
dataType
:
'PICKUPTEXT'
,
},
{
name
:
'purchasetimeframe'
,
prop
:
'purchasetimeframe'
,
dataType
:
'SSCODELIST'
,
},
{
name
:
'transactioncurrencyname'
,
prop
:
'transactioncurrencyname'
,
dataType
:
'PICKUPTEXT'
,
},
{
name
:
'budgetamount'
,
prop
:
'budgetamount'
,
dataType
:
'BIGDECIMAL'
,
},
{
name
:
'purchaseprocess'
,
prop
:
'purchaseprocess'
,
dataType
:
'SSCODELIST'
,
},
{
name
:
'description'
,
prop
:
'description'
,
dataType
:
'TEXT'
,
},
{
name
:
'currentsituation'
,
prop
:
'currentsituation'
,
dataType
:
'TEXT'
,
},
{
name
:
'customerneed'
,
prop
:
'customerneed'
,
dataType
:
'TEXT'
,
},
{
name
:
'proposedsolution'
,
prop
:
'proposedsolution'
,
dataType
:
'TEXT'
,
},
{
name
:
'opportunityid'
,
prop
:
'opportunityid'
,
dataType
:
'GUID'
,
},
{
name
:
'opportunity'
,
prop
:
'opportunityid'
,
dataType
:
'FONTKEY'
,
},
]
}
}
\ No newline at end of file
app_CRM/src/widgets/opportunity/abstract-info-form/abstract-info-form-service.ts
0 → 100644
浏览文件 @
071449f5
import
{
Http
,
Util
,
Errorlog
}
from
'@/utils'
;
import
ControlService
from
'@/widgets/control-service'
;
import
OpportunityService
from
'@/service/opportunity/opportunity-service'
;
import
AbstractInfoModel
from
'./abstract-info-form-model'
;
/**
* AbstractInfo 部件服务对象
*
* @export
* @class AbstractInfoService
*/
export
default
class
AbstractInfoService
extends
ControlService
{
/**
* 商机服务对象
*
* @type {OpportunityService}
* @memberof AbstractInfoService
*/
public
appEntityService
:
OpportunityService
=
new
OpportunityService
({
$store
:
this
.
getStore
()
});
/**
* 设置从数据模式
*
* @type {boolean}
* @memberof AbstractInfoService
*/
public
setTempMode
(){
this
.
isTempMode
=
false
;
}
/**
* Creates an instance of AbstractInfoService.
*
* @param {*} [opts={}]
* @memberof AbstractInfoService
*/
constructor
(
opts
:
any
=
{})
{
super
(
opts
);
this
.
model
=
new
AbstractInfoModel
();
}
/**
* 处理数据
*
* @private
* @param {Promise<any>} promise
* @returns {Promise<any>}
* @memberof AbstractInfoService
*/
private
doItems
(
promise
:
Promise
<
any
>
,
deKeyField
:
string
,
deName
:
string
):
Promise
<
any
>
{
return
new
Promise
((
resolve
,
reject
)
=>
{
promise
.
then
((
response
:
any
)
=>
{
if
(
response
&&
response
.
status
===
200
)
{
const
data
=
response
.
data
;
data
.
forEach
((
item
:
any
,
index
:
number
)
=>
{
item
[
deName
]
=
item
[
deKeyField
];
data
[
index
]
=
item
;
});
resolve
(
data
);
}
else
{
reject
([])
}
}).
catch
((
response
:
any
)
=>
{
reject
([])
});
});
}
/**
* 获取跨实体数据集合
*
* @param {string} serviceName 服务名称
* @param {string} interfaceName 接口名称
* @param {*} data
* @param {boolean} [isloading]
* @returns {Promise<any[]>}
* @memberof AbstractInfoService
*/
@
Errorlog
public
getItems
(
serviceName
:
string
,
interfaceName
:
string
,
context
:
any
=
{},
data
:
any
,
isloading
?:
boolean
):
Promise
<
any
[]
>
{
return
Promise
.
reject
([])
}
/**
* 启动工作流
*
* @param {string} action
* @param {*} [context={}]
* @param {*} [data={}]
* @param {boolean} [isloading]
* @param {*} [localdata]
* @returns {Promise<any>}
* @memberof AbstractInfoService
*/
@
Errorlog
public
wfstart
(
action
:
string
,
context
:
any
=
{},
data
:
any
=
{},
isloading
?:
boolean
,
localdata
?:
any
):
Promise
<
any
>
{
data
=
this
.
handleWFData
(
data
);
context
=
this
.
handleRequestData
(
action
,
context
,
data
).
context
;
return
new
Promise
((
resolve
:
any
,
reject
:
any
)
=>
{
let
result
:
Promise
<
any
>
;
const
_appEntityService
:
any
=
this
.
appEntityService
;
if
(
_appEntityService
[
action
]
&&
_appEntityService
[
action
]
instanceof
Function
)
{
result
=
_appEntityService
[
action
](
context
,
data
,
isloading
,
localdata
);
}
else
{
result
=
this
.
appEntityService
.
WFStart
(
context
,
data
,
isloading
,
localdata
);
}
result
.
then
((
response
)
=>
{
this
.
handleResponse
(
action
,
response
);
resolve
(
response
);
}).
catch
(
response
=>
{
reject
(
response
);
});
});
}
/**
* 提交工作流
*
* @param {string} action
* @param {*} [context={}]
* @param {*} [data={}]
* @param {boolean} [isloading]
* @param {*} [localdata]
* @returns {Promise<any>}
* @memberof AbstractInfoService
*/
@
Errorlog
public
wfsubmit
(
action
:
string
,
context
:
any
=
{},
data
:
any
=
{},
isloading
?:
boolean
,
localdata
?:
any
):
Promise
<
any
>
{
data
=
this
.
handleWFData
(
data
,
true
);
context
=
this
.
handleRequestData
(
action
,
context
,
data
,
true
).
context
;
return
new
Promise
((
resolve
:
any
,
reject
:
any
)
=>
{
let
result
:
Promise
<
any
>
;
const
_appEntityService
:
any
=
this
.
appEntityService
;
if
(
_appEntityService
[
action
]
&&
_appEntityService
[
action
]
instanceof
Function
)
{
result
=
_appEntityService
[
action
](
context
,
data
,
isloading
,
localdata
);
}
else
{
result
=
this
.
appEntityService
.
WFSubmit
(
context
,
data
,
isloading
,
localdata
);
}
result
.
then
((
response
)
=>
{
this
.
handleResponse
(
action
,
response
);
resolve
(
response
);
}).
catch
(
response
=>
{
reject
(
response
);
});
});
}
/**
* 添加数据
*
* @param {string} action
* @param {*} [context={}]
* @param {*} [data={}]
* @param {boolean} [isloading]
* @returns {Promise<any>}
* @memberof AbstractInfoService
*/
@
Errorlog
public
add
(
action
:
string
,
context
:
any
=
{},
data
:
any
=
{},
isloading
?:
boolean
):
Promise
<
any
>
{
const
{
data
:
Data
,
context
:
Context
}
=
this
.
handleRequestData
(
action
,
context
,
data
);
return
new
Promise
((
resolve
:
any
,
reject
:
any
)
=>
{
let
result
:
Promise
<
any
>
;
const
_appEntityService
:
any
=
this
.
appEntityService
;
if
(
_appEntityService
[
action
]
&&
_appEntityService
[
action
]
instanceof
Function
)
{
result
=
_appEntityService
[
action
](
Context
,
Data
,
isloading
);
}
else
{
result
=
this
.
appEntityService
.
Create
(
Context
,
Data
,
isloading
);
}
result
.
then
((
response
)
=>
{
this
.
handleResponse
(
action
,
response
);
resolve
(
response
);
}).
catch
(
response
=>
{
reject
(
response
);
});
});
}
/**
* 删除数据
*
* @param {string} action
* @param {*} [context={}]
* @param {*} [data={}]
* @param {boolean} [isloading]
* @returns {Promise<any>}
* @memberof AbstractInfoService
*/
@
Errorlog
public
delete
(
action
:
string
,
context
:
any
=
{},
data
:
any
=
{},
isloading
?:
boolean
):
Promise
<
any
>
{
const
{
data
:
Data
,
context
:
Context
}
=
this
.
handleRequestData
(
action
,
context
,
data
);
return
new
Promise
((
resolve
:
any
,
reject
:
any
)
=>
{
let
result
:
Promise
<
any
>
;
const
_appEntityService
:
any
=
this
.
appEntityService
;
if
(
_appEntityService
[
action
]
&&
_appEntityService
[
action
]
instanceof
Function
)
{
result
=
_appEntityService
[
action
](
Context
,
Data
,
isloading
);
}
else
{
result
=
this
.
appEntityService
.
Remove
(
Context
,
Data
,
isloading
);
}
result
.
then
((
response
)
=>
{
resolve
(
response
);
}).
catch
(
response
=>
{
reject
(
response
);
});
});
}
/**
* 修改数据
*
* @param {string} action
* @param {*} [context={}]
* @param {*} [data={}]
* @param {boolean} [isloading]
* @returns {Promise<any>}
* @memberof AbstractInfoService
*/
@
Errorlog
public
update
(
action
:
string
,
context
:
any
=
{},
data
:
any
=
{},
isloading
?:
boolean
):
Promise
<
any
>
{
const
{
data
:
Data
,
context
:
Context
}
=
this
.
handleRequestData
(
action
,
context
,
data
);
return
new
Promise
((
resolve
:
any
,
reject
:
any
)
=>
{
let
result
:
Promise
<
any
>
;
const
_appEntityService
:
any
=
this
.
appEntityService
;
if
(
_appEntityService
[
action
]
&&
_appEntityService
[
action
]
instanceof
Function
)
{
result
=
_appEntityService
[
action
](
Context
,
Data
,
isloading
);
}
else
{
result
=
this
.
appEntityService
.
Update
(
Context
,
Data
,
isloading
);
}
result
.
then
((
response
)
=>
{
this
.
handleResponse
(
action
,
response
);
resolve
(
response
);
}).
catch
(
response
=>
{
reject
(
response
);
});
});
}
/**
* 查询数据
*
* @param {string} action
* @param {*} [context={}]
* @param {*} [data={}]
* @param {boolean} [isloading]
* @returns {Promise<any>}
* @memberof AbstractInfoService
*/
@
Errorlog
public
get
(
action
:
string
,
context
:
any
=
{},
data
:
any
=
{},
isloading
?:
boolean
):
Promise
<
any
>
{
const
{
data
:
Data
,
context
:
Context
}
=
this
.
handleRequestData
(
action
,
context
,
data
);
return
new
Promise
((
resolve
:
any
,
reject
:
any
)
=>
{
let
result
:
Promise
<
any
>
;
const
_appEntityService
:
any
=
this
.
appEntityService
;
if
(
_appEntityService
[
action
]
&&
_appEntityService
[
action
]
instanceof
Function
)
{
result
=
_appEntityService
[
action
](
Context
,
Data
,
isloading
);
}
else
{
result
=
this
.
appEntityService
.
Get
(
Context
,
Data
,
isloading
);
}
result
.
then
((
response
)
=>
{
this
.
handleResponse
(
action
,
response
);
resolve
(
response
);
}).
catch
(
response
=>
{
reject
(
response
);
});
});
}
/**
* 加载草稿
*
* @param {string} action
* @param {*} [context={}]
* @param {*} [data={}]
* @param {boolean} [isloading]
* @returns {Promise<any>}
* @memberof AbstractInfoService
*/
@
Errorlog
public
loadDraft
(
action
:
string
,
context
:
any
=
{},
data
:
any
=
{},
isloading
?:
boolean
):
Promise
<
any
>
{
const
{
data
:
Data
,
context
:
Context
}
=
this
.
handleRequestData
(
action
,
context
,
data
);
//仿真主键数据
const
PrimaryKey
=
Util
.
createUUID
();
Data
.
opportunityid
=
PrimaryKey
;
Data
.
opportunity
=
PrimaryKey
;
return
new
Promise
((
resolve
:
any
,
reject
:
any
)
=>
{
let
result
:
Promise
<
any
>
;
const
_appEntityService
:
any
=
this
.
appEntityService
;
if
(
_appEntityService
[
action
]
&&
_appEntityService
[
action
]
instanceof
Function
)
{
result
=
_appEntityService
[
action
](
Context
,
Data
,
isloading
);
}
else
{
result
=
this
.
appEntityService
.
GetDraft
(
Context
,
Data
,
isloading
);
}
result
.
then
((
response
)
=>
{
response
.
data
.
opportunityid
=
PrimaryKey
;
this
.
handleResponse
(
action
,
response
,
true
);
resolve
(
response
);
}).
catch
(
response
=>
{
reject
(
response
);
});
});
}
/**
* 前台逻辑
* @param {string} action
* @param {*} [context={}]
* @param {*} [data={}]
* @param {boolean} [isloading]
* @returns {Promise<any>}
* @memberof AbstractInfoService
*/
@
Errorlog
public
frontLogic
(
action
:
string
,
context
:
any
=
{},
data
:
any
=
{},
isloading
?:
boolean
):
Promise
<
any
>
{
const
{
data
:
Data
,
context
:
Context
}
=
this
.
handleRequestData
(
action
,
context
,
data
);
return
new
Promise
((
resolve
:
any
,
reject
:
any
)
=>
{
let
result
:
Promise
<
any
>
;
const
_appEntityService
:
any
=
this
.
appEntityService
;
if
(
_appEntityService
[
action
]
&&
_appEntityService
[
action
]
instanceof
Function
)
{
result
=
_appEntityService
[
action
](
Context
,
Data
,
isloading
);
}
else
{
return
Promise
.
reject
({
status
:
500
,
data
:
{
title
:
'失败'
,
message
:
'系统异常'
}
});
}
result
.
then
((
response
)
=>
{
this
.
handleResponse
(
action
,
response
,
true
);
resolve
(
response
);
}).
catch
(
response
=>
{
reject
(
response
);
});
})
}
/**
* 处理请求数据
*
* @param action 行为
* @param data 数据
* @memberof AbstractInfoService
*/
public
handleRequestData
(
action
:
string
,
context
:
any
,
data
:
any
=
{},
isMerge
:
boolean
=
false
){
let
mode
:
any
=
this
.
getMode
();
if
(
!
mode
&&
mode
.
getDataItems
instanceof
Function
)
{
return
data
;
}
let
formItemItems
:
any
[]
=
mode
.
getDataItems
();
let
requestData
:
any
=
{};
if
(
isMerge
&&
(
data
&&
data
.
viewparams
)){
Object
.
assign
(
requestData
,
data
.
viewparams
);
}
formItemItems
.
forEach
((
item
:
any
)
=>
{
if
(
item
&&
item
.
dataType
&&
Object
.
is
(
item
.
dataType
,
'FONTKEY'
)){
if
(
item
&&
item
.
prop
){
requestData
[
item
.
prop
]
=
context
[
item
.
name
];
}
}
else
{
if
(
item
&&
item
.
prop
){
requestData
[
item
.
prop
]
=
data
[
item
.
name
];
}
}
});
let
tempContext
:
any
=
JSON
.
parse
(
JSON
.
stringify
(
context
));
if
(
tempContext
&&
tempContext
.
srfsessionid
){
tempContext
.
srfsessionkey
=
tempContext
.
srfsessionid
;
delete
tempContext
.
srfsessionid
;
}
return
{
context
:
tempContext
,
data
:
requestData
};
}
}
\ No newline at end of file
app_CRM/src/widgets/opportunity/abstract-info-form/abstract-info-form.html
0 → 100644
浏览文件 @
071449f5
<i-form
:model=
"this.data"
class=
'app-form info-form-mode'
ref=
'form'
id=
'opportunity_abstractinfo'
style=
""
>
<input
style=
"display:none;"
/>
<row
>
<i-col
v-show=
"detailsModel.group1.visible"
:style=
"{}"
:lg=
"{ span: 24, offset: 0 }"
>
<app-form-group
layoutType=
"TABLE_24COL"
titleStyle=
""
class=
''
:uiActionGroup=
"detailsModel.group1.uiActionGroup"
@
groupuiactionclick=
"groupUIActionClick($event)"
:caption=
"$t('entities.opportunity.abstractinfo_form.details.group1')"
:isShowCaption=
"false"
uiStyle=
"DEFAULT"
:titleBarCloseMode=
"0"
:isInfoGroupMode=
"true"
>
<row>
<i-col
v-show=
"detailsModel.opportunityname.visible"
:style=
"{}"
:md=
"{ span: 12, offset: 0 }"
:lg=
"{ span: 8, offset: 0 }"
:xl=
"{ span: 6, offset: 0 }"
>
<app-form-item
name=
'opportunityname'
:itemRules=
"this.rules.opportunityname"
class=
''
:caption=
"$t('entities.opportunity.abstractinfo_form.details.opportunityname')"
uiStyle=
"DEFAULT"
:labelWidth=
"130"
:isShowCaption=
"true"
:error=
"detailsModel.opportunityname.error"
:isEmptyCaption=
"false"
labelPos=
"LEFT"
>
<app-span
name=
'opportunityname'
:value=
"data.opportunityname"
:data=
"data"
:context=
"context"
:viewparams=
"viewparams"
:localContext =
'{ }'
:localParam =
'{ }'
style=
""
></app-span>
</app-form-item>
</i-col>
<i-col
v-show=
"detailsModel.parentcontactname.visible"
:style=
"{}"
:md=
"{ span: 12, offset: 0 }"
:lg=
"{ span: 8, offset: 0 }"
:xl=
"{ span: 6, offset: 0 }"
>
<app-form-item
name=
'parentcontactname'
:itemRules=
"this.rules.parentcontactname"
class=
''
:caption=
"$t('entities.opportunity.abstractinfo_form.details.parentcontactname')"
uiStyle=
"DEFAULT"
:labelWidth=
"130"
:isShowCaption=
"true"
:error=
"detailsModel.parentcontactname.error"
:isEmptyCaption=
"false"
labelPos=
"LEFT"
>
<app-span
name=
'parentcontactname'
:value=
"data.parentcontactname"
:data=
"data"
:context=
"context"
:viewparams=
"viewparams"
:localContext =
'{ }'
:localParam =
'{ }'
style=
""
></app-span>
</app-form-item>
</i-col>
<i-col
v-show=
"detailsModel.parentaccountname.visible"
:style=
"{}"
:md=
"{ span: 12, offset: 0 }"
:lg=
"{ span: 8, offset: 0 }"
:xl=
"{ span: 6, offset: 0 }"
>
<app-form-item
name=
'parentaccountname'
:itemRules=
"this.rules.parentaccountname"
class=
''
:caption=
"$t('entities.opportunity.abstractinfo_form.details.parentaccountname')"
uiStyle=
"DEFAULT"
:labelWidth=
"130"
:isShowCaption=
"true"
:error=
"detailsModel.parentaccountname.error"
:isEmptyCaption=
"false"
labelPos=
"LEFT"
>
<app-span
name=
'parentaccountname'
:value=
"data.parentaccountname"
:data=
"data"
:context=
"context"
:viewparams=
"viewparams"
:localContext =
'{ }'
:localParam =
'{ }'
style=
""
></app-span>
</app-form-item>
</i-col>
<i-col
v-show=
"detailsModel.purchasetimeframe.visible"
:style=
"{}"
:md=
"{ span: 12, offset: 0 }"
:lg=
"{ span: 8, offset: 0 }"
:xl=
"{ span: 6, offset: 0 }"
>
<app-form-item
name=
'purchasetimeframe'
:itemRules=
"this.rules.purchasetimeframe"
class=
''
:caption=
"$t('entities.opportunity.abstractinfo_form.details.purchasetimeframe')"
uiStyle=
"DEFAULT"
:labelWidth=
"130"
:isShowCaption=
"true"
:error=
"detailsModel.purchasetimeframe.error"
:isEmptyCaption=
"false"
labelPos=
"LEFT"
>
<app-span
name=
'purchasetimeframe'
:value=
"data.purchasetimeframe"
tag=
'Opportunity__PurchaseTimeframe'
codelistType=
'STATIC'
:data=
"data"
:context=
"context"
:viewparams=
"viewparams"
:localContext =
'{ }'
:localParam =
'{ }'
style=
""
></app-span>
</app-form-item>
</i-col>
<i-col
v-show=
"detailsModel.transactioncurrencyname.visible"
:style=
"{}"
:md=
"{ span: 12, offset: 0 }"
:lg=
"{ span: 8, offset: 0 }"
:xl=
"{ span: 6, offset: 0 }"
>
<app-form-item
name=
'transactioncurrencyname'
:itemRules=
"this.rules.transactioncurrencyname"
class=
''
:caption=
"$t('entities.opportunity.abstractinfo_form.details.transactioncurrencyname')"
uiStyle=
"DEFAULT"
:labelWidth=
"130"
:isShowCaption=
"true"
:error=
"detailsModel.transactioncurrencyname.error"
:isEmptyCaption=
"false"
labelPos=
"LEFT"
>
<app-span
name=
'transactioncurrencyname'
:value=
"data.transactioncurrencyname"
:data=
"data"
:context=
"context"
:viewparams=
"viewparams"
:localContext =
'{ }'
:localParam =
'{ }'
style=
""
></app-span>
</app-form-item>
</i-col>
<i-col
v-show=
"detailsModel.budgetamount.visible"
:style=
"{}"
:md=
"{ span: 12, offset: 0 }"
:lg=
"{ span: 8, offset: 0 }"
:xl=
"{ span: 6, offset: 0 }"
>
<app-form-item
name=
'budgetamount'
:itemRules=
"this.rules.budgetamount"
class=
''
:caption=
"$t('entities.opportunity.abstractinfo_form.details.budgetamount')"
uiStyle=
"DEFAULT"
:labelWidth=
"130"
:isShowCaption=
"true"
:error=
"detailsModel.budgetamount.error"
:isEmptyCaption=
"false"
labelPos=
"LEFT"
>
<app-span
name=
'budgetamount'
:value=
"data.budgetamount"
:data=
"data"
:context=
"context"
:viewparams=
"viewparams"
:localContext =
'{ }'
:localParam =
'{ }'
style=
""
></app-span>
</app-form-item>
</i-col>
<i-col
v-show=
"detailsModel.purchaseprocess.visible"
:style=
"{}"
:md=
"{ span: 12, offset: 0 }"
:lg=
"{ span: 8, offset: 0 }"
:xl=
"{ span: 6, offset: 0 }"
>
<app-form-item
name=
'purchaseprocess'
:itemRules=
"this.rules.purchaseprocess"
class=
''
:caption=
"$t('entities.opportunity.abstractinfo_form.details.purchaseprocess')"
uiStyle=
"DEFAULT"
:labelWidth=
"130"
:isShowCaption=
"true"
:error=
"detailsModel.purchaseprocess.error"
:isEmptyCaption=
"false"
labelPos=
"LEFT"
>
<app-span
name=
'purchaseprocess'
:value=
"data.purchaseprocess"
tag=
'Opportunity__PurchaseProcess'
codelistType=
'STATIC'
:data=
"data"
:context=
"context"
:viewparams=
"viewparams"
:localContext =
'{ }'
:localParam =
'{ }'
style=
""
></app-span>
</app-form-item>
</i-col>
<i-col
v-show=
"detailsModel.description.visible"
:style=
"{}"
:md=
"{ span: 12, offset: 0 }"
:lg=
"{ span: 24, offset: 0 }"
:xl=
"{ span: 24, offset: 0 }"
>
<app-form-item
name=
'description'
:itemRules=
"this.rules.description"
class=
''
:caption=
"$t('entities.opportunity.abstractinfo_form.details.description')"
uiStyle=
"DEFAULT"
:labelWidth=
"130"
:isShowCaption=
"true"
:error=
"detailsModel.description.error"
:isEmptyCaption=
"false"
labelPos=
"LEFT"
>
<app-span
name=
'description'
:value=
"data.description"
:data=
"data"
:context=
"context"
:viewparams=
"viewparams"
:localContext =
'{ }'
:localParam =
'{ }'
style=
""
></app-span>
</app-form-item>
</i-col>
<i-col
v-show=
"detailsModel.currentsituation.visible"
:style=
"{}"
:md=
"{ span: 12, offset: 0 }"
:lg=
"{ span: 24, offset: 0 }"
:xl=
"{ span: 24, offset: 0 }"
>
<app-form-item
name=
'currentsituation'
:itemRules=
"this.rules.currentsituation"
class=
''
:caption=
"$t('entities.opportunity.abstractinfo_form.details.currentsituation')"
uiStyle=
"DEFAULT"
:labelWidth=
"130"
:isShowCaption=
"true"
:error=
"detailsModel.currentsituation.error"
:isEmptyCaption=
"false"
labelPos=
"LEFT"
>
<app-span
name=
'currentsituation'
:value=
"data.currentsituation"
:data=
"data"
:context=
"context"
:viewparams=
"viewparams"
:localContext =
'{ }'
:localParam =
'{ }'
style=
""
></app-span>
</app-form-item>
</i-col>
<i-col
v-show=
"detailsModel.customerneed.visible"
:style=
"{}"
:md=
"{ span: 12, offset: 0 }"
:lg=
"{ span: 24, offset: 0 }"
:xl=
"{ span: 24, offset: 0 }"
>
<app-form-item
name=
'customerneed'
:itemRules=
"this.rules.customerneed"
class=
''
:caption=
"$t('entities.opportunity.abstractinfo_form.details.customerneed')"
uiStyle=
"DEFAULT"
:labelWidth=
"130"
:isShowCaption=
"true"
:error=
"detailsModel.customerneed.error"
:isEmptyCaption=
"false"
labelPos=
"LEFT"
>
<app-span
name=
'customerneed'
:value=
"data.customerneed"
:data=
"data"
:context=
"context"
:viewparams=
"viewparams"
:localContext =
'{ }'
:localParam =
'{ }'
style=
""
></app-span>
</app-form-item>
</i-col>
<i-col
v-show=
"detailsModel.proposedsolution.visible"
:style=
"{}"
:md=
"{ span: 12, offset: 0 }"
:lg=
"{ span: 24, offset: 0 }"
:xl=
"{ span: 24, offset: 0 }"
>
<app-form-item
name=
'proposedsolution'
:itemRules=
"this.rules.proposedsolution"
class=
''
:caption=
"$t('entities.opportunity.abstractinfo_form.details.proposedsolution')"
uiStyle=
"DEFAULT"
:labelWidth=
"130"
:isShowCaption=
"true"
:error=
"detailsModel.proposedsolution.error"
:isEmptyCaption=
"false"
labelPos=
"LEFT"
>
<app-span
name=
'proposedsolution'
:value=
"data.proposedsolution"
:data=
"data"
:context=
"context"
:viewparams=
"viewparams"
:localContext =
'{ }'
:localParam =
'{ }'
style=
""
></app-span>
</app-form-item>
</i-col>
</row>
</app-form-group>
</i-col>
</row>
</i-form>
\ No newline at end of file
app_CRM/src/widgets/opportunity/abstract-info-form/abstract-info-form.vue
0 → 100644
浏览文件 @
071449f5
<
template
src=
"./abstract-info-form.html"
/>
<script
lang=
'tsx'
>
import
{ Component } from 'vue-property-decorator';
import { VueLifeCycleProcessing } from '@/studio-core';
import { AbstractInfoEditFormBase } from './abstract-info-form-base';
/**
* form部件
*
* @export
* @class AbstractInfoEditForm
* @extends {AbstractInfoEditFormBase}
*/
@Component({
components: {
}
})
@VueLifeCycleProcessing()
export default class AbstractInfoEditForm extends AbstractInfoEditFormBase { }
</script>
app_CRM/src/widgets/opportunity/view-opp-abs-portlet/view-opp-abs-portlet-base.tsx
0 → 100644
浏览文件 @
071449f5
import
{
Prop
,
Provide
,
Emit
,
Model
}
from
'vue-property-decorator'
;
import
{
Subject
,
Subscription
}
from
'rxjs'
;
import
{
Watch
,
MainControlBase
}
from
'@/studio-core'
;
import
OpportunityService
from
'@/service/opportunity/opportunity-service'
;
import
View_OppAbsService
from
'./view-opp-abs-portlet-service'
;
import
{
Environment
}
from
'@/environments/environment'
;
/**
* dashboard_sysportlet1部件基类
*
* @export
* @class MainControlBase
* @extends {View_OppAbsPortletBase}
*/
export
class
View_OppAbsPortletBase
extends
MainControlBase
{
/**
* 建构部件服务对象
*
* @type {View_OppAbsService}
* @memberof View_OppAbsPortletBase
*/
public
service
:
View_OppAbsService
=
new
View_OppAbsService
({
$store
:
this
.
$store
});
/**
* 实体服务对象
*
* @type {OpportunityService}
* @memberof View_OppAbsPortletBase
*/
public
appEntityService
:
OpportunityService
=
new
OpportunityService
({
$store
:
this
.
$store
});
/**
* 应用实体名称
*
* @protected
* @type {string}
* @memberof View_OppAbsPortletBase
*/
protected
appDeName
:
string
=
'opportunity'
;
/**
* 长度
*
* @type {number}
* @memberof View_OppAbs
*/
@
Prop
()
public
height
?:
number
;
/**
* 宽度
*
* @type {number}
* @memberof View_OppAbs
*/
@
Prop
()
public
width
?:
number
;
/**
* 是否自适应大小
*
* @returns {boolean}
* @memberof View_OppAbsBase
*/
@
Prop
({
default
:
false
})
public
isAdaptiveSize
!
:
boolean
;
/**
* 获取多项数据
*
* @returns {any[]}
* @memberof View_OppAbsBase
*/
public
getDatas
():
any
[]
{
return
[];
}
/**
* 获取单项树
*
* @returns {*}
* @memberof View_OppAbsBase
*/
public
getData
():
any
{
return
{};
}
/**
* 获取高度
*
* @returns {any[]}
* @memberof View_OppAbsBase
*/
get
getHeight
():
any
{
if
(
!
this
.
$util
.
isEmpty
(
this
.
height
)
&&
!
this
.
$util
.
isNumberNaN
(
this
.
height
)){
if
(
this
.
height
==
0
){
return
'auto'
;
}
else
{
return
this
.
height
+
'px'
;
}
}
else
{
return
'auto'
;
}
}
/**
* vue 生命周期
*
* @memberof View_OppAbsBase
*/
public
created
()
{
this
.
afterCreated
();
}
/**
* 执行created后的逻辑
*
* @memberof View_OppAbsBase
*/
public
afterCreated
(){
if
(
this
.
viewState
)
{
this
.
viewStateEvent
=
this
.
viewState
.
subscribe
(({
tag
,
action
,
data
})
=>
{
if
(
!
Object
.
is
(
tag
,
this
.
name
))
{
return
;
}
const
refs
:
any
=
this
.
$refs
;
Object
.
keys
(
refs
).
forEach
((
_name
:
string
)
=>
{
this
.
viewState
.
next
({
tag
:
_name
,
action
:
action
,
data
:
data
});
});
});
}
}
/**
* vue 生命周期
*
* @memberof View_OppAbsBase
*/
public
destroyed
()
{
this
.
afterDestroy
();
}
/**
* 执行destroyed后的逻辑
*
* @memberof View_OppAbsBase
*/
public
afterDestroy
()
{
if
(
this
.
viewStateEvent
)
{
this
.
viewStateEvent
.
unsubscribe
();
}
}
}
app_CRM/src/widgets/opportunity/view-opp-abs-portlet/view-opp-abs-portlet-model.ts
0 → 100644
浏览文件 @
071449f5
/**
* View_OppAbs 部件模型
*
* @export
* @class View_OppAbsModel
*/
export
default
class
View_OppAbsModel
{
/**
* 获取数据项集合
*
* @returns {any[]}
* @memberof View_OppAbsModel
*/
public
getDataItems
():
any
[]
{
return
[
{
name
:
'decisionmaker'
,
},
{
name
:
'totallineitemamount'
,
},
{
name
:
'processid'
,
},
{
name
:
'discountpercentage'
,
},
{
name
:
'pricingerrorcode'
,
},
{
name
:
'totalamount'
,
},
{
name
:
'totaltax_base'
,
},
{
name
:
'totaltax'
,
},
{
name
:
'updateman'
,
},
{
name
:
'estimatedvalue_base'
,
},
{
name
:
'presentfinalproposal'
,
},
{
name
:
'developproposal'
,
},
{
name
:
'opportunityratingcode'
,
},
{
name
:
'totalamount_base'
,
},
{
name
:
'totalamountlessfreight'
,
},
{
name
:
'description'
,
},
{
name
:
'identifycompetitors'
,
},
{
name
:
'updatedate'
,
},
{
name
:
'sendthankyounote'
,
},
{
name
:
'totaldiscountamount_base'
,
},
{
name
:
'totallineitemdiscountamount'
,
},
{
name
:
'purchaseprocess'
,
},
{
name
:
'traversedpath'
,
},
{
name
:
'captureproposalfeedback'
,
},
{
name
:
'finaldecisiondate'
,
},
{
name
:
'stepid'
,
},
{
name
:
'resolvefeedback'
,
},
{
name
:
'budgetamount_base'
,
},
{
name
:
'owneridyominame'
,
},
{
name
:
'pursuitdecision'
,
},
{
name
:
'revenuesystemcalculated'
,
},
{
name
:
'scheduleproposalmeeting'
,
},
{
name
:
'closeprobability'
,
},
{
name
:
'utcconversiontimezonecode'
,
},
{
name
:
'presentproposal'
,
},
{
name
:
'schedulefollowup_prospect'
,
},
{
name
:
'statuscode'
,
},
{
name
:
'actualclosedate'
,
},
{
name
:
'confirminterest'
,
},
{
name
:
'customerid'
,
},
{
name
:
'salesstage'
,
},
{
name
:
'opportunity'
,
prop
:
'opportunityid'
,
},
{
name
:
'onholdtime'
,
},
{
name
:
'qualificationcomments'
,
},
{
name
:
'accountidyominame'
,
},
{
name
:
'schedulefollowup_qualify'
,
},
{
name
:
'participatesinworkflow'
,
},
{
name
:
'exchangerate'
,
},
{
name
:
'stepname'
,
},
{
name
:
'customerneed'
,
},
{
name
:
'importsequencenumber'
,
},
{
name
:
'completeinternalreview'
,
},
{
name
:
'evaluatefit'
,
},
{
name
:
'salesstagecode'
,
},
{
name
:
'identifypursuitteam'
,
},
{
name
:
'contactidyominame'
,
},
{
name
:
'initialcommunication'
,
},
{
name
:
'versionnumber'
,
},
{
name
:
'freightamount_base'
,
},
{
name
:
'teamsfollowed'
,
},
{
name
:
'proposedsolution'
,
},
{
name
:
'filedebrief'
,
},
{
name
:
'budgetamount'
,
},
{
name
:
'budgetstatus'
,
},
{
name
:
'discountamount_base'
,
},
{
name
:
'completefinalproposal'
,
},
{
name
:
'discountamount'
,
},
{
name
:
'customeridyominame'
,
},
{
name
:
'need'
,
},
{
name
:
'stageid'
,
},
{
name
:
'freightamount'
,
},
{
name
:
'actualvalue'
,
},
{
name
:
'ibizprivate'
,
},
{
name
:
'timezoneruleversionnumber'
,
},
{
name
:
'createdate'
,
},
{
name
:
'prioritycode'
,
},
{
name
:
'totallineitemamount_base'
,
},
{
name
:
'estimatedclosedate'
,
},
{
name
:
'currentsituation'
,
},
{
name
:
'actualvalue_base'
,
},
{
name
:
'customerpainpoints'
,
},
{
name
:
'totaldiscountamount'
,
},
{
name
:
'opportunityname'
,
},
{
name
:
'owneridtype'
,
},
{
name
:
'identifycustomercontacts'
,
},
{
name
:
'timeline'
,
},
{
name
:
'lastonholdtime'
,
},
{
name
:
'totalamountlessfreight_base'
,
},
{
name
:
'estimatedvalue'
,
},
{
name
:
'emailaddress'
,
},
{
name
:
'statecode'
,
},
{
name
:
'purchasetimeframe'
,
},
{
name
:
'createman'
,
},
{
name
:
'quotecomments'
,
},
{
name
:
'customeridtype'
,
},
{
name
:
'overriddencreatedon'
,
},
{
name
:
'ownerid'
,
},
{
name
:
'slaname'
,
},
{
name
:
'parentcontactid'
,
},
{
name
:
'campaignid'
,
},
{
name
:
'transactioncurrencyid'
,
},
{
name
:
'parentaccountid'
,
},
{
name
:
'pricelevelid'
,
},
{
name
:
'originatingleadid'
,
},
{
name
:
'slaid'
,
},
{
name
:
'originatingleadname'
,
},
{
name
:
'parentaccountname'
,
},
{
name
:
'campaignname'
,
},
{
name
:
'parentcontactname'
,
},
{
name
:
'transactioncurrencyname'
,
},
{
name
:
'pricelevelname'
,
},
]
}
}
app_CRM/src/widgets/opportunity/view-opp-abs-portlet/view-opp-abs-portlet-service.ts
0 → 100644
浏览文件 @
071449f5
import
{
Http
}
from
'@/utils'
;
import
ControlService
from
'@/widgets/control-service'
;
/**
* View_OppAbs 部件服务对象
*
* @export
* @class View_OppAbsService
*/
export
default
class
View_OppAbsService
extends
ControlService
{
}
app_CRM/src/widgets/opportunity/view-opp-abs-portlet/view-opp-abs-portlet.html
0 → 100644
浏览文件 @
071449f5
<div
class=
'portlet view-opp-abs '
:style=
"{}"
>
<p
class=
'portlet-title'
>
<span>
摘要信息
</span>
</p>
<div
class=
"portlet-with-title"
>
<opportunity-info-abstract
:viewdata=
"JSON.stringify(context)"
:viewDefaultUsage=
"false"
></opportunity-info-abstract>
</div>
</div>
app_CRM/src/widgets/opportunity/view-opp-abs-portlet/view-opp-abs-portlet.vue
0 → 100644
浏览文件 @
071449f5
<
template
src=
"./view-opp-abs-portlet.html"
/>
<script
lang=
'tsx'
>
import
{ Component } from 'vue-property-decorator';
import { VueLifeCycleProcessing } from '@/studio-core';
import { View_OppAbsPortletBase } from './view-opp-abs-portlet-base';
/**
* dashboard_sysportlet1部件
*
* @export
* @class View_OppAbsPortlet
* @extends {View_OppAbsPortletBase}
*/
@Component({
components: {
}
})
@VueLifeCycleProcessing()
export default class View_OppAbsPortlet extends View_OppAbsPortletBase { }
</script>
businesscentral-core/src/main/resources/liquibase/h2_table.xml
浏览文件 @
071449f5
...
...
@@ -10424,7 +10424,7 @@
<!--输出实体[OPPORTUNITY]数据结构 -->
<changeSet
author=
"a_LAB01_e85d8801c"
id=
"tab-opportunity-10
4
-122"
>
<changeSet
author=
"a_LAB01_e85d8801c"
id=
"tab-opportunity-10
6
-122"
>
<createTable
tableName=
"OPPORTUNITY"
>
<column
name=
"DECISIONMAKER"
remarks=
""
type=
"INT"
>
</column>
...
...
@@ -11647,25 +11647,25 @@
<!--输出实体[RELATIONSHIPS]外键关系 -->
<!--输出实体[CONNECTIONROLE]外键关系 -->
<!--输出实体[OPPORTUNITY]外键关系 -->
<changeSet
author=
"a_LAB01_e85d8801c"
id=
"fk-opportunity-10
4
-408"
>
<changeSet
author=
"a_LAB01_e85d8801c"
id=
"fk-opportunity-10
6
-408"
>
<addForeignKeyConstraint
baseColumnNames=
"PARENTACCOUNTID"
baseTableName=
"OPPORTUNITY"
constraintName=
"DER1N_OPPORTUNITY__ACCOUNT__PA"
deferrable=
"false"
initiallyDeferred=
"false"
onDelete=
"RESTRICT"
onUpdate=
"RESTRICT"
referencedColumnNames=
"ACCOUNTID"
referencedTableName=
"ACCOUNT"
validate=
"true"
/>
</changeSet>
<changeSet
author=
"a_LAB01_e85d8801c"
id=
"fk-opportunity-10
4
-409"
>
<changeSet
author=
"a_LAB01_e85d8801c"
id=
"fk-opportunity-10
6
-409"
>
<addForeignKeyConstraint
baseColumnNames=
"CAMPAIGNID"
baseTableName=
"OPPORTUNITY"
constraintName=
"DER1N_OPPORTUNITY__CAMPAIGN__C"
deferrable=
"false"
initiallyDeferred=
"false"
onDelete=
"RESTRICT"
onUpdate=
"RESTRICT"
referencedColumnNames=
"CAMPAIGNID"
referencedTableName=
"CAMPAIGN"
validate=
"true"
/>
</changeSet>
<changeSet
author=
"a_LAB01_e85d8801c"
id=
"fk-opportunity-10
4
-410"
>
<changeSet
author=
"a_LAB01_e85d8801c"
id=
"fk-opportunity-10
6
-410"
>
<addForeignKeyConstraint
baseColumnNames=
"PARENTCONTACTID"
baseTableName=
"OPPORTUNITY"
constraintName=
"DER1N_OPPORTUNITY__CONTACT__PA"
deferrable=
"false"
initiallyDeferred=
"false"
onDelete=
"RESTRICT"
onUpdate=
"RESTRICT"
referencedColumnNames=
"CONTACTID"
referencedTableName=
"CONTACT"
validate=
"true"
/>
</changeSet>
<changeSet
author=
"a_LAB01_e85d8801c"
id=
"fk-opportunity-10
4
-411"
>
<changeSet
author=
"a_LAB01_e85d8801c"
id=
"fk-opportunity-10
6
-411"
>
<addForeignKeyConstraint
baseColumnNames=
"ORIGINATINGLEADID"
baseTableName=
"OPPORTUNITY"
constraintName=
"DER1N_OPPORTUNITY__LEAD__ORIGI"
deferrable=
"false"
initiallyDeferred=
"false"
onDelete=
"RESTRICT"
onUpdate=
"RESTRICT"
referencedColumnNames=
"LEADID"
referencedTableName=
"LEAD"
validate=
"true"
/>
</changeSet>
<changeSet
author=
"a_LAB01_e85d8801c"
id=
"fk-opportunity-10
4
-412"
>
<changeSet
author=
"a_LAB01_e85d8801c"
id=
"fk-opportunity-10
6
-412"
>
<addForeignKeyConstraint
baseColumnNames=
"PRICELEVELID"
baseTableName=
"OPPORTUNITY"
constraintName=
"DER1N_OPPORTUNITY__PRICELEVEL_"
deferrable=
"false"
initiallyDeferred=
"false"
onDelete=
"RESTRICT"
onUpdate=
"RESTRICT"
referencedColumnNames=
"PRICELEVELID"
referencedTableName=
"PRICELEVEL"
validate=
"true"
/>
</changeSet>
<changeSet
author=
"a_LAB01_e85d8801c"
id=
"fk-opportunity-10
4
-413"
>
<changeSet
author=
"a_LAB01_e85d8801c"
id=
"fk-opportunity-10
6
-413"
>
<addForeignKeyConstraint
baseColumnNames=
"SLAID"
baseTableName=
"OPPORTUNITY"
constraintName=
"DER1N_OPPORTUNITY__SLA__SLAID"
deferrable=
"false"
initiallyDeferred=
"false"
onDelete=
"RESTRICT"
onUpdate=
"RESTRICT"
referencedColumnNames=
"SLAID"
referencedTableName=
"SLA"
validate=
"true"
/>
</changeSet>
<changeSet
author=
"a_LAB01_e85d8801c"
id=
"fk-opportunity-10
4
-414"
>
<changeSet
author=
"a_LAB01_e85d8801c"
id=
"fk-opportunity-10
6
-414"
>
<addForeignKeyConstraint
baseColumnNames=
"TRANSACTIONCURRENCYID"
baseTableName=
"OPPORTUNITY"
constraintName=
"DER1N_OPPORTUNITY__TRANSACTION"
deferrable=
"false"
initiallyDeferred=
"false"
onDelete=
"RESTRICT"
onUpdate=
"RESTRICT"
referencedColumnNames=
"TRANSACTIONCURRENCYID"
referencedTableName=
"TRANSACTIONCURRENCY"
validate=
"true"
/>
</changeSet>
<!--输出实体[OPPORTUNITYCOMPETITOR]外键关系 -->
...
...
编辑
预览
Markdown
格式
0%
请重试
or
添加新附件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
先完成此消息的编辑!
取消
想要评论请
注册
或
登录