You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

805 lines
23 KiB

  1. <script setup>
  2. import { ref, onMounted, reactive, computed, watch, nextTick } from 'vue'
  3. import { ElMessage } from 'element-plus'
  4. import { Plus } from '@element-plus/icons-vue'
  5. import axios from 'axios'
  6. import { ElMessageBox } from 'element-plus'
  7. import API from '@/util/http.js'
  8. import { uploadFile } from '@/util/request.js';
  9. import moment from 'moment'
  10. import { range, re } from 'mathjs'
  11. import { utils, read } from 'xlsx'
  12. import throttle from 'lodash/throttle'
  13. // 定义 fixedAdminId
  14. // const fixedAdminId = 1;
  15. // 精网号去空格
  16. const trimJwCode = () => {
  17. if (recharge.value.jwcode) {
  18. recharge.value.jwcode = recharge.value.jwcode.replace(/\s/g, '');
  19. }
  20. }
  21. // 上传图片前的验证函数
  22. const beforeAvatarUpload = (file) => {
  23. const validTypes = ['image/jpeg', 'image/png'];
  24. const isImage = validTypes.includes(file.type);
  25. const isLt1M = file.size / 1024 / 1024 < 1;
  26. if (!isImage) {
  27. ElMessage.error('只能上传 JPG/PNG 图片!');
  28. return false;
  29. }
  30. if (!isLt1M) {
  31. ElMessage.error('图片大小不能超过 1MB!');
  32. return false;
  33. }
  34. return true;
  35. };
  36. // 这是添加上传图片的接口
  37. const imageUrl = ref('')
  38. const voucher = ref('')
  39. // const rateName = ref()
  40. const adminData = ref({})
  41. // 获取管理员信息
  42. const getAdminData = async function () {
  43. try {
  44. const result = await API({
  45. url: '/admin/userinfo',
  46. data: {}
  47. })
  48. adminData.value = result
  49. recharge.value.adminId = adminData.value.id
  50. recharge.value.market = adminData.value.market
  51. console.log('请求成功', result)
  52. console.log('用户信息', user.value)
  53. } catch (error) {
  54. console.log('请求失败', error)
  55. }
  56. }
  57. // 这是添加充值信息的表单
  58. const recharge = ref({
  59. jwcode: '', // jwcode 字段
  60. activity: '', // activity 字段
  61. voucher: '',
  62. rechargeWay: '客服充值',
  63. freeGold: "",
  64. money: null,
  65. permanentGold: "",
  66. rateName: null,
  67. rateId: null,
  68. payModel: '', // payModel 字段
  69. payTime: null, // payTime 字段
  70. remark: '', // remark 字段
  71. rechargeRatio: ''
  72. })
  73. // 这是添加充值信息的接口
  74. const add = async function () {
  75. try {
  76. const formattedRecharge = { ...recharge.value }
  77. // 将永久金币数、免费金币数和充值金额数乘以 100
  78. if (formattedRecharge.permanentGold) {
  79. formattedRecharge.permanentGold = Number(formattedRecharge.permanentGold) * 100;
  80. }
  81. if (formattedRecharge.freeGold) {
  82. formattedRecharge.freeGold = Number(formattedRecharge.freeGold) * 100;
  83. }
  84. if (formattedRecharge.money) {
  85. formattedRecharge.money = Number(formattedRecharge.money) * 100;
  86. }
  87. if (formattedRecharge.payTime) {
  88. // 使用 moment.js 格式化 payTime
  89. formattedRecharge.payTime = moment(formattedRecharge.payTime).format('YYYY-MM-DD HH:mm:ss')
  90. }
  91. console.log('开始添加充值信息', recharge.value)
  92. // 发送POST请求
  93. const result = await API({
  94. url: '/recharge/add',
  95. data: formattedRecharge
  96. })
  97. if (result.code === 0) {
  98. ElMessage.error(result.msg)
  99. return
  100. }
  101. // 将响应结果存储到响应式数据中
  102. console.log('请求成功', result)
  103. // 显示成功消息
  104. ElMessage.success('添加成功')
  105. // 重置表单
  106. recharge.value = {}
  107. recharge.value.adminId = adminData.value.id
  108. recharge.value.market = adminData.value.market
  109. recharge.value.voucher = ''
  110. recharge.value.rechargeWay = '客服充值'
  111. recharge.value.freeGold = ''
  112. recharge.value.money = null
  113. recharge.value.permanentGold = ''
  114. recharge.value.rateId = null
  115. imageUrl.value = ''
  116. recharge.value.rateName = null
  117. user.value = {}
  118. } catch (error) {
  119. console.log('请求失败', error)
  120. // 在这里可以处理错误逻辑,比如显示错误提示等
  121. }
  122. }
  123. //添加充值信息前的按钮点击事件,进行表单验证和用户确认操作
  124. const addBefore = () => {
  125. if(!recharge.value.permanentGold){
  126. recharge.value.permanentGold ='0'
  127. }
  128. if(!recharge.value.freeGold){
  129. recharge.value.freeGold ='0'
  130. }
  131. Ref.value.validate(async (valid) => {
  132. if (valid) {
  133. if (Number(recharge.value.permanentGold) === 0 && Number(recharge.value.freeGold) === 0) {
  134. ElMessage({
  135. type: 'error',
  136. message: '永久金币和免费金币不能同时为0'
  137. })
  138. return
  139. }
  140. if (recharge.value.rateName == null || recharge.value.rateName == '' || recharge.value.rateName == undefined) {
  141. ElMessage({
  142. type: 'error',
  143. message: '请选择币种'
  144. })
  145. return
  146. }
  147. if (recharge.value.money == null || recharge.value.money == '' || recharge.value.money == undefined) {
  148. ElMessage({
  149. type: 'error',
  150. message: '请输入充值金额'
  151. })
  152. return
  153. }
  154. // 根据选择的货币名称找到对应的 rateId
  155. const selectedRate = rateName.find(item => item.value === recharge.value.rateName)
  156. if (selectedRate) {
  157. recharge.value.rateId = selectedRate.rateId
  158. }
  159. ElMessageBox.confirm('确认充值?')
  160. .then(() => {
  161. add()
  162. console.log('充值成功')
  163. })
  164. .catch(() => {
  165. console.log('取消充值')
  166. })
  167. } else {
  168. //提示
  169. ElMessage({
  170. type: 'error',
  171. message: '请检查输入内容'
  172. })
  173. }
  174. })
  175. }
  176. // 表单验证
  177. // 开始时间改变时,重新验证结束时间
  178. const Ref = ref(null)
  179. const rules = reactive({
  180. jwcode: [{
  181. required: true, validator: (rule, value, callback) => {
  182. if (!value) {
  183. callback(new Error('精网号不能为空'));
  184. return;
  185. }
  186. if (/[^0-9]/.test(value)) {
  187. callback(new Error('精网号只能包含数字'));
  188. return;
  189. }
  190. callback();
  191. }, trigger: 'blur'
  192. }],
  193. activity: [{ required: true, message: '请选择活动名称', trigger: 'blur' }],
  194. permanentGold: [
  195. { required: true, message: '请输入永久金币数', trigger: 'change' },
  196. {
  197. validator: (rule, value, callback) => {
  198. if(!value){
  199. value = '0'
  200. }
  201. // 检查是否包含特殊符号
  202. if (/[^0-9.]/.test(value)) {
  203. callback(new Error('不能包含特殊符号或负数'));
  204. return;
  205. }
  206. // 检查整数位数
  207. const integerPart = value.split('.')[0];
  208. if (integerPart.length > 6) {
  209. callback(new Error('整数位数不能超过6位'));
  210. return;
  211. }
  212. // 检查小数位数
  213. if (value.includes('.')) {
  214. const decimalPart = value.split('.')[1];
  215. if (decimalPart.length > 2) {
  216. callback(new Error('小数位数不能超过两位'));
  217. return;
  218. }
  219. }
  220. const numValue = Number(value);
  221. if (isNaN(numValue)) {
  222. callback(new Error('请输入有效的数字'));
  223. } else if (numValue < 0) {
  224. callback(new Error('输入金额不能小于0'));
  225. } else {
  226. callback();
  227. }
  228. },
  229. trigger: 'blur'
  230. }
  231. ],
  232. freeGold: [
  233. { required: true, message: '请输入免费金币数', trigger: 'change' },
  234. {
  235. validator: (rule, value, callback) => {
  236. if(!value){
  237. value = '0'
  238. }
  239. // 检查是否包含特殊符号
  240. if (/[^0-9.]/.test(value)) {
  241. callback(new Error('不能包含特殊符号或负数'));
  242. return;
  243. }
  244. // 检查整数位数
  245. const integerPart = value.split('.')[0];
  246. if (integerPart.length > 6) {
  247. callback(new Error('整数位数不能超过6位'));
  248. return;
  249. }
  250. // 检查小数位数
  251. if (value.includes('.')) {
  252. const decimalPart = value.split('.')[1];
  253. if (decimalPart.length > 2) {
  254. callback(new Error('小数位数不能超过两位'));
  255. return;
  256. }
  257. }
  258. const numValue = Number(value);
  259. if (isNaN(numValue)) {
  260. callback(new Error('请输入有效的数字'));
  261. } else if (numValue < 0) {
  262. callback(new Error('输入金额不能小于0'));
  263. } else {
  264. callback();
  265. }
  266. },
  267. trigger: 'blur'
  268. }
  269. ],
  270. rateName: [{
  271. required: true,
  272. message: '请选择货币名称',
  273. trigger: 'blur'
  274. }],
  275. money: [
  276. { required: true, message: '请输入充值金额', trigger: 'blur' },
  277. {
  278. validator: (rule, value, callback) => {
  279. // 检查是否包含特殊符号
  280. if (/[^0-9.]/.test(value)) {
  281. callback(new Error('不能包含特殊符号或负数'));
  282. return;
  283. }
  284. // 检查整数位数
  285. const integerPart = value.split('.')[0];
  286. if (integerPart.length > 6) {
  287. callback(new Error('整数位数不能超过6位'));
  288. return;
  289. }
  290. // 检查小数位数
  291. if (value.includes('.')) {
  292. const decimalPart = value.split('.')[1];
  293. if (decimalPart.length > 2) {
  294. callback(new Error('小数位数不能超过两位'));
  295. return;
  296. }
  297. }
  298. const numValue = Number(value);
  299. if (isNaN(numValue)) {
  300. callback(new Error('请输入有效的数字'));
  301. } else if (numValue < 0) {
  302. callback(new Error('输入金额不能小于0'));
  303. } else {
  304. callback();
  305. }
  306. },
  307. trigger: 'blur'
  308. }
  309. ],
  310. payModel: [{ required: true, message: '请选择付款方式', trigger: 'blur' }],
  311. payTime: [{ required: true, message: '请选择交款时间', trigger: 'blur' }]
  312. });
  313. // 查找客户信息的方法
  314. const user = ref({})
  315. const getUser = async function (jwcode) {
  316. trimJwCode();
  317. // 验证精网号
  318. if (!jwcode) {
  319. ElMessage.warning('精网号不能为空');
  320. return;
  321. }
  322. // 验证精网号是否为数字
  323. if (!/^\d{1,9}$/.test(jwcode)) {
  324. ElMessage.warning('精网号必须为数字且不超过九位');
  325. deleteRecharge()
  326. return;
  327. }
  328. try {
  329. const result = await API({
  330. url: '/user/selectUser',
  331. data: {
  332. jwcode: recharge.value.jwcode
  333. }
  334. })
  335. if (result.code === 0) {
  336. ElMessage.error(result.msg);
  337. } else if (result.data === null) {
  338. ElMessage.error("用户不存在");
  339. } else {
  340. user.value = result.data;
  341. console.log("用户信息", user.value);
  342. ElMessage.success("查询成功");
  343. }
  344. } catch (error) {
  345. console.log("请求失败", error);
  346. ElMessage.error("精网号错误");
  347. }
  348. }
  349. // 这是查询活动的接口,一期没有调用这个接口
  350. const activity = ref([])
  351. // const getActivity = async function () {
  352. // try {
  353. // // 发送POST请求
  354. // const result = await API({
  355. // url: '/general/activity',
  356. // data: {
  357. // }
  358. // })
  359. // // 将响应结果存储到响应式数据中
  360. // console.log('请求成功', result)
  361. // // 存储表格数据
  362. // activity.value = result.data
  363. // console.log('活动信息', activity.value)
  364. // } catch (error) {
  365. // console.log('activity请求失败', error)
  366. // // 在这里可以处理错误逻辑,比如显示错误提示等
  367. // }
  368. // }
  369. //货币条目
  370. const rateName = [
  371. {
  372. value: 'USD',
  373. label: 'USD',
  374. rateId: 1
  375. },
  376. {
  377. value: 'HKD',
  378. label: 'HKD',
  379. rateId: 2
  380. },
  381. {
  382. value: 'THB',
  383. label: 'THB',
  384. rateId: 3
  385. },
  386. {
  387. value: 'VND',
  388. label: 'VND',
  389. rateId: 4
  390. },
  391. {
  392. value: 'CAD',
  393. label: 'CAD',
  394. rateId: 5
  395. },
  396. {
  397. value: 'MYR',
  398. label: 'MYR',
  399. rateId: 6
  400. },
  401. {
  402. value: 'KRW',
  403. label: 'KRW',
  404. rateId: 7
  405. },
  406. {
  407. value: 'JPY',
  408. label: 'JPY',
  409. rateId: 8
  410. },
  411. {
  412. value: 'CNY',
  413. label: 'CNY',
  414. rateId: 9
  415. }
  416. ]
  417. // 修改上传处理
  418. const customUpload = async (options) => {
  419. try {
  420. const formData = new FormData();
  421. formData.append('file', options.file);
  422. const response = await axios.post(import.meta.env.VITE_UPLOAD_URL, formData, {
  423. headers: {
  424. 'Content-Type': 'multipart/form-data',
  425. 'Authorization': `Bearer ${localStorage.getItem('token')}`
  426. }
  427. });
  428. if (response.data.code === 200 && response.data.data) {
  429. // 传递原始文件对象和响应数据
  430. handleAvatarSuccess(response.data, options.file);
  431. ElMessage.success('上传成功');
  432. } else {
  433. ElMessage.error(response.data.msg || '上传失败');
  434. }
  435. } catch (error) {
  436. console.error('上传错误:', error);
  437. ElMessage.error(`上传失败: ${error.response?.data?.message || error.message}`);
  438. }
  439. };
  440. // 获取环境变量
  441. // const uploadUrl = import.meta.env.VITE_UPLOAD_URL;
  442. // 上传图片成功的回调函数
  443. const handleAvatarSuccess = (response, file) => {
  444. // 直接使用 file 对象创建 Object URL
  445. imageUrl.value = URL.createObjectURL(file);
  446. // 使用服务器返回的文件路径(根据实际响应结构调整)
  447. if (response && response.filePath) {
  448. recharge.value.voucher = response.filePath;
  449. } else if (response && response.url) {
  450. recharge.value.voucher = response.url;
  451. } else if (response && response.data) {
  452. // 假设响应结构为 { code: 200, data: { filePath: ... } }
  453. recharge.value.voucher = response.data.filePath || response.data.url;
  454. } else {
  455. // 后备方案:使用环境变量中的上传URL
  456. recharge.value.voucher = import.meta.env.VITE_UPLOAD_URL;
  457. }
  458. }
  459. //支付方式条目
  460. const payModel = [
  461. {
  462. value: '现金',
  463. label: '现金'
  464. },
  465. {
  466. value: '支票',
  467. label: '支票'
  468. },
  469. {
  470. value: '刷卡',
  471. label: '刷卡'
  472. },
  473. {
  474. value: '其他(各地区电子支付)',
  475. label: '其他(各地区电子支付)'
  476. }
  477. ]
  478. // }
  479. function handleActivityChange(value) {
  480. // 在这里执行你的逻辑,例如获取选中的值
  481. console.log('选中的值:', value)
  482. // getActivityById(value)
  483. console.log('看看', recharge.value)
  484. }
  485. //这是重置重置表单的方法
  486. const deleteRecharge = function () {
  487. recharge.value = {
  488. adminId: adminData.value.id,
  489. //adminId: fixedAdminId,
  490. market: adminData.value.market,
  491. voucher: '',
  492. rechargeWay: '客服充值',
  493. freeGold: '',
  494. money: null,
  495. permanentGold: '',
  496. rateId: null
  497. }
  498. imageUrl.value = ''
  499. recharge.value.rateName = ''
  500. }
  501. onMounted(async function () {
  502. await getAdminData()
  503. // await getCurrency()
  504. // await getActivity()// 现在的活动就是文字输入框,不需要请求接口,具体等后续需求
  505. })
  506. onMounted(() => {
  507. console.log('上传URL:', import.meta.env.VITE_UPLOAD_URL);
  508. });
  509. </script>
  510. <template>
  511. <div>
  512. <el-form :model="recharge" ref="Ref" :rules="rules" label-width="auto" style="max-width: 600px" class="add-form">
  513. <el-form-item prop="jwcode" label="精网号">
  514. <el-input v-model="recharge.jwcode" style="width: 220px" />
  515. <el-button type="primary" @click="getUser(recharge.jwcode)" style="margin-left: 20px">查询</el-button>
  516. </el-form-item>
  517. <!-- <el-form-item prop="activity" label="活动名称">
  518. <el-select
  519. v-model="recharge.activity"
  520. placeholder="请选择"
  521. style="width: 300px"
  522. @change="handleActivityChange"
  523. >
  524. <el-option
  525. v-for="(item, index) in activity"
  526. :key="index"
  527. :label="item"
  528. :value="item"
  529. />
  530. </el-select>
  531. </el-form-item> -->
  532. <el-form-item prop="activity" label="活动名称">
  533. <el-input v-model="recharge.activity" placeholder="请输入活动名称" style="width: 300px" />
  534. </el-form-item>
  535. <el-form-item prop="permanentGold" label="永久金币">
  536. <el-input v-model="recharge.permanentGold" placeholder="0" style="width: 100px" />
  537. <p></p>
  538. </el-form-item>
  539. <el-form-item prop="freeGold" label="免费金币">
  540. <el-input v-model="recharge.freeGold" placeholder="0" style="width: 100px" />
  541. <p></p>
  542. </el-form-item>
  543. <!-- <el-form-item label="充值金额">
  544. <el-select
  545. prop="moneys"
  546. v-model="rateName"
  547. placeholder="货币名称"
  548. style="width: 95px; margin-right: 5px"
  549. aria-required="true"
  550. >
  551. <el-option
  552. v-for="item in rateName"
  553. :key="item.value"
  554. :label="item.label"
  555. :value="item.value"
  556. />
  557. </el-select>
  558. <el-input prop="money" v-model="recharge.money" style="width: 200px" aria-required="true"/>
  559. </el-form-item> -->
  560. <el-form-item label="充值金额" required>
  561. <!-- 货币名称 -->
  562. <el-form-item prop="rateName" style="display: inline-block; margin-left:0;">
  563. <el-select v-model="recharge.rateName" placeholder="货币名称" style="width: 100px">
  564. <el-option v-for="item in rateName" :key="item.value" :label="item.label" :value="item.value" />
  565. </el-select>
  566. </el-form-item>
  567. <!-- 充值金额 -->
  568. <el-form-item prop="money" style="display: inline-block; margin-left:10px;">
  569. <el-input v-model="recharge.money" style="width: 190px" />
  570. </el-form-item>
  571. </el-form-item>
  572. <el-form-item prop="payModel" label="收款方式">
  573. <el-select v-model="recharge.payModel" placeholder="请选择" style="width: 300px">
  574. <el-option v-for="item in payModel" :key="item.value" :label="item.label" :value="item.value" />
  575. </el-select>
  576. </el-form-item>
  577. <el-form-item prop="payTime" label="交款时间">
  578. <!-- 修改 type 属性为 datetime 以支持时分秒选择 -->
  579. <el-date-picker v-model="recharge.payTime" type="datetime" style="width: 300px" />
  580. </el-form-item>
  581. <el-form-item prop="voucher" label="交款凭证" style="margin-bottom: 5px">
  582. <el-upload :http-request="customUpload" class="avatar-uploader" :show-file-list="false"
  583. :before-upload="beforeAvatarUpload" style="width: 100px; height: 115px">
  584. <img v-if="imageUrl" :src="imageUrl" class="avatar" style="width: 100px; height: 115px" />
  585. <el-icon v-else class="avatar-uploader-icon" style="width: 100px; height: 100px">
  586. <Plus />
  587. </el-icon>
  588. </el-upload>
  589. <p style="margin-left: 10px; color: rgb(177, 176, 176)">
  590. 仅支持.jpg .png格式文件1MB
  591. </p>
  592. </el-form-item>
  593. <el-form-item prop="remark" label="备注">
  594. <el-input v-model="recharge.remark" style="width: 300px" :rows="2" maxlength="100" show-word-limit
  595. type="textarea" />
  596. </el-form-item>
  597. <el-button @click="deleteRecharge" style="margin-left: 280px" type="success">重置</el-button>
  598. <el-button type="primary" @click="addBefore"> 提交 </el-button>
  599. </el-form>
  600. <!-- 客户信息栏 -->
  601. <el-card v-if="user.jwcode" style="width: 800px; float: right" class="customer-info">
  602. <el-form :model="user" label-width="auto" style="max-width: 1000px" label-position="left">
  603. <el-text size="large" style="margin-left: 20px">客户信息</el-text>
  604. <!-- 第一行姓名 + 历史金币 -->
  605. <el-row style="margin-top: 20px">
  606. <el-col :span="9">
  607. <el-form-item label="姓名:">
  608. <p>{{ user.name }}</p>
  609. </el-form-item>
  610. </el-col>
  611. <el-col :span="14">
  612. <el-form-item label="历史金币总数">
  613. <!-- 检查 user.historySumGold 是否为有效的数字 -->
  614. <p style="color: #2fa1ff; margin-right: 5px" v-if="!isNaN(Number(user.historySumGold))">
  615. {{ Number(user.historySumGold) / 100 }}
  616. </p>
  617. <!-- 如果不是有效的数字显示默认值 -->
  618. <p v-else></p>
  619. </el-form-item>
  620. <el-form-item style="margin-top: -23px">
  621. <span style="display: inline; white-space: nowrap; color: #b1b1b1"
  622. v-if="user.historyPermanentGold !== undefined">(永久金币:{{ user.historyPermanentGold / 100 }};免费金币:{{
  623. (user.historyFreeGold) / 100
  624. }};任务金币:{{ user.historyTaskGold / 100 }})</span>
  625. </el-form-item>
  626. </el-col>
  627. </el-row>
  628. <!-- 第二行精网号 + 当前金币独立行 -->
  629. <el-row style="margin-top:-23px">
  630. <el-col :span="9">
  631. <el-form-item label="精网号">
  632. <p>{{ user.jwcode }}</p>
  633. </el-form-item>
  634. </el-col>
  635. <el-col :span="14">
  636. <el-form-item label="当前金币总数" style="width: 500px">
  637. <span style="color: #2fa1ff; margin-right: 5px" v-if="user.nowSumGold !== undefined">{{ user.nowSumGold
  638. /100}}</span>
  639. </el-form-item>
  640. <!-- 金币详情独立显示 -->
  641. <el-form-item style="margin-top: -23px"> <!-- 负边距减少间距 -->
  642. <span style="color: #b1b1b1; margin-left: 0px" v-if="user.nowPermanentGold !== undefined">(永久金币:{{
  643. user.nowPermanentGold /100}};
  644. 免费金币:{{ user.nowFreeGold / 100 }};
  645. 任务金币:{{ user.nowTaskGold / 100 }})</span>
  646. </el-form-item>
  647. </el-col>
  648. </el-row>
  649. <!-- 第三行首次充值日期 + 充值次数 -->
  650. <el-row style="margin-top:-23px">
  651. <el-col :span="9">
  652. <el-form-item label="首次充值日期">
  653. <p v-if="user.firstRecharge">
  654. {{ moment(user.firstRecharge).format('YYYY-MM-DD HH:mm:ss') }}
  655. </p>
  656. </el-form-item>
  657. </el-col>
  658. <el-col :span="14">
  659. <el-form-item label="充值次数">
  660. <p style="color: #2fa1ff">{{ user.rechargeNum }}</p>
  661. </el-form-item>
  662. </el-col>
  663. </el-row>
  664. <!-- 第四行消费次数 + 所属门店 -->
  665. <el-row>
  666. <el-col :span="9">
  667. <el-form-item label="消费次数">
  668. <p style="color: #2fa1ff">{{ user.consumeNum }}</p>
  669. </el-form-item>
  670. </el-col>
  671. <el-col :span="9">
  672. <el-form-item label="所属门店">
  673. <p>{{ user.market }}</p>
  674. </el-form-item>
  675. </el-col>
  676. </el-row>
  677. </el-form>
  678. </el-card>
  679. </div>
  680. </template>
  681. <style scoped>
  682. p {
  683. margin: 0px;
  684. }
  685. .batch-btn {
  686. margin-top: 20px;
  687. margin-left: auto;
  688. }
  689. .el-form-item {
  690. margin-left: 50px;
  691. }
  692. /* 上传图片的格式 */
  693. .avatar-uploader .avatar {
  694. width: 50px;
  695. height: 50px;
  696. display: block;
  697. }
  698. </style>
  699. <style>
  700. .error-message {
  701. color: red;
  702. font-size: 8px;
  703. }
  704. .is-invalid .el-input__inner {
  705. border-color: red;
  706. }
  707. .avatar-uploader .el-upload {
  708. border: 1px dashed var(--el-border-color);
  709. border-radius: 6px;
  710. cursor: pointer;
  711. position: relative;
  712. overflow: hidden;
  713. transition: var(--el-transition-duration-fast);
  714. }
  715. .avatar-uploader .el-upload:hover {
  716. border-color: var(--el-color-primary);
  717. }
  718. .el-icon.avatar-uploader-icon {
  719. font-size: 28px;
  720. color: #8c939d;
  721. width: 50px;
  722. height: 50px;
  723. text-align: center;
  724. }
  725. .add-form {
  726. margin-top: 50px;
  727. max-width: 50%;
  728. float: left;
  729. }
  730. .customer-info {
  731. max-width: 60%;
  732. }
  733. </style>