|
|
@@ -82,37 +82,36 @@
|
|
|
</el-card>
|
|
|
|
|
|
<el-card shadow="never" class="phases">
|
|
|
- <el-collapse v-model="activeNames" accordion>
|
|
|
- <el-collapse-item title="1期绑定门店" :name="1">
|
|
|
- <el-form-item prop="contractStoreList" class="form-item-choose-contract">
|
|
|
- <contract-store-choose
|
|
|
- v-for="(item, index) in formData.contractStoreList"
|
|
|
- v-model="formData.contractStoreList[index]"
|
|
|
- :index="index"
|
|
|
- :key="index"
|
|
|
- @remove="removeContractStore"
|
|
|
- ref="contractStoreChoose"
|
|
|
- :checkInType="formData.checkInType"
|
|
|
- :storeOptions="storeOptions"
|
|
|
- ></contract-store-choose>
|
|
|
- </el-form-item>
|
|
|
- </el-collapse-item>
|
|
|
- <el-collapse-item title="反馈 Feedback" name="2">
|
|
|
- <div>控制反馈:通过界面样式和交互动效让用户可以清晰的感知自己的操作;</div>
|
|
|
- <div>页面反馈:操作后,通过页面元素的变化清晰地展现当前状态。</div>
|
|
|
- </el-collapse-item>
|
|
|
- <el-collapse-item title="效率 Efficiency" name="3">
|
|
|
- <div>简化流程:设计简洁直观的操作流程;</div>
|
|
|
- <div>清晰明确:语言表达清晰且表意明确,让用户快速理解进而作出决策;</div>
|
|
|
- <div>帮助用户识别:界面简单直白,让用户快速识别而非回忆,减少用户记忆负担。</div>
|
|
|
- </el-collapse-item>
|
|
|
- <el-collapse-item title="可控 Controllability" name="4">
|
|
|
- <div>用户决策:根据场景可给予用户操作建议或安全提示,但不能代替用户进行决策;</div>
|
|
|
- <div>结果可控:用户可以自由的进行操作,包括撤销、回退和终止当前操作等。</div>
|
|
|
+ <el-collapse accordion v-model="activeTab">
|
|
|
+ <el-collapse-item :name="index" v-for="(item, index) in formData.phases" :key="index">
|
|
|
+ <template slot="title">
|
|
|
+ {{ toChinesNum(index + 1) }}期绑定门店
|
|
|
+ <el-button
|
|
|
+ v-if="activeTab === index"
|
|
|
+ @click.stop="addPhaseStore(index)"
|
|
|
+ type="primary"
|
|
|
+ plain
|
|
|
+ size="mini"
|
|
|
+ style="margin-left:10px"
|
|
|
+ >
|
|
|
+ 新增门店
|
|
|
+ </el-button>
|
|
|
+ <span class="phase-time">{{ item.startTime }} 至 {{ item.endTime }}</span>
|
|
|
+ </template>
|
|
|
+ <contract-store-choose
|
|
|
+ v-for="(item, storeIdx) in item.stores"
|
|
|
+ v-model="formData.phases[index].stores[storeIdx]"
|
|
|
+ :index="storeIdx"
|
|
|
+ :key="storeIdx"
|
|
|
+ @remove="removePhaseStore(index, $event)"
|
|
|
+ ref="contractStoreChoose"
|
|
|
+ :checkInType="formData.checkInType"
|
|
|
+ :storeOptions="storeOptions"
|
|
|
+ ></contract-store-choose>
|
|
|
</el-collapse-item>
|
|
|
</el-collapse>
|
|
|
|
|
|
- <el-button class="btn-add-phase">添加合同期</el-button>
|
|
|
+ <el-button class="btn-add-phase" @click="onAddPhase">添加合同期</el-button>
|
|
|
</el-card>
|
|
|
|
|
|
<el-card shadow="never">
|
|
|
@@ -429,6 +428,42 @@
|
|
|
<el-button @click="submit" type="primary">确认</el-button>
|
|
|
</span>
|
|
|
</el-dialog>
|
|
|
+ <el-dialog :visible.sync="showPhaseDialog" title="新增周期" width="400px">
|
|
|
+ <el-form
|
|
|
+ :model="phaseForm"
|
|
|
+ ref="phaseForm"
|
|
|
+ label-width="80px"
|
|
|
+ label-position="right"
|
|
|
+ :rules="phaseFormRules"
|
|
|
+ size="small"
|
|
|
+ >
|
|
|
+ <el-form-item prop="startTime" label="开始时间">
|
|
|
+ <el-date-picker
|
|
|
+ v-model="phaseForm.startTime"
|
|
|
+ type="datetime"
|
|
|
+ value-format="yyyy-MM-dd HH:mm:ss"
|
|
|
+ placeholder="请选择"
|
|
|
+ :disabled="phaseForm.disableStart"
|
|
|
+ ></el-date-picker>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item prop="months" label="月份">
|
|
|
+ <el-input-number v-model="phaseForm.months" controls-position="right" :min="1"></el-input-number>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item prop="endTime" label="结束时间">
|
|
|
+ <el-date-picker
|
|
|
+ v-model="phaseForm.endTime"
|
|
|
+ type="datetime"
|
|
|
+ value-format="yyyy-MM-dd HH:mm:ss"
|
|
|
+ placeholder="请选择"
|
|
|
+ disabled
|
|
|
+ ></el-date-picker>
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+ <span slot="footer">
|
|
|
+ <el-button @click="showPhaseDialog = false">取 消</el-button>
|
|
|
+ <el-button @click="addPhase" type="primary">确 定</el-button>
|
|
|
+ </span>
|
|
|
+ </el-dialog>
|
|
|
</div>
|
|
|
</template>
|
|
|
<script>
|
|
|
@@ -526,7 +561,7 @@ export default {
|
|
|
this.lastFlowBet = res.content[0].flowBet;
|
|
|
});
|
|
|
}
|
|
|
- this.formData = { ...res };
|
|
|
+ this.formData = { ...res, phases: res.phases || [] };
|
|
|
this.$nextTick(_ => {
|
|
|
console.log(res.flowBet);
|
|
|
this.formData.flowBet = res.flowBet;
|
|
|
@@ -579,7 +614,8 @@ export default {
|
|
|
contractEndTime: '',
|
|
|
isInvoice: false,
|
|
|
brandId: null,
|
|
|
- status: 'STAY_IN'
|
|
|
+ status: 'STAY_IN',
|
|
|
+ phases: []
|
|
|
},
|
|
|
lastFlowBet: 0,
|
|
|
rules: {
|
|
|
@@ -673,51 +709,20 @@ export default {
|
|
|
},
|
|
|
storeOptions: [],
|
|
|
invoiceType: [
|
|
|
- {
|
|
|
- value: 'SPECIAL',
|
|
|
- label: '专票'
|
|
|
- },
|
|
|
- {
|
|
|
- value: 'GENERAL',
|
|
|
- label: '普票'
|
|
|
- },
|
|
|
- {
|
|
|
- value: 'RECEIPT',
|
|
|
- label: '收据'
|
|
|
- }
|
|
|
+ { value: 'SPECIAL', label: '专票' },
|
|
|
+ { value: 'GENERAL', label: '普票' },
|
|
|
+ { value: 'RECEIPT', label: '收据' }
|
|
|
],
|
|
|
CheckinTypeOptions: [
|
|
|
- {
|
|
|
- value: 'TEAM',
|
|
|
- label: '团队包房'
|
|
|
- },
|
|
|
- {
|
|
|
- value: 'SCATTERED_BEDS',
|
|
|
- label: '团队床位'
|
|
|
- },
|
|
|
- {
|
|
|
- value: 'TEAM_POST_PAID',
|
|
|
- label: '团散'
|
|
|
- }
|
|
|
- // ,
|
|
|
- // {
|
|
|
- // value: 'INDIVIDUAL',
|
|
|
- // label: '散客'
|
|
|
- // }
|
|
|
+ { value: 'TEAM', label: '团队包房' },
|
|
|
+ { value: 'SCATTERED_BEDS', label: '团队床位' },
|
|
|
+ { value: 'TEAM_POST_PAID', label: '团散' }
|
|
|
+ // ,{ value: 'INDIVIDUAL', label: '散客' }
|
|
|
],
|
|
|
ContractSourceType: [
|
|
|
- {
|
|
|
- value: 'NEW_SIGN',
|
|
|
- label: '新签'
|
|
|
- },
|
|
|
- {
|
|
|
- value: 'RENEWAL',
|
|
|
- label: '续签'
|
|
|
- },
|
|
|
- {
|
|
|
- value: 'ADD_ROOM',
|
|
|
- label: '加房'
|
|
|
- }
|
|
|
+ { value: 'NEW_SIGN', label: '新签' },
|
|
|
+ { value: 'RENEWAL', label: '续签' },
|
|
|
+ { value: 'ADD_ROOM', label: '加房' }
|
|
|
],
|
|
|
departmentGroup: [],
|
|
|
saleUser: [],
|
|
|
@@ -725,20 +730,11 @@ export default {
|
|
|
searchingCustomer: false,
|
|
|
brandOptions: [],
|
|
|
sourceData: [
|
|
|
- {
|
|
|
- value: 'NETWORK',
|
|
|
- label: '网络推广(58同城、赶集网、百姓网、贝壳租房、搜房网,其它)'
|
|
|
- },
|
|
|
- {
|
|
|
- value: 'PLATFORM',
|
|
|
- label: '平台推广(嗨住、巴乐兔、平安好房、蘑菇租房、其它)'
|
|
|
- },
|
|
|
+ { value: 'NETWORK', label: '网络推广(58同城、赶集网、百姓网、贝壳租房、搜房网,其它)' },
|
|
|
+ { value: 'PLATFORM', label: '平台推广(嗨住、巴乐兔、平安好房、蘑菇租房、其它)' },
|
|
|
{ value: 'TELEPHONE', label: '电话陌拜' },
|
|
|
{ value: 'GROUND_PUSH', label: '地推陌拜' },
|
|
|
- {
|
|
|
- value: 'WORD_MOUTH',
|
|
|
- label: '口碑推荐(老客户推荐、朋友推荐)'
|
|
|
- },
|
|
|
+ { value: 'WORD_MOUTH', label: '口碑推荐(老客户推荐、朋友推荐)' },
|
|
|
{ value: 'PEE', label: '中介同行' },
|
|
|
{ value: 'DOOR', label: '上门咨询' },
|
|
|
{ value: 'DOWN', label: '公司下发' },
|
|
|
@@ -751,7 +747,15 @@ export default {
|
|
|
{ value: 'RETREAT', label: '已退' }
|
|
|
],
|
|
|
renewal: false,
|
|
|
- curentPhaseId: 1
|
|
|
+ curentPhaseId: 1,
|
|
|
+ showPhaseDialog: false,
|
|
|
+ phaseForm: {},
|
|
|
+ phaseFormRules: {
|
|
|
+ startTime: [{ required: true, message: '请选择开始时间', trigger: 'blur' }],
|
|
|
+ endTime: [{ required: true, message: '请选择结束时间', trigger: 'blur' }],
|
|
|
+ months: [{ required: true, message: '请输入月份', trigger: 'blur' }]
|
|
|
+ },
|
|
|
+ activeTab: 0
|
|
|
};
|
|
|
},
|
|
|
computed: {
|
|
|
@@ -803,6 +807,24 @@ export default {
|
|
|
if (!isNaN(Number(this.formData.monthlyRent)) && !isNaN(Number(this.formData.bet))) {
|
|
|
this.$set(this.formData, 'flowBet', Number(this.formData.monthlyRent) * Number(this.formData.bet));
|
|
|
}
|
|
|
+ },
|
|
|
+ 'phaseForm.startTime'() {
|
|
|
+ if (this.phaseForm.startTime && this.phaseForm.months) {
|
|
|
+ this.$set(
|
|
|
+ this.phaseForm,
|
|
|
+ 'endTime',
|
|
|
+ formatDate(addMonths(parseDate(this.phaseForm.startTime), this.phaseForm.months))
|
|
|
+ );
|
|
|
+ }
|
|
|
+ },
|
|
|
+ 'phaseForm.months'() {
|
|
|
+ if (this.phaseForm.startTime && this.phaseForm.months) {
|
|
|
+ this.$set(
|
|
|
+ this.phaseForm,
|
|
|
+ 'endTime',
|
|
|
+ formatDate(addSeconds(addMonths(parseDate(this.phaseForm.startTime), this.phaseForm.months), -1))
|
|
|
+ );
|
|
|
+ }
|
|
|
}
|
|
|
},
|
|
|
methods: {
|
|
|
@@ -1036,9 +1058,9 @@ export default {
|
|
|
.then(res => {
|
|
|
this.formData.contractStoreList.push({
|
|
|
storeId: '',
|
|
|
- personalFeeTypes: [],
|
|
|
+ freeFeeTypes: [],
|
|
|
roomTypeInfo: [],
|
|
|
- deductions: [],
|
|
|
+ fixedFeeTypes: [],
|
|
|
roomTypes: []
|
|
|
});
|
|
|
this.$nextTick(() => {
|
|
|
@@ -1057,9 +1079,43 @@ export default {
|
|
|
}
|
|
|
});
|
|
|
},
|
|
|
+ addPhaseStore(index) {
|
|
|
+ Promise.all([
|
|
|
+ ...(this.$refs.contractStoreChoose || []).map(ref => {
|
|
|
+ return ref.valid();
|
|
|
+ })
|
|
|
+ ])
|
|
|
+ .then(res => {
|
|
|
+ this.formData.phases[index].stores.push({
|
|
|
+ storeId: '',
|
|
|
+ freeFeeTypes: [],
|
|
|
+ roomTypeInfo: [],
|
|
|
+ fixedFeeTypes: [],
|
|
|
+ roomTypes: []
|
|
|
+ });
|
|
|
+ this.$nextTick(() => {
|
|
|
+ document
|
|
|
+ .querySelector('.phases .el-collapse-item__wrap')
|
|
|
+ .scrollTo({ left: 100000, behavior: 'smooth' });
|
|
|
+ });
|
|
|
+ })
|
|
|
+ .catch(e => {
|
|
|
+ console.log(11111, e);
|
|
|
+ for (let vm of this.$refs.contractStoreChoose || []) {
|
|
|
+ if (vm.hasError) {
|
|
|
+ document
|
|
|
+ .querySelector('.phases .el-collapse-item__wrap')
|
|
|
+ .scrollTo({ left: 100000, behavior: 'smooth' });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ },
|
|
|
removeContractStore(index) {
|
|
|
this.formData.contractStoreList.splice(index, 1);
|
|
|
},
|
|
|
+ removePhaseStore(idx0, idx1) {
|
|
|
+ this.formData.phases[idx0].stores.splice(idx1, 1);
|
|
|
+ },
|
|
|
// changeSaleInfo(dId) {
|
|
|
// let lable = this.departmentGroup.filter(i => {
|
|
|
// return i.id === dId;
|
|
|
@@ -1115,18 +1171,6 @@ export default {
|
|
|
})[0];
|
|
|
return label;
|
|
|
},
|
|
|
-
|
|
|
- getSaleUser() {
|
|
|
- this.$http
|
|
|
- .get(`/contract/get/${this.$route.query.id}`)
|
|
|
- .then(res => {
|
|
|
- this.formData = res;
|
|
|
- })
|
|
|
- .catch(e => {
|
|
|
- console.log(e);
|
|
|
- this.$message.error(e.error);
|
|
|
- });
|
|
|
- },
|
|
|
onSave() {
|
|
|
this.$refs.form.validate(valid => {
|
|
|
if (valid) {
|
|
|
@@ -1227,6 +1271,53 @@ export default {
|
|
|
m = (r1.split('.')[1] ? r1.split('.')[1].length : 0) + (r2.split('.')[1] ? r2.split('.')[1].length : 0);
|
|
|
resultVal = (Number(r1.replace('.', '')) * Number(r2.replace('.', ''))) / Math.pow(10, m);
|
|
|
return typeof d !== 'number' ? Number(resultVal) : Number(resultVal.toFixed(parseInt(d)));
|
|
|
+ },
|
|
|
+ onAddPhase() {
|
|
|
+ if (this.formData.phases.length === 0) {
|
|
|
+ this.phaseForm = {};
|
|
|
+ } else {
|
|
|
+ this.phaseForm = {
|
|
|
+ startTime: formatDate(
|
|
|
+ addSeconds(parseDate(this.formData.phases[this.formData.phases.length - 1].endTime), 1)
|
|
|
+ ),
|
|
|
+ disableStart: true
|
|
|
+ };
|
|
|
+ }
|
|
|
+ this.showPhaseDialog = true;
|
|
|
+ },
|
|
|
+ addPhase() {
|
|
|
+ this.$refs.phaseForm.validate(valid => {
|
|
|
+ if (valid) {
|
|
|
+ this.formData.phases.push({ ...this.phaseForm, stores: [] });
|
|
|
+ this.showPhaseDialog = false;
|
|
|
+ this.activeTab = this.formData.phases.length - 1;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ },
|
|
|
+ toChinesNum(num) {
|
|
|
+ let changeNum = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九']; //changeNum[0] = "零"
|
|
|
+ let unit = ['', '十', '百', '千', '万'];
|
|
|
+ num = parseInt(num);
|
|
|
+ let getWan = temp => {
|
|
|
+ let strArr = temp
|
|
|
+ .toString()
|
|
|
+ .split('')
|
|
|
+ .reverse();
|
|
|
+ let newNum = '';
|
|
|
+ for (var i = 0; i < strArr.length; i++) {
|
|
|
+ newNum =
|
|
|
+ (i == 0 && strArr[i] == 0
|
|
|
+ ? ''
|
|
|
+ : i > 0 && strArr[i] == 0 && strArr[i - 1] == 0
|
|
|
+ ? ''
|
|
|
+ : changeNum[strArr[i]] + (strArr[i] == 0 ? unit[0] : unit[i])) + newNum;
|
|
|
+ }
|
|
|
+ return newNum;
|
|
|
+ };
|
|
|
+ let overWan = Math.floor(num / 10000);
|
|
|
+ let noWan = num % 10000;
|
|
|
+ if (noWan.toString().length < 4) noWan = '0' + noWan;
|
|
|
+ return overWan ? getWan(overWan) + '万' + getWan(noWan) : getWan(num);
|
|
|
}
|
|
|
},
|
|
|
components: {
|
|
|
@@ -1335,37 +1426,14 @@ export default {
|
|
|
margin-left: 20px;
|
|
|
}
|
|
|
}
|
|
|
+.phase-time {
|
|
|
+ color: @text3;
|
|
|
+ flex-grow: 1;
|
|
|
+ text-align: right;
|
|
|
+ padding-right: 20px;
|
|
|
+}
|
|
|
</style>
|
|
|
<style lang="less">
|
|
|
-.stepInfo {
|
|
|
- .el-table {
|
|
|
- tr,
|
|
|
- td,
|
|
|
- th {
|
|
|
- background: transparent;
|
|
|
- }
|
|
|
- }
|
|
|
- .bill-money {
|
|
|
- .el-input__inner {
|
|
|
- padding: 0 10px;
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-.el-input__inner[type='number'] {
|
|
|
- padding-right: 0;
|
|
|
-}
|
|
|
-.form-item-choose-contract {
|
|
|
- width: 100%;
|
|
|
- margin: 0 !important;
|
|
|
- > .el-form-item__content {
|
|
|
- white-space: nowrap;
|
|
|
- overflow-x: scroll;
|
|
|
- > .el-form-item__error {
|
|
|
- top: inherit;
|
|
|
- bottom: 0;
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
.contract-edit {
|
|
|
margin: 0;
|
|
|
padding: 15px;
|
|
|
@@ -1439,5 +1507,44 @@ export default {
|
|
|
.btn-add-phase {
|
|
|
margin: 10px 0 10px 0;
|
|
|
}
|
|
|
+ .stepInfo {
|
|
|
+ .el-table {
|
|
|
+ tr,
|
|
|
+ td,
|
|
|
+ th {
|
|
|
+ background: transparent;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .bill-money {
|
|
|
+ .el-input__inner {
|
|
|
+ padding: 0 10px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .el-input__inner[type='number'] {
|
|
|
+ padding-right: 0;
|
|
|
+ }
|
|
|
+ .form-item-choose-contract {
|
|
|
+ width: 100%;
|
|
|
+ margin: 0 !important;
|
|
|
+ > .el-form-item__content {
|
|
|
+ white-space: nowrap;
|
|
|
+ overflow-x: scroll;
|
|
|
+ > .el-form-item__error {
|
|
|
+ top: inherit;
|
|
|
+ bottom: 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .phases {
|
|
|
+ .el-collapse-item__wrap {
|
|
|
+ white-space: nowrap;
|
|
|
+ overflow-x: scroll;
|
|
|
+ > .el-form-item__error {
|
|
|
+ top: inherit;
|
|
|
+ bottom: 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
</style>
|