对比新文件 |
| | |
| | | <template> |
| | | <div class="copy-textarea"> |
| | | <div> |
| | | <span style="color:red;">手动输入最多支持100个号码,大批量号码建议通过文件导入形式提交</span> |
| | | <el-button type="text" @click="clearVal">点击清空</el-button></div> |
| | | <el-input type="textarea" :rows="5" v-model="currentValue" |
| | | placeholder="提示:一行输入一个号码,多个手机号请换行隔开。" |
| | | width="80%" |
| | | @change="handlerInputChange" |
| | | ></el-input> |
| | | <div> |
| | | <span style="color:gray;">提示:一行输入一个号码,多个手机号请换行隔开。</span> |
| | | </div> |
| | | |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import cloneDeep from 'lodash.clonedeep' |
| | | export default { |
| | | props: { |
| | | value: { |
| | | type: String, |
| | | default:'', |
| | | }, |
| | | disabled: { |
| | | type: Boolean, |
| | | default: false, |
| | | }, |
| | | }, |
| | | data() { |
| | | return { |
| | | dialogVisible: false, |
| | | currentValue: '', |
| | | } |
| | | }, |
| | | watch: { |
| | | value: { |
| | | immediate: true, |
| | | handler(value) { |
| | | this.currentValue = value |
| | | }, |
| | | }, |
| | | }, |
| | | methods: { |
| | | clearVal(){ |
| | | this.$elBusUtil |
| | | .confirm('确定要清空吗?') |
| | | .then(() => { |
| | | this.currentValue = '' |
| | | this.$emit('input', '') |
| | | this.$emit('change', '') |
| | | }) |
| | | .catch(() => {}) |
| | | }, |
| | | handlerInputChange(){ |
| | | this.$emit('input', this.currentValue) |
| | | this.$emit('change', this.currentValue) |
| | | } |
| | | }, |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .copy-textarea { |
| | | } |
| | | </style> |
| | | <style lang="scss"> |
| | | .shop-user-dialog { |
| | | .dialog-container { |
| | | display: flex; |
| | | align-items: flex-start; |
| | | &__list { |
| | | flex: 1; |
| | | border-right: 1px solid #eee; |
| | | height: 100%; |
| | | } |
| | | &__selected { |
| | | width: 40%; |
| | | height: 100%; |
| | | padding: 24px; |
| | | .el-bus-title { |
| | | margin-bottom: 15px; |
| | | } |
| | | .el-tag { |
| | | margin-right: 6px; |
| | | margin-bottom: 6px; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | </style> |
对比新文件 |
| | |
| | | <template> |
| | | <div class="select-shop-user"> |
| | | <el-button v-if="!disabled" type="primary" @click="chooseUser">选择用户列表</el-button> |
| | | <el-table v-if="value && value.length > 0" :data="value"> |
| | | <el-table-column label="id" prop="id"></el-table-column> |
| | | <el-table-column label="名称" prop="loginName"></el-table-column> |
| | | <el-table-column label="注册手机号方式" prop="tel"></el-table-column> |
| | | <el-table-column v-if="!disabled" label="操作"> |
| | | <template #default="{ $index }"> |
| | | <text-button type="danger" @click="deleteUser($index)">删除</text-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | <el-dialog :visible.sync="dialogVisible" title="选择用户列表" append-to-body :close-on-click-modal="false" |
| | | custom-class="shop-user-dialog" width="80%"> |
| | | <div class="dialog-container"> |
| | | <div class="dialog-container__list"> |
| | | <el-bus-crud v-bind="tableConfig" /> |
| | | </div> |
| | | <div class="dialog-container__selected"> |
| | | <el-bus-title title="已添加用户" size="mini" /> |
| | | <el-tag v-for="(tag, i) in currentValue" :key="tag.id" closable @close="deleteCurrentUser(i)">{{ tag.loginName |
| | | }}</el-tag> |
| | | </div> |
| | | </div> |
| | | <div slot="footer"> |
| | | <el-button @click="cancel">取消</el-button> |
| | | <el-button type="primary" @click="confirm">确定</el-button> |
| | | </div> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import cloneDeep from 'lodash.clonedeep' |
| | | export default { |
| | | props: { |
| | | value: { |
| | | type: Array, |
| | | default: () => [], |
| | | }, |
| | | disabled: { |
| | | type: Boolean, |
| | | default: false, |
| | | }, |
| | | }, |
| | | data() { |
| | | return { |
| | | dialogVisible: false, |
| | | currentValue: [], |
| | | tableConfig: { |
| | | url: 'flower/api/user/user/list', |
| | | saveQuery: false, |
| | | hasNew: false, |
| | | hasEdit: false, |
| | | hasDelete: false, |
| | | hasView: false, |
| | | columns: [ |
| | | { type: 'selection' }, |
| | | { label: 'id', prop: 'id' }, |
| | | { label: '名称', prop: 'loginName' }, |
| | | { label: '注册手机号', prop: 'tel' }, |
| | | ], |
| | | extraButtons: [ |
| | | { |
| | | text: '选择', |
| | | show: (row) => |
| | | !this.currentValue.find((item) => item.id === row.id), |
| | | atClick: (row) => { |
| | | this.currentValue.push({ |
| | | id: row.id, |
| | | loginName: row.loginName, |
| | | tel: row.tel, |
| | | }) |
| | | return false |
| | | }, |
| | | }, |
| | | { |
| | | text: '取消选择', |
| | | show: (row) => this.currentValue.find((item) => item.id === row.id), |
| | | atClick: (row) => { |
| | | const index = this.currentValue.findIndex( |
| | | (item) => item.id === row.id |
| | | ) |
| | | this.currentValue.splice(index, 1) |
| | | return false |
| | | }, |
| | | }, |
| | | ], |
| | | headerButtons: [ |
| | | { |
| | | text: '批量选择', |
| | | type: 'primary', |
| | | disabled: (selected) => selected.length === 0, |
| | | atClick: (selected) => { |
| | | console.log(selected) |
| | | selected.forEach(item => { |
| | | // 检查 selected 数组的每个元素是否已在 currentValue 中 |
| | | if (!this.currentValue.some(currentItem => currentItem.id === item.id)) { |
| | | this.currentValue.push({ |
| | | id: item.id, |
| | | loginName: item.loginName, |
| | | tel: item.tel, |
| | | }) |
| | | } |
| | | }); |
| | | return true |
| | | }, |
| | | }, |
| | | { |
| | | text: '批量取消', |
| | | type: 'primary', |
| | | disabled: (selected) => selected.length === 0, |
| | | atClick: (selected) => { |
| | | selected.forEach(item => { |
| | | // 检查 selected 数组的每个元素是否存在于 currentValue 中 |
| | | const index = this.currentValue.findIndex(currentItem => currentItem.id === item.id); |
| | | if (index !== -1) { |
| | | this.currentValue.splice(index, 1); // 如果存在,则移除 |
| | | } |
| | | }); |
| | | return true |
| | | }, |
| | | }, |
| | | ], |
| | | |
| | | searchFormAttrs: { |
| | | labelWidth: 'auto', |
| | | }, |
| | | searchForm: [ |
| | | { |
| | | type: 'row', |
| | | span: 12, |
| | | items: [ |
| | | { |
| | | label: '列表类型:', |
| | | id: 'userType', |
| | | type: 'bus-select-dict', |
| | | el: { |
| | | code: 'USER_TYPE', |
| | | multiple: false, |
| | | style: 'width:100%', |
| | | }, |
| | | default: 'customer', |
| | | searchImmediately: true, |
| | | on: { |
| | | change: (e, updateForm, obj) => { |
| | | console.log(e[0]) |
| | | // if (e[0] === 'supplier') { |
| | | // this.tableConfig.url = 'flower/api/supplier/page' |
| | | // } else if (e[0] === 'partner') { |
| | | // this.tableConfig.url = 'flower/api/partner/page' |
| | | // }else if(e[0]==='customer'){ |
| | | // this.tableConfig.url = 'flower/api/customer/page' |
| | | // } |
| | | }, |
| | | }, |
| | | |
| | | }, |
| | | |
| | | { label: 'id:', id: 'id', type: 'input' }, |
| | | { label: '名称:', id: 'loginName', type: 'input' }, |
| | | { label: '注册手机号:', id: 'tel', type: 'input' }, |
| | | ], |
| | | }, |
| | | ], |
| | | }, |
| | | } |
| | | }, |
| | | watch: { |
| | | value: { |
| | | immediate: true, |
| | | handler(value) { |
| | | this.currentValue = cloneDeep(value || []) |
| | | }, |
| | | }, |
| | | }, |
| | | methods: { |
| | | handleSelectionChange(rows) { |
| | | console.log(rows) |
| | | alert("全选") |
| | | }, |
| | | chooseUser() { |
| | | this.currentValue = cloneDeep(this.value || []) |
| | | this.dialogVisible = true |
| | | }, |
| | | deleteCurrentUser(i) { |
| | | this.currentValue.splice(i, 1) |
| | | }, |
| | | deleteUser(i) { |
| | | this.$elBusUtil |
| | | .confirm('确定要删除吗?') |
| | | .then(() => { |
| | | const userList = cloneDeep(this.value || []) |
| | | userList.splice(i, 1) |
| | | this.$emit('input', userList) |
| | | this.$emit('change', userList) |
| | | }) |
| | | .catch(() => { }) |
| | | }, |
| | | confirm() { |
| | | this.$emit('input', this.currentValue) |
| | | this.$emit('change', this.currentValue) |
| | | this.dialogVisible = false |
| | | }, |
| | | cancel() { |
| | | this.dialogVisible = false |
| | | }, |
| | | }, |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .select-shop-user {} |
| | | </style> |
| | | <style lang="scss"> |
| | | .shop-user-dialog { |
| | | .dialog-container { |
| | | display: flex; |
| | | align-items: flex-start; |
| | | |
| | | &__list { |
| | | flex: 1; |
| | | border-right: 1px solid #eee; |
| | | height: 100%; |
| | | } |
| | | |
| | | &__selected { |
| | | width: 40%; |
| | | height: 100%; |
| | | padding: 24px; |
| | | |
| | | .el-bus-title { |
| | | margin-bottom: 15px; |
| | | } |
| | | |
| | | .el-tag { |
| | | margin-right: 6px; |
| | | margin-bottom: 6px; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | </style> |
对比新文件 |
| | |
| | | <template> |
| | | <div class="copy-textarea"> |
| | | <div> |
| | | <el-link href="https://hmy-flower.oss-cn-shanghai.aliyuncs.com/a5/a57ec65b165148e5a669e7766743e489template_phone.xlsx" download="template_phone.xlsx"> |
| | | <span style="color:#5FA7EE;">点击下载模板</span> |
| | | </el-link> |
| | | |
| | | <!-- <el-link @click="downloadTemplate">点击下载模板a</el-link> --> |
| | | </div> |
| | | |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import cloneDeep from 'lodash.clonedeep' |
| | | export default { |
| | | props: { |
| | | value: { |
| | | type: String, |
| | | default:'', |
| | | }, |
| | | disabled: { |
| | | type: Boolean, |
| | | default: false, |
| | | }, |
| | | }, |
| | | data() { |
| | | return { |
| | | dialogVisible: false, |
| | | currentValue: '', |
| | | } |
| | | }, |
| | | watch: { |
| | | value: { |
| | | immediate: true, |
| | | handler(value) { |
| | | this.currentValue = value |
| | | }, |
| | | }, |
| | | }, |
| | | methods: { |
| | | downloadTemplate() { |
| | | const link = document.createElement('a'); |
| | | link.href = 'https://hmy-flower.oss-cn-shanghai.aliyuncs.com/a5/a57ec65b165148e5a669e7766743e489template_phone.xlsx'; |
| | | link.download = 'template_phone.xlsx'; |
| | | link.click(); |
| | | } |
| | | }, |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .copy-textarea { |
| | | } |
| | | </style> |
| | | <style lang="scss"> |
| | | .shop-user-dialog { |
| | | .dialog-container { |
| | | display: flex; |
| | | align-items: flex-start; |
| | | &__list { |
| | | flex: 1; |
| | | border-right: 1px solid #eee; |
| | | height: 100%; |
| | | } |
| | | &__selected { |
| | | width: 40%; |
| | | height: 100%; |
| | | padding: 24px; |
| | | .el-bus-title { |
| | | margin-bottom: 15px; |
| | | } |
| | | .el-tag { |
| | | margin-right: 6px; |
| | | margin-bottom: 6px; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | </style> |
对比新文件 |
| | |
| | | <template> |
| | | <div class="base-page-wrapper coupon-detail"> |
| | | <el-bus-title title="基本信息" size="small" /> |
| | | <!-- <el-bus-form ref="form" label-width="auto" :content="formContent" readonly class="readonly-form" /> --> |
| | | <el-form ref="form" label-width="100px"> |
| | | <el-form-item label="模板名称:"> {{ statisticsData.smsTaskName || '' }} </el-form-item> |
| | | <el-form-item label="号码数量:"> {{ statisticsData.totalNum || 0 }} </el-form-item> |
| | | </el-form> |
| | | |
| | | <div class="base-page-wrapper__line"></div> |
| | | <el-bus-title title="发送结果" size="small" /> |
| | | <div><el-row :gutter="20"> |
| | | <el-col :span="3" class="mb-2"> |
| | | <el-card> |
| | | <div class="statistic-title">发送号码数量</div> |
| | | <div class="statistic-num">{{ statisticsData.totalNum || 0 }}</div> |
| | | </el-card> |
| | | </el-col> |
| | | <el-col :span="3" class="mb-2"> |
| | | <el-card> |
| | | <div class="statistic-title">成功</div> |
| | | <div class="statistic-num">{{ statisticsData.successNum || 0 }}</div> |
| | | </el-card> |
| | | </el-col> |
| | | <el-col :span="3" class="mb-2"> |
| | | <el-card> |
| | | <div class="statistic-title">失败</div> |
| | | <div class="statistic-num">{{ statisticsData.failureNum || 0 }}</div> |
| | | </el-card> |
| | | </el-col> |
| | | <el-col :span="3" class="mb-2"> |
| | | <el-card> |
| | | <div class="statistic-title">发送中</div> |
| | | <div class="statistic-num"> {{ statisticsData.sendingNum || 0 }} </div> |
| | | </el-card> |
| | | </el-col> |
| | | |
| | | </el-row></div> |
| | | <div class="base-page-wrapper__line"></div> |
| | | <el-bus-title title="发放记录" size="small" /> |
| | | <el-bus-crud v-bind="recordTableConfig" /> |
| | | <div class="text-center mt-20"> |
| | | <el-button class="min-w-100" @click="goBack">返回</el-button> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | export default { |
| | | data() { |
| | | return { |
| | | statisticsData:{}, |
| | | recordTableConfig: { |
| | | url: `flower/v2/sms-task-detail/list`, |
| | | hasOperation: false, |
| | | hasNew: false, |
| | | extraQuery: { |
| | | smsTaskId: this.$route.params.id, |
| | | }, |
| | | columns: [ |
| | | { label: '接收号码', prop: 'phone' }, |
| | | { label: '发送时间', prop: 'createTime' }, |
| | | { label: '发送结果', prop: 'resultStr' }, |
| | | { label: '失败原因', prop: 'failReason' }, |
| | | ], |
| | | searchForm: [ |
| | | { |
| | | type: 'row', |
| | | items: [ |
| | | { label: '接收号码', id: 'phone', type: 'input', searchImmediately: true, }, |
| | | { |
| | | label: '发送结果', |
| | | id: 'result', |
| | | type: 'bus-select-dict', |
| | | el: { |
| | | code: 'SMS_SEND_RESULT', |
| | | multiple: false, |
| | | style: 'width:100%', |
| | | clearable: true, |
| | | }, |
| | | searchImmediately: true, |
| | | }, |
| | | ], |
| | | }, |
| | | ], |
| | | }, |
| | | } |
| | | }, |
| | | head() { |
| | | return { |
| | | title: '批量发送短信详情', |
| | | } |
| | | }, |
| | | mounted() { |
| | | this.getInitData() |
| | | }, |
| | | methods: { |
| | | async getInitData() { |
| | | const { code, data } = await this.$elBusHttp.request( |
| | | `flower/v2/sms-task-detail/taskStatistics/${this.$route.params.id}`, |
| | | { |
| | | method: 'get', |
| | | // params: { |
| | | // id: this.$route.params.id |
| | | // } |
| | | } |
| | | ) |
| | | if (code === 0) { |
| | | console.log("data") |
| | | console.log(data) |
| | | this.statisticsData = data |
| | | } |
| | | }, |
| | | }, |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | @import '@/assets/coupon/detail.scss'; |
| | | @import '@/assets/statistic/index.scss'; |
| | | |
| | | .statistic-title { |
| | | text-align: center; |
| | | font-size: 16px; |
| | | color: $main-title-color; |
| | | font-weight: bold; |
| | | margin-bottom: 6px; |
| | | } |
| | | |
| | | .statistic-num { |
| | | text-align: center; |
| | | font-size: 16px; |
| | | color: $primary-color; |
| | | } |
| | | </style> |
对比新文件 |
| | |
| | | <template> |
| | | <el-bus-crud ref="curd" v-bind="tableConfig" /> |
| | | </template> |
| | | |
| | | <script> |
| | | import dayjs from 'dayjs' |
| | | import 'dayjs/locale/zh-cn' |
| | | import SelectAllUser from '@/components/sms/select-all-user' |
| | | import CopyTextarea from '@/components/sms/copy-textarea' |
| | | import TemplateDownload from '@/components/sms/template-download' |
| | | export default { |
| | | data() { |
| | | const defaultDate = `${dayjs().format('YYYY-MM-DD')} 00:00:00` |
| | | return { |
| | | tableConfig: { |
| | | url: 'flower/v2/sms-task/list', |
| | | newUrl: 'flower/v2/sms-task/new', |
| | | editUrl: 'flower/v2/sms-task/edit', |
| | | viewUrl: 'flower/v2/sms-task', |
| | | viewOnPath: true, |
| | | deleteUrl: 'flower/v2/sms-task/delete', |
| | | hasNew: true, |
| | | newText: '添加发送任务', |
| | | dialogNeedRequest: true, |
| | | canEdit: (row) => row.status === 'wait_publish', |
| | | canDelete: (row) => row.status === 'wait_publish', |
| | | extraButtons: [ |
| | | { |
| | | text: '发布', |
| | | show: (row) => { |
| | | return row.status === 'wait_publish'; |
| | | }, |
| | | atClick: async (row) => { |
| | | try { |
| | | await this.$elBusUtil.confirm('确定要发布吗?') |
| | | const { code } = await this.$elBusHttp.request( |
| | | `flower/v2/sms-task/publish`, |
| | | { |
| | | method: 'post', |
| | | data: { |
| | | id: row.id, |
| | | } |
| | | } |
| | | ) |
| | | if (code === 0) { |
| | | this.$message.success('发布成功') |
| | | } |
| | | } catch (e) { |
| | | return false |
| | | } |
| | | }, |
| | | }, |
| | | ], |
| | | onResetView: (row) => { |
| | | // this.$router.push(`${this.$route.path}/${row.id}`) |
| | | |
| | | // const searchFormRef = this.$refs.crud.$refs.searchForm |
| | | // const searchFormValue = searchFormRef.getFormValue() |
| | | const url = this.$router.resolve( |
| | | `/sms/send-batch/${row.id}` |
| | | ).href |
| | | window.open(url, '_blank') |
| | | |
| | | }, |
| | | columns: [ |
| | | { label: '任务名称', prop: 'name' }, |
| | | { label: '模板名称', prop: 'smsTemplateName' }, |
| | | { label: '模板描述', prop: 'smsTemplateDesc' }, |
| | | { label: '任务状态', prop: 'statusStr' }, |
| | | { label: '创建时间', prop: 'createTime' }, |
| | | ], |
| | | searchForm: [ |
| | | { |
| | | type: 'row', |
| | | items: [ |
| | | { label: '任务名称', id: 'name', type: 'input' }, |
| | | { label: '模板名称', id: 'smsTemplateName', type: 'input' }, |
| | | { |
| | | label: '任务状态', |
| | | id: 'status', |
| | | type: 'bus-select-dict', |
| | | el: { |
| | | code: 'SMS_TASK_STATUS', |
| | | multiple: false, |
| | | style: 'width:100%', |
| | | }, |
| | | }, |
| | | { |
| | | label: '创建时间', |
| | | id: 'startDate', |
| | | component: 'el-bus-date-range', |
| | | el: { |
| | | clearable: true, |
| | | }, |
| | | // commonFormat: true, |
| | | // commonFormatProps: ['startDate', 'endDate'], |
| | | inputFormat: (row) => { |
| | | if ('startDate' in row || 'endDate' in row) { |
| | | return [ |
| | | this.$elBusUtil.toDate(row.startDate), |
| | | this.$elBusUtil.toDate(row.endDate), |
| | | ] |
| | | } |
| | | }, |
| | | outputFormat: (val) => { |
| | | return { |
| | | startDate: val[0] ? `${this.$elBusUtil.toDate(val[0])} 00:00:00` : undefined, |
| | | endDate: val[1] ? `${this.$elBusUtil.toDate(val[1])} 23:59:59` : undefined, |
| | | } |
| | | }, |
| | | customClass: 'in-bus-form', |
| | | // commonRules: true, |
| | | // default: [defaultDate, defaultDate], |
| | | }, |
| | | |
| | | ], |
| | | }, |
| | | ], |
| | | form: [ |
| | | { |
| | | label: '任务名称', |
| | | id: 'name', |
| | | type: 'input', |
| | | rules: { |
| | | required: true, |
| | | message: '请输入任务名称', |
| | | trigger: 'blur', |
| | | }, |
| | | }, |
| | | { |
| | | label: '短信模板:', |
| | | id: 'smsTemplateId', |
| | | type: 'bus-select', |
| | | el: { |
| | | interfaceUri: 'flower/v2/sms-template/templateName/all', |
| | | extraQuery: { |
| | | current: 1, |
| | | size: 2000, |
| | | }, |
| | | props: { |
| | | label: 'name', |
| | | value: 'id', |
| | | // dataPath: 'data', |
| | | }, |
| | | filterable: true, |
| | | multiple: false, |
| | | style: 'width:100%', |
| | | }, |
| | | rules: { |
| | | required: true, |
| | | message: '请选择短信模板', |
| | | trigger: 'change', |
| | | }, |
| | | }, |
| | | { |
| | | label: '接收号码:', |
| | | id: 'type', |
| | | type: 'bus-radio', |
| | | el: { |
| | | code: 'SMS_RECEIVE_TYPE', |
| | | // hasAll: false, |
| | | // childType: 'el-radio-button', |
| | | }, |
| | | str: true, |
| | | on: { |
| | | change: (e, updateForm, obj) => { |
| | | // updateForm({ |
| | | // // fileUrl: undefined, |
| | | // // fileUrlDesc: undefined, |
| | | // // pointCostomIdList: undefined, |
| | | // // input: undefined, |
| | | // }) |
| | | }, |
| | | }, |
| | | default: this.$route.query.status || '', |
| | | span: 24, |
| | | searchImmediately: true, |
| | | rules: { |
| | | required: true, |
| | | message: '请输入接收号码', |
| | | trigger: 'change', |
| | | }, |
| | | }, |
| | | { |
| | | label: '导入接收文件', |
| | | id: 'fileUrl', |
| | | component: 'el-bus-upload', |
| | | el: { |
| | | // listType: 'text', |
| | | accept: ".xls,.xlsx", |
| | | limit: 1 |
| | | }, |
| | | commonFormat: true, |
| | | forceDisabled: true, |
| | | hidden: (row) => { |
| | | return row.type !== 'IMPORT' |
| | | }, |
| | | readonly: false, |
| | | rules: [ |
| | | { required: true, message: '请上传文件' }, |
| | | { |
| | | validator: (rule, value, callback) => { |
| | | if (!value || value.length > 1) { |
| | | callback(new Error('只能上传一个文件')); |
| | | } else { |
| | | callback(); |
| | | } |
| | | }, |
| | | trigger: 'change', |
| | | }, |
| | | ], |
| | | }, |
| | | { |
| | | label: '', |
| | | id: 'fileUrlDesc', |
| | | component: TemplateDownload, |
| | | hidden: (row) => row.type !== 'IMPORT', |
| | | }, |
| | | { |
| | | label: '手动输入:', |
| | | id: 'phones', |
| | | component: CopyTextarea, |
| | | el: { |
| | | type: 'textarea', |
| | | }, |
| | | // hidden: (row) => row.discountType !== 'ratio', |
| | | hidden: (row) => row.type !== 'INPUT', |
| | | readonly: false, |
| | | span: 24, |
| | | rules: [ |
| | | { required: true, message: '请输入号码', trigger: 'blur,change', }, |
| | | // { |
| | | // validator: (rule, value, callback) => { |
| | | // // 如果值为空,直接返回错误 |
| | | // if (!value || value.trim() === '') { |
| | | // callback(new Error('请输入电话号码,每个号码后跟换行符')); |
| | | // return; |
| | | // } |
| | | |
| | | // // 正则表达式:只匹配中国大陆手机号格式 |
| | | // const phoneRegex = /^1[3-9]\d{9}$/; |
| | | // const lines = value.split('\n'); // 按换行符分割文本 |
| | | |
| | | // // 遍历每一行并校验 |
| | | // for (let i = 0; i < lines.length; i++) { |
| | | // const line = lines[i]; // 每一行去除空格 |
| | | // if (line && !phoneRegex.test(line)) { |
| | | // // 如果当前行的电话号码格式不正确,提示出错的行号 |
| | | // callback(new Error(`第 ${i + 1} 行电话号码格式不正确,请检查输入, 如 电话号码后面有空格等`)); |
| | | // return; // 一旦发现不符合的号码格式,就终止校验 |
| | | // } |
| | | // } |
| | | |
| | | // if(lines.length>100){ |
| | | // callback(new Error(`手动输入最多支持100个号码`)); |
| | | // } |
| | | |
| | | // // 所有行都符合格式,执行 callback() |
| | | // callback(); |
| | | // }, |
| | | // trigger: 'blur', |
| | | // } |
| | | { |
| | | validator: (rule, value, callback) => { |
| | | // 如果值为空,直接返回错误 |
| | | if (!value || value.trim() === '') { |
| | | callback(new Error('请输入电话号码,每个号码后跟换行符')); |
| | | return; |
| | | } |
| | | |
| | | |
| | | |
| | | const phoneRegex = /^1[3-9]\d{9}$/; // 校验手机号格式 |
| | | const lines = value.split('\n'); // 按换行符分割文本 |
| | | const phoneCount = {}; // 用来统计电话号码出现次数 |
| | | |
| | | if (lines.length > 100) { |
| | | callback(new Error(`手动输入最多支持100个号码`)); |
| | | } |
| | | |
| | | // 校验每一行的电话号码 |
| | | for (let i = 0; i < lines.length; i++) { |
| | | const line = lines[i].trim(); |
| | | if (line) { |
| | | // 如果当前行不是空的,校验其格式 |
| | | if (!phoneRegex.test(line)) { |
| | | callback(new Error(`第 ${i + 1} 行电话号码格式不正确,请检查输入`)); |
| | | return; |
| | | } |
| | | |
| | | // 统计号码出现的次数 |
| | | phoneCount[line] = (phoneCount[line] || 0) + 1; |
| | | } |
| | | } |
| | | |
| | | |
| | | // 收集所有重复的电话号码 |
| | | const duplicates = []; |
| | | for (const phone in phoneCount) { |
| | | if (phoneCount[phone] > 1) { |
| | | duplicates.push(`${phone} 重复了 ${phoneCount[phone]} 次`); |
| | | } |
| | | } |
| | | |
| | | |
| | | // 如果有重复号码,返回错误并列出所有重复的号码 |
| | | if (duplicates.length > 0) { |
| | | callback(new Error(`以下电话号码重复:\n${duplicates.join('\n')}`)); |
| | | return; |
| | | } |
| | | |
| | | // 校验通过 |
| | | callback(); |
| | | }, |
| | | trigger: 'blur', |
| | | } |
| | | |
| | | ], |
| | | |
| | | }, |
| | | |
| | | { |
| | | label: '选择用户列表', |
| | | id: 'smsUserDTOS', |
| | | component: SelectAllUser, |
| | | hidden: (row) => row.type !== 'SELECT', |
| | | rules: { required: true, message: '请选择领取用户' }, |
| | | inputFormat: (row) => { |
| | | if ('smsUserDTOS' in row) { |
| | | return row.smsUserDTOS.filter((i) => i) |
| | | } |
| | | }, |
| | | outputFormat: (val) => { |
| | | return val?.length ? val.map((i) => {return {userId:i.id,userPhone:i.tel} }) : [] |
| | | }, |
| | | forceDisabled: true, |
| | | }, |
| | | ], |
| | | }, |
| | | } |
| | | }, |
| | | head() { |
| | | return { |
| | | title: '批量发送短信', |
| | | } |
| | | }, |
| | | |
| | | } |
| | | </script> |
对比新文件 |
| | |
| | | <template> |
| | | <el-bus-crud v-bind="tableConfig" /> |
| | | </template> |
| | | |
| | | <script> |
| | | import dayjs from 'dayjs' |
| | | import 'dayjs/locale/zh-cn' |
| | | export default { |
| | | data() { |
| | | const defaultDate = `${dayjs().format('YYYY-MM-DD')} 00:00:00` |
| | | return { |
| | | tableConfig: { |
| | | url: 'flower/v2/sms-template/list', |
| | | newUrl: 'flower/v2/sms-template/new', |
| | | deleteUrl: 'flower/v2/sms-template/delete', |
| | | editUrl: 'flower/v2/sms-template/edit', |
| | | columns: [ |
| | | { label: 'ID', prop: 'id' }, |
| | | { label: 'CODE', prop: 'code' }, |
| | | { label: '模板名称', prop: 'name' }, |
| | | { label: '模板描述', prop: 'description' }, |
| | | { label: '创建时间', prop: 'createTime' }, |
| | | ], |
| | | searchForm: [ |
| | | { |
| | | type: 'row', |
| | | items: [ |
| | | { label: 'ID', id: 'id', type: 'input' }, |
| | | { label: 'CODE', id: 'code', type: 'input' }, |
| | | { label: '模板名称', id: 'name', type: 'input' }, |
| | | { |
| | | label: '创建时间', |
| | | id: 'startDate', |
| | | component: 'el-bus-date-range', |
| | | el: { |
| | | clearable: true, |
| | | }, |
| | | // commonFormat: true, |
| | | commonFormatProps: ['startDate', 'endDate'], |
| | | inputFormat: (row) => { |
| | | if ('startDate' in row || 'endDate' in row) { |
| | | return [ |
| | | this.$elBusUtil.toDate(row.startDate), |
| | | this.$elBusUtil.toDate(row.endDate), |
| | | ] |
| | | } |
| | | }, |
| | | outputFormat: (val) => { |
| | | return { |
| | | startDate:val[0] ? `${this.$elBusUtil.toDate(val[0])} 00:00:00`: undefined, |
| | | endDate: val[1] ?`${this.$elBusUtil.toDate(val[1])} 23:59:59`: undefined, |
| | | } |
| | | }, |
| | | customClass: 'in-bus-form', |
| | | // commonRules: true, |
| | | // default: [defaultDate, defaultDate], |
| | | }, |
| | | ], |
| | | }, |
| | | ], |
| | | form: [ |
| | | { |
| | | label: 'CODE:', |
| | | id: 'code', |
| | | type: 'bus-select', |
| | | el: { |
| | | interfaceUri: 'flower/v2/sms-template/aliyun/list', |
| | | extraQuery: { |
| | | current: 1, |
| | | size: 2000, |
| | | }, |
| | | props: { |
| | | label: 'templateName', |
| | | value: 'templateCode', |
| | | // dataPath: 'records', |
| | | }, |
| | | filterable: true, |
| | | multiple: false, |
| | | style: 'width:100%', |
| | | }, |
| | | rules: { |
| | | required: true, |
| | | message: '请选择CODE', |
| | | trigger: 'blur', |
| | | }, |
| | | }, |
| | | |
| | | { |
| | | label: '模板名称:', |
| | | id: 'name', |
| | | type: 'input', |
| | | rules: { |
| | | required: true, |
| | | message: '请输入模板名称', |
| | | trigger: 'blur', |
| | | }, |
| | | }, |
| | | { |
| | | label: '模板描述:', |
| | | id: 'description', |
| | | type: 'input', |
| | | el: { |
| | | type: 'textarea', |
| | | rows: 6, |
| | | }, |
| | | rules: { |
| | | required: true, |
| | | message: '请输入模板描述', |
| | | trigger: 'blur', |
| | | }, |
| | | }, |
| | | |
| | | ], |
| | | }, |
| | | } |
| | | }, |
| | | head() { |
| | | return { |
| | | title: '短信模板维护', |
| | | } |
| | | }, |
| | | } |
| | | </script> |