Commit 70369de3ef8086f5707e02f3830508030ddfd975

Authored by 史婷婷
1 parent 7bedc532

feat: 客户信息-新增

@@ -5,7 +5,7 @@ import { getToken } from '@/utils/auth' @@ -5,7 +5,7 @@ import { getToken } from '@/utils/auth'
5 5
6 6
7 /** 7 /**
8 - * 根据编号获取数据字段 8 + * 根据字典编号获取数据字段
9 * @param code 9 * @param code
10 */ 10 */
11 export function getDicByCodeApi(code) { 11 export function getDicByCodeApi(code) {
@@ -41,11 +41,26 @@ export function selectorCityApi() { @@ -41,11 +41,26 @@ export function selectorCityApi() {
41 }) 41 })
42 } 42 }
43 /** 43 /**
44 - * 回去城市接口 省市区 一次性返回 44 + * 获取菜单
45 */ 45 */
46 export function getMenusApi() { 46 export function getMenusApi() {
47 return request({ 47 return request({
48 url: `/auth/menus`, 48 url: `/auth/menus`,
49 method: 'get' 49 method: 'get'
50 }) 50 })
  51 +}
  52 +
  53 +/**
  54 + * 生成编号
  55 + * @param type
  56 + * 客户池编号 5
  57 + */
  58 +export function generateCodeApi(type) {
  59 + return request({
  60 + url: `/component/generate/code`,
  61 + method: 'get',
  62 + params: {
  63 + type
  64 + },
  65 + })
51 } 66 }
@@ -114,6 +114,14 @@ @@ -114,6 +114,14 @@
114 } 114 }
115 }, 115 },
116 { 116 {
  117 + "path": "pages/customer/add",
  118 + "style": {
  119 + "navigationBarTitleText": "新增客户信息",
  120 + "navigationBarBackgroundColor": "#ffffff",
  121 + "navigationBarTextStyle": "black"
  122 + }
  123 + },
  124 + {
117 "path": "pages/credit_manage/index", 125 "path": "pages/credit_manage/index",
118 "style": { 126 "style": {
119 "navigationBarTitleText": "客户资信管理", 127 "navigationBarTitleText": "客户资信管理",
  1 +<template>
  2 + <view class="page">
  3 + <scroll-view class="scroll" scroll-y>
  4 + <uni-list>
  5 + <uni-list-item class="select-item" :class="form.code ? 'is-filled' : 'is-empty'">
  6 + <template v-slot:body>
  7 + <view class="item-title"><text class="required">*</text><text>编号</text></view>
  8 + </template>
  9 + <template v-slot:footer>
  10 + <view class="serial-number-row">
  11 + <uni-easyinput v-model="form.code" placeholder="自动生成编号" :inputBorder="false" disabled />
  12 + <button class="generate-btn" @click="loadCode">点此生成</button>
  13 + </view>
  14 + </template>
  15 + </uni-list-item>
  16 +
  17 + <uni-list-item title="名称">
  18 + <template v-slot:body>
  19 + <view class="item-title"><text class="required">*</text><text>名称</text></view>
  20 + </template>
  21 + <template v-slot:footer>
  22 + <uni-easyinput v-model="form.name" placeholder="请输入名称" :inputBorder="false" />
  23 + </template>
  24 + </uni-list-item>
  25 +
  26 + <uni-list-item title="联系人">
  27 + <template v-slot:footer>
  28 + <uni-easyinput v-model="form.contact" placeholder="请输入联系人" :inputBorder="false" />
  29 + </template>
  30 + </uni-list-item>
  31 +
  32 + <uni-list-item title="联系电话">
  33 + <template v-slot:footer>
  34 + <uni-easyinput v-model="form.telephone" placeholder="请输入联系电话" :inputBorder="false" />
  35 + </template>
  36 + </uni-list-item>
  37 +
  38 + <uni-list-item title="电子邮箱">
  39 + <template v-slot:footer>
  40 + <uni-easyinput v-model="form.email" placeholder="请输入电子邮箱" :inputBorder="false" />
  41 + </template>
  42 + </uni-list-item>
  43 +
  44 + <uni-list-item title="邮编">
  45 + <template v-slot:footer>
  46 + <uni-easyinput v-model="form.zipCode" placeholder="请输入邮编" :inputBorder="false" />
  47 + </template>
  48 + </uni-list-item>
  49 +
  50 + <uni-list-item title="传真">
  51 + <template v-slot:footer>
  52 + <uni-easyinput v-model="form.fax" placeholder="请输入传真" :inputBorder="false" />
  53 + </template>
  54 + </uni-list-item>
  55 +
  56 + <uni-list-item class="select-item"
  57 + :class="(Array.isArray(form.cityIds) && form.cityIds.length) ? 'is-filled' : 'is-empty'" clickable
  58 + @click="openCitySelector" :rightText="form.cityLabel || '请选择'" showArrow>
  59 + <template v-slot:body>
  60 + <view class="item-title"><text>地区</text></view>
  61 + <CitySelector ref="citySelectorRef" v-model="form.cityIds" @change="onCityChange" />
  62 + </template>
  63 + </uni-list-item>
  64 +
  65 + <uni-list-item title="地址">
  66 + <template v-slot:footer>
  67 + <uni-easyinput v-model="form.address" placeholder="请输入地址" :inputBorder="false" />
  68 + </template>
  69 + </uni-list-item>
  70 +
  71 + <uni-list-item title="统一社会信用代码">
  72 + <template v-slot:footer>
  73 + <uni-easyinput v-model="form.creditCode" placeholder="请输入统一社会信用代码" :inputBorder="false" />
  74 + </template>
  75 + </uni-list-item>
  76 +
  77 + <uni-list-item title="纳税人识别号">
  78 + <template v-slot:footer>
  79 + <uni-easyinput v-model="form.taxIdentifyNo" placeholder="请输入纳税人识别号" :inputBorder="false" />
  80 + </template>
  81 + </uni-list-item>
  82 +
  83 + <uni-list-item title="开户银行">
  84 + <template v-slot:footer>
  85 + <uni-easyinput v-model="form.bankName" placeholder="请输入开户银行" :inputBorder="false" />
  86 + </template>
  87 + </uni-list-item>
  88 +
  89 + <uni-list-item title="户名">
  90 + <template v-slot:footer>
  91 + <uni-easyinput v-model="form.accountName" placeholder="请输入户名" :inputBorder="false" />
  92 + </template>
  93 + </uni-list-item>
  94 +
  95 + <uni-list-item title="银行账号">
  96 + <template v-slot:footer>
  97 + <uni-easyinput v-model="form.accountNo" placeholder="请输入银行账号" :inputBorder="false" />
  98 + </template>
  99 + </uni-list-item>
  100 +
  101 + <uni-list-item title="备注">
  102 + <template v-slot:footer>
  103 + <uni-easyinput type="textarea" v-model="form.description" placeholder="请输入备注" :inputBorder="false" />
  104 + </template>
  105 + </uni-list-item>
  106 +
  107 + </uni-list>
  108 + </scroll-view>
  109 +
  110 + <view class="footer">
  111 + <button class="btn submit" type="primary" @click="onSubmit">提交</button>
  112 + </view>
  113 + </view>
  114 +</template>
  115 +
  116 +<script>
  117 +import { createApi } from '@/api/customer.js'
  118 +import { generateCodeApi } from '@/api/base.js'
  119 +import CitySelector from '@/components/city-selector/index.vue'
  120 +import { isEmail } from '@/utils/common.js'
  121 +
  122 +export default {
  123 + name: 'CustomerAdd',
  124 + components: { CitySelector },
  125 + data() {
  126 + return {
  127 + form: {
  128 + code: '',
  129 + name: '',
  130 + contact: '',
  131 + telephone: '',
  132 + email: '',
  133 + zipCode: '',
  134 + fax: '',
  135 + cityIds: [],
  136 + cityLabel: '',
  137 + address: '',
  138 + creditCode: '',
  139 + taxIdentifyNo: '',
  140 + bankName: '',
  141 + accountName: '',
  142 + accountNo: '',
  143 + description: ''
  144 + }
  145 + }
  146 + },
  147 + created() {
  148 + this.loadCode()
  149 + },
  150 + methods: {
  151 + async loadCode() {
  152 + try {
  153 + const res = await generateCodeApi(5)
  154 + this.form.code = (res && res.data) || ''
  155 + } catch (e) {
  156 + this.form.code = ''
  157 + }
  158 + },
  159 + openCitySelector() {
  160 + this.$refs.citySelectorRef && this.$refs.citySelectorRef.open()
  161 + },
  162 + onCityChange(payload) {
  163 + const label = payload && payload.label != null ? payload.label : ''
  164 + this.form.cityLabel = label
  165 + },
  166 + validateRequired() {
  167 + if (!this.form.code) {
  168 + uni.showToast({ title: '请先生成编号', icon: 'none' })
  169 + return false
  170 + }
  171 + if (!this.form.name || !this.form.name.trim()) {
  172 + uni.showToast({ title: '请输入名称', icon: 'none' })
  173 + return false
  174 + }
  175 + if (this.form.email && !isEmail(this.form.email)) {
  176 + uni.showToast({ title: '邮箱地址格式不正确', icon: 'none' })
  177 + return false
  178 + }
  179 + return true
  180 + },
  181 + async onSubmit() {
  182 + if (!this.validateRequired()) return
  183 +
  184 + const { cityIds, cityLabel, ...other } = this.form
  185 + // 取最后一个 ID 作为 city
  186 + const cityId = cityIds && cityIds.length > 0 ? cityIds[cityIds.length - 1] : ''
  187 +
  188 + const payload = {
  189 + ...other,
  190 + cityId
  191 + }
  192 +
  193 + console.log('onSubmit payload', payload)
  194 + try {
  195 + await createApi(payload)
  196 + uni.showToast({ title: '提交成功', icon: 'success' })
  197 + setTimeout(() => { uni.redirectTo({ url: '/pages/customer/index' }) }, 300)
  198 + } catch (e) {
  199 + uni.showToast({ title: (e && e.msg) || '提交失败', icon: 'none' })
  200 + }
  201 + }
  202 + }
  203 +}
  204 +</script>
  205 +
  206 +<style lang="scss" scoped>
  207 +.page {
  208 + display: flex;
  209 + flex-direction: column;
  210 + height: 100vh;
  211 +}
  212 +
  213 +.scroll {
  214 + flex: 1;
  215 + padding: 12rpx 0 160rpx;
  216 +}
  217 +
  218 +.footer {
  219 + position: fixed;
  220 + left: 0;
  221 + right: 0;
  222 + bottom: 0;
  223 + padding: 32rpx;
  224 + padding-bottom: calc(32rpx + env(safe-area-inset-bottom));
  225 + background: #fff;
  226 + box-shadow: 0 -8rpx 24rpx rgba(0, 0, 0, 0.06);
  227 + z-index: 10;
  228 +
  229 + .btn {
  230 + height: 80rpx;
  231 + line-height: 80rpx;
  232 + border-radius: 12rpx;
  233 + font-size: 32rpx;
  234 + }
  235 +
  236 + .submit {
  237 + background: $theme-primary;
  238 + color: #fff;
  239 + }
  240 +}
  241 +
  242 +::v-deep .uni-list {
  243 + background: transparent;
  244 +
  245 + &-item {
  246 + &__extra-text {
  247 + font-size: 32rpx;
  248 + }
  249 +
  250 + &__content-title {
  251 + font-size: 32rpx;
  252 + color: rgba(0, 0, 0, 0.9);
  253 + }
  254 +
  255 + &__container {
  256 + padding: 32rpx;
  257 +
  258 + .uni-easyinput {
  259 + .is-disabled {
  260 + background-color: transparent !important;
  261 + }
  262 +
  263 + &__placeholder-class {
  264 + font-size: 32rpx;
  265 + color: rgba(0, 0, 0, 0.4);
  266 + }
  267 +
  268 + &__content {
  269 + border: none;
  270 +
  271 + &-input {
  272 + padding-left: 0 !important;
  273 + height: 48rpx;
  274 + line-height: 48rpx;
  275 + font-size: 32rpx;
  276 + }
  277 + }
  278 + }
  279 +
  280 + .item-title,
  281 + .uni-list-item__content {
  282 + flex: none;
  283 + min-height: 48rpx;
  284 + line-height: 48rpx;
  285 + font-size: 32rpx;
  286 + position: relative;
  287 + width: 210rpx;
  288 + margin-right: 32rpx;
  289 + color: rgba(0, 0, 0, 0.9);
  290 + padding-right: 0;
  291 +
  292 + .required {
  293 + color: red;
  294 + position: absolute;
  295 + top: 50%;
  296 + transform: translateY(-50%);
  297 + left: -16rpx;
  298 + }
  299 + }
  300 + }
  301 +
  302 + &.select-item {
  303 + &.is-empty {
  304 + .uni-list-item__extra-text {
  305 + color: rgba(0, 0, 0, 0.4) !important;
  306 + }
  307 + }
  308 +
  309 + &.is-filled {
  310 + .uni-list-item__extra-text {
  311 + color: rgba(0, 0, 0, 0.9) !important;
  312 + }
  313 + }
  314 +
  315 + .serial-number-row {
  316 + display: flex;
  317 + align-items: center;
  318 +
  319 + .generate-btn {
  320 + margin-left: 24rpx;
  321 + height: 64rpx;
  322 + line-height: 64rpx;
  323 + padding: 0 24rpx;
  324 + font-size: 28rpx;
  325 + border-radius: 8rpx;
  326 + background: $theme-primary;
  327 + color: #fff;
  328 + }
  329 + }
  330 + }
  331 + }
  332 +}
  333 +</style>
@@ -157,7 +157,7 @@ @@ -157,7 +157,7 @@
157 }, 157 },
158 onAdd() { 158 onAdd() {
159 uni.navigateTo({ 159 uni.navigateTo({
160 - url: '/pages/credit_manage/add' 160 + url: '/pages/customer/add'
161 }) 161 })
162 }, 162 },
163 openFilter() { 163 openFilter() {
@@ -106,4 +106,14 @@ export function formatCurrencyToChinese(num) { @@ -106,4 +106,14 @@ export function formatCurrencyToChinese(num) {
106 // 处理特殊情况(如"零元整"已在开头处理,此处处理多零情况) 106 // 处理特殊情况(如"零元整"已在开头处理,此处处理多零情况)
107 return str.replace(/零+/g, '零').replace(/零([万亿])/g, '$1').replace(/零元/, '元') 107 return str.replace(/零+/g, '零').replace(/零([万亿])/g, '$1').replace(/零元/, '元')
108 .replace(/零角零分$/, '整').replace(/零分$/, '整'); 108 .replace(/零角零分$/, '整').replace(/零分$/, '整');
109 -}  
  109 +}
  110 +
  111 +/**
  112 + * 校验邮箱格式
  113 + * @param email
  114 + * @returns {boolean}
  115 + */
  116 +export function isEmail(email) {
  117 + const reg = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
  118 + return reg.test(email);
  119 +}