index.vue 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458
  1. <template>
  2. <div>
  3. <PlusPage
  4. ref="plusPageInstance"
  5. :columns="tableConfig"
  6. :request="getList"
  7. :is-card="true"
  8. :search="{
  9. labelWidth: 100,
  10. showNumber: 3
  11. }"
  12. :table="{
  13. actionBar: { buttons, type: 'link', width: 180 },
  14. adaptive: { offsetBottom: 50 },
  15. hasIndexColumn: true
  16. }"
  17. :pageInfoMap="{ page: 'pageNum', pageSize: 'pageSize' }"
  18. >
  19. <template #table-title>
  20. <el-row class="button-row">
  21. <el-button size="default" type="success" @click="handleCreate">
  22. 新增
  23. </el-button>
  24. </el-row>
  25. </template>
  26. </PlusPage>
  27. <!-- 弹窗编辑 -->
  28. <PlusDialogForm
  29. ref="dialogForm"
  30. v-model="form"
  31. v-model:visible="dialogVisible"
  32. :form="{
  33. columns,
  34. labelPosition: 'left',
  35. labelWidth: 190,
  36. rules
  37. }"
  38. :dialog="{ title: dialogTitle + '菜单', width: 600, confirmLoading }"
  39. @confirm="handleSubmit"
  40. @close="handleClose"
  41. />
  42. </div>
  43. </template>
  44. <script lang="ts" setup>
  45. import {
  46. computed,
  47. onMounted,
  48. reactive,
  49. ref,
  50. resolveDirective,
  51. toRefs
  52. } from "vue";
  53. import type { FormRules } from "element-plus";
  54. import { ElMessage } from "element-plus";
  55. import {
  56. type FieldValues,
  57. type PlusColumn,
  58. PlusDialogForm,
  59. PlusPage,
  60. PlusPageInstance,
  61. useTable
  62. } from "plus-pro-components";
  63. import { useRouter } from "vue-router";
  64. import {
  65. createChildAccount,
  66. getChildAccountList,
  67. merchantUserInfoDetail,
  68. merchantUserInfoupdateAllocationStatus,
  69. merchantUserInfoupdateStatus,
  70. updateChildAccount
  71. } from "@/api/childAccount";
  72. import { AesEncode } from "@/utils/crypto";
  73. import { md5 } from "js-md5";
  74. defineOptions({
  75. name: "ChildAccount"
  76. });
  77. const router = useRouter();
  78. const plusPageInstance = ref<PlusPageInstance | null>(null);
  79. const getList = async (query: Record<string, any>) => {
  80. let res = await getChildAccountList(query);
  81. return {
  82. data: res.data.list,
  83. total: res.data.total
  84. };
  85. };
  86. // 重新请求列表接口
  87. const refresh = () => {
  88. plusPageInstance.value?.getList();
  89. };
  90. const dialogTitle = computed(() => (state.isCreate ? "新增" : "编辑"));
  91. // 表格数据
  92. const tableConfig: PlusColumn[] = [
  93. {
  94. label: "姓名",
  95. prop: "contractName",
  96. hideInSearch: true
  97. },
  98. {
  99. label: "手机号",
  100. prop: "contractMobile",
  101. hideInSearch: true
  102. },
  103. {
  104. label: "备注",
  105. prop: "remark",
  106. hideInSearch: true
  107. },
  108. {
  109. label: "创建人",
  110. prop: "creater",
  111. hideInSearch: true
  112. },
  113. {
  114. label: "创建时间",
  115. prop: "createTime",
  116. hideInSearch: true
  117. },
  118. {
  119. label: "微信号",
  120. prop: "wechat",
  121. hideInSearch: true
  122. },
  123. {
  124. label: "接单状态",
  125. prop: "receiveStatus",
  126. valueType: "select",
  127. options: [
  128. { label: "接单", value: true },
  129. { label: "不接单", value: false }
  130. ],
  131. hideInSearch: true
  132. },
  133. {
  134. label: "当前状态",
  135. prop: "status",
  136. valueType: "select",
  137. options: [
  138. { label: "正常", value: "1" },
  139. { label: "禁用", value: "0" }
  140. ],
  141. hideInSearch: true
  142. }
  143. ];
  144. /*--------------------表单--------------------*/
  145. // 表单实例
  146. const dialogForm = ref(null);
  147. interface State {
  148. dialogVisible: boolean;
  149. detailsVisible: boolean;
  150. confirmLoading: boolean;
  151. selectedIds: number[];
  152. isCreate: boolean;
  153. form: Record<string, any>;
  154. rules: FormRules;
  155. }
  156. const state = reactive<State>({
  157. dialogVisible: false,
  158. detailsVisible: false,
  159. confirmLoading: false,
  160. selectedIds: [],
  161. isCreate: false,
  162. form: {},
  163. rules: {
  164. contractName: [
  165. {
  166. required: true,
  167. message: "请输入姓名",
  168. trigger: "blur"
  169. }
  170. ],
  171. contractMobile: [
  172. {
  173. required: true,
  174. message: "请输入手机号",
  175. trigger: "blur"
  176. },
  177. {
  178. pattern: /^1[3-9]\d{9}$/,
  179. message: "请输入正确的手机号",
  180. trigger: "blur"
  181. }
  182. ],
  183. accountName: [
  184. {
  185. required: true,
  186. message: "请输入账号",
  187. trigger: "blur"
  188. }
  189. ],
  190. contractPassword: [
  191. {
  192. pattern:
  193. /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[~!@#$%^&*()_+`\-={}:";'<>?,./]).{8,16}$/,
  194. message: "输入8到16位密码,须包括大小写字母、数字和特殊符号",
  195. trigger: "blur"
  196. }
  197. ]
  198. }
  199. });
  200. const columns: PlusColumn[] = [
  201. {
  202. label: "姓名",
  203. prop: "contractName",
  204. fieldProps: {
  205. clearable: true
  206. }
  207. },
  208. {
  209. label: "手机号",
  210. prop: "contractMobile",
  211. fieldProps: {
  212. clearable: true
  213. }
  214. },
  215. {
  216. label: "微信号",
  217. prop: "wechat",
  218. fieldProps: {
  219. clearable: true
  220. }
  221. },
  222. {
  223. label: "账号",
  224. prop: "accountName",
  225. fieldProps: computed(() => {
  226. return {
  227. disabled: !state.isCreate
  228. };
  229. })
  230. },
  231. {
  232. label: "密码",
  233. prop: "contractPassword",
  234. fieldProps: {
  235. type: "password",
  236. clearable: true,
  237. showPassword: true
  238. }
  239. },
  240. {
  241. label: "确认密码",
  242. prop: "confirmPassword",
  243. fieldProps: {
  244. type: "password",
  245. clearable: true,
  246. showPassword: true
  247. },
  248. formItemProps: computed(() => ({
  249. required:
  250. form.value.contractPassword !== "" &&
  251. form.value.contractPassword !== null &&
  252. form.value.contractPassword !== undefined,
  253. rules: [
  254. {
  255. required: true,
  256. message: "请输入确认密码",
  257. trigger: "blur"
  258. },
  259. {
  260. validator: (rule, value, callback) => {
  261. if (value !== form.value.contractPassword) {
  262. callback(new Error("密码不一致"));
  263. } else {
  264. callback();
  265. }
  266. }
  267. }
  268. ]
  269. }))
  270. },
  271. {
  272. label: "是否愿意客户主动电话联系",
  273. prop: "isAllowCusContact",
  274. valueType: "radio",
  275. options: [
  276. {
  277. label: "是",
  278. value: true
  279. },
  280. {
  281. label: "否",
  282. value: false
  283. }
  284. ]
  285. },
  286. {
  287. label: "备注",
  288. prop: "remark",
  289. fieldProps: {
  290. type: "textarea",
  291. rows: 4,
  292. clearable: true,
  293. maxlength: 200,
  294. showWordLimit: true
  295. }
  296. }
  297. ];
  298. // 创建
  299. const handleCreate = (): void => {
  300. form.value = {
  301. status: "normal"
  302. };
  303. state.isCreate = true;
  304. state.dialogVisible = true;
  305. };
  306. const handleSubmit = async (values: FieldValues) => {
  307. console.log(values, "Submit");
  308. confirmLoading.value = true;
  309. if (state.isCreate) {
  310. try {
  311. let params = form.value;
  312. params.contractPassword = form.value.contractPassword
  313. ? md5(form.value.contractPassword).toUpperCase()
  314. : "";
  315. params.confirmPassword = form.value.confirmPassword
  316. ? md5(form.value.confirmPassword).toUpperCase()
  317. : "";
  318. let res = await createChildAccount(params);
  319. if (res.code === 0) {
  320. ElMessage.success("新增成功");
  321. confirmLoading.value = false;
  322. dialogVisible.value = false;
  323. refresh();
  324. } else {
  325. ElMessage.error(res.msg);
  326. }
  327. } finally {
  328. confirmLoading.value = false;
  329. }
  330. } else {
  331. // 编辑
  332. try {
  333. let params = form.value;
  334. params.contractPassword = md5(form.value.contractPassword).toUpperCase();
  335. params.confirmPassword = md5(form.value.confirmPassword).toUpperCase();
  336. let res = await updateChildAccount(params);
  337. if (res.code === 0) {
  338. ElMessage.success("修改成功");
  339. confirmLoading.value = false;
  340. dialogVisible.value = false;
  341. refresh();
  342. } else {
  343. ElMessage.error(res.msg);
  344. }
  345. } finally {
  346. confirmLoading.value = false;
  347. }
  348. }
  349. };
  350. const handleClose = () => {
  351. // 重置表单校验状态
  352. console.log(dialogForm.value.formInstance);
  353. };
  354. const { buttons } = useTable();
  355. const perms = resolveDirective("perms");
  356. buttons.value = [
  357. {
  358. // 修改
  359. text: "修改",
  360. code: "edit",
  361. // props v0.1.16 版本新增函数类型
  362. props: {
  363. type: "primary"
  364. },
  365. onClick(params) {
  366. merchantUserInfoDetail(params.row.id).then(res => {
  367. if (res.code === 0) {
  368. let data = res.data;
  369. data.contractPassword = "";
  370. data.confirmPassword = "";
  371. form.value = data;
  372. state.isCreate = false;
  373. state.dialogVisible = true;
  374. }
  375. });
  376. }
  377. },
  378. {
  379. // 修改
  380. text: "修改状态",
  381. props: {
  382. type: "warning"
  383. },
  384. confirm: {
  385. options: {
  386. draggable: true,
  387. message: "确认修改状态?"
  388. }
  389. },
  390. onConfirm: async params => {
  391. try {
  392. let res = await merchantUserInfoupdateStatus({
  393. id: params.row.id,
  394. status: params.row.status === "1" ? "0" : "1"
  395. });
  396. if (res.code === 0) {
  397. ElMessage.success("修改成功");
  398. refresh();
  399. } else {
  400. ElMessage.error(res.msg);
  401. }
  402. } catch (e) {
  403. ElMessage.error("删除失败");
  404. }
  405. }
  406. },
  407. {
  408. // 修改
  409. text: "修改接单状态",
  410. props: {
  411. type: "warning"
  412. },
  413. confirm: {
  414. options: {
  415. draggable: true,
  416. message: "确认修改接单状态?"
  417. }
  418. },
  419. onConfirm: async params => {
  420. try {
  421. let res = await merchantUserInfoupdateAllocationStatus({
  422. ids: [params.row.id],
  423. allocationStatus: params.row.receiveStatus === true ? false : true
  424. });
  425. if (res.code === 0) {
  426. ElMessage.success("修改成功");
  427. refresh();
  428. } else {
  429. ElMessage.error(res.msg);
  430. }
  431. } catch (e) {
  432. ElMessage.error("删除失败");
  433. }
  434. }
  435. }
  436. ];
  437. const { form, confirmLoading, rules, dialogVisible } = toRefs(state);
  438. </script>