123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813 |
- <template>
- <view class="objectives-add">
- <view class="message">
- <uv-text
- type="error"
- text="本系统中的年度服务目标、【年度服务预算】、年度服务计划等,无论是否经由一方或双方同意或者确认,均不构成双方之间的协议;服务量、服务费用价格与金额等应以另行签署的合同为准。"
- ></uv-text>
- </view>
- <view class="form">
- <uv-form labelPosition="left" :model="form" :rules="rules" ref="formRef" labelWidth="80">
- <uv-form-item
- label="目标产品"
- prop="skuIdLable"
- borderBottom
- @click="showSelect('skuId')"
- :customStyle="customStyle"
- required
- >
- <uv-input v-model="form.skuIdLable" border="none" placeholder="请选择" readonly />
- <template v-slot:right>
- <uv-icon name="arrow-right"></uv-icon>
- </template>
- </uv-form-item>
- <uv-form-item label="生产企业" prop="ent_name" borderBottom :customStyle="customStyle">
- <uv-input v-model="form.ent_name" border="none" readonly />
- </uv-form-item>
- <uv-form-item
- label="目标总值"
- prop="planScore"
- borderBottom
- :customStyle="customStyle"
- required
- >
- <uv-input v-model="form.planScore" :readonly="formDisabled" type="number" border="none" />
- </uv-form-item>
- <uv-form-item
- label="承接对象"
- prop="consigneeIdLable"
- borderBottom
- @click="showSelect('consigneeId')"
- :customStyle="customStyle"
- required
- >
- <uv-input v-model="form.consigneeIdLable" border="none" placeholder="请选择" readonly />
- <template v-slot:right>
- <uv-icon name="arrow-right"></uv-icon>
- </template>
- </uv-form-item>
- <uv-form-item
- label="目标类型"
- prop="planTypeLable"
- borderBottom
- @click="showSelect('planType')"
- :customStyle="customStyle"
- required
- >
- <uv-input v-model="form.planTypeLable" border="none" placeholder="请选择" readonly />
- <template v-slot:right>
- <uv-icon name="arrow-right"></uv-icon>
- </template>
- </uv-form-item>
- <uv-form-item
- label="目标周期"
- prop="monthrange"
- borderBottom
- @click="showSelect('monthrange')"
- :customStyle="customStyle"
- required
- >
- <uv-input
- prefixIcon="calendar"
- prefixIconStyle="font-size: 22px;color: #909399"
- v-model="form.monthrange"
- border="none"
- placeholder="请选择"
- readonly
- />
- <template v-slot:right>
- <uv-icon name="arrow-right"></uv-icon>
- </template>
- </uv-form-item>
- <uv-form-item
- label="目标名称"
- prop="planName"
- borderBottom
- :customStyle="customStyle"
- required
- >
- <uv-input
- v-model="form.planName"
- :readonly="formDisabled"
- placeholder="请输入"
- border="none"
- />
- </uv-form-item>
- </uv-form>
- <view class="avail-score" v-if="type === '3'">
- 剩余积分值:{{ detailInfo?.availScore }}
- </view>
- </view>
- <view class="table" v-if="['5', '6', '7'].includes(type)">
- <tableData v-if="type === '5'" ref="tableRef" :planScore="Number(form.planScore)" />
- <tableDetail
- v-if="['6', '7'].includes(type)"
- :planScore="Number(form.planScore)"
- ref="tableDetailRef"
- />
- </view>
- <!-- 新增 -->
- <!-- 1 新增 3 -->
- <template v-if="['1', '3', '5'].includes(type)">
- <view class="btn botton-content" :class="['1', '3'].includes(type) ? 'b-fixed' : ''">
- <view class="cancel" @click="cancelFn">取消</view>
- <view class="confirm" @click="confirmFn">确定</view>
- </view>
- </template>
- <template v-if="['2', '4', '7'].includes(type)">
- <view class="botton-content" :class="['2', '4'].includes(type) ? 'b-fixed' : ''">
- <view class="review-form">
- <uv-form
- labelPosition="left"
- :model="reviewForm"
- :rules="reviewFormRules"
- ref="reviewFormRef"
- labelWidth="80"
- >
- <uv-form-item label="审核说明" prop="msg" borderBottom>
- <uv-textarea
- v-model="reviewForm.msg"
- placeholder="请输入审核说明"
- height="48"
- ></uv-textarea>
- </uv-form-item>
- </uv-form>
- </view>
- <view class="btn">
- <view class="cancel" @click="reviewFn(false)">拒绝</view>
- <view class="confirm" @click="reviewFn(true)">通过</view>
- </view>
- </view>
- </template>
- <!-- 选择目标产品 -->
- <uv-picker ref="skuIdPicker" :columns="drugList" keyName="drug_name" @confirm="skuIdConfirm" />
- <!-- 选择承接对象 -->
- <uv-picker
- ref="consigneeIdPicker"
- :columns="csoList"
- keyName="name"
- @confirm="consigneeIdConfirm"
- />
- <!-- 选择目标类型 -->
- <uv-picker
- ref="planTypePicker"
- :columns="[planTypeList]"
- keyName="label"
- @confirm="planTypeConfirm"
- />
- <!-- 选择年份 -->
- <uv-datetime-picker ref="yearPicker" mode="year" @confirm="yearConfirm"></uv-datetime-picker>
- <!-- 选择季度 -->
- <uv-picker ref="seasonPicker" :columns="seasonList" keyName="label" @confirm="seasonConfirm" />
- <!-- 月份范围 -->
- <KDatePicker
- v-model="show"
- :limitStartDate="limitStartDate"
- :limitEndDate="limitEndDate"
- type="month"
- is-range
- @change="getDate"
- formatter="YYYY-MM-DD"
- />
- </view>
- </template>
- <script setup lang="ts">
- import {
- getListDrugApi,
- getListDescendant,
- createListApi,
- planCheckApi,
- getPlanInfoApi,
- planDetailCreateApi,
- checkPlanDetailsApi,
- updatePlanApi
- } from '@/service/modules/objectivesList'
- import { onLoad } from '@dcloudio/uni-app'
- import { reactive, ref } from 'vue'
- import KDatePicker from '@/components/dateSelect/k-date-picker/KDatePicker.vue'
- import tableData from '@/components/table/tableData.vue'
- import tableDetail from '@/components/table/tableDetail.vue'
- import dayjs from 'dayjs'
- const drugList = ref<any[]>([])
- const csoList = ref<any[]>([])
- const getDict = () => {
- getListDrugApi().then((res: any) => (drugList.value = [res.data]))
- getListDescendant().then((res: any) => (csoList.value = [res.data]))
- }
- const type = ref('')
- const planId = ref('')
- const formDisabled = ref(false)
- const distributeDisbled = ref(false)
- const btnType = ref('')
- onLoad(async (info: any) => {
- type.value = info?.type
- planId.value = info?.planId
- btnType.value = info?.btnType
- await getDict()
- // 审核
- if (info?.type === '2') {
- formDisabled.value = true
- uni.setNavigationBarTitle({
- title: '审核'
- })
- planInfo()
- }
- if (info?.type === '3') {
- distributeDisbled.value = true
- uni.setNavigationBarTitle({
- title: '分发-新增'
- })
- planInfo()
- }
- if (info?.type === '4') {
- formDisabled.value = true
- uni.setNavigationBarTitle({
- title: '分发-审核'
- })
- planInfo()
- }
- if (info?.type === '5') {
- formDisabled.value = true
- uni.setNavigationBarTitle({
- title: '拆解'
- })
- planInfo()
- }
- if (info?.type === '6') {
- formDisabled.value = true
- uni.setNavigationBarTitle({
- title: '数据统计'
- })
- planInfo()
- }
- if (info?.type === '7') {
- formDisabled.value = true
- uni.setNavigationBarTitle({
- title: '拆解审核'
- })
- planInfo()
- }
- if (info?.btnType === '1') {
- uni.setNavigationBarTitle({
- title: '编辑'
- })
- planInfo()
- }
- })
- const detailInfo = ref()
- const limitStartDate = ref()
- const limitEndDate = ref()
- const tableDetailRef = ref()
- const detailsState = ref()
- const planInfo = async () => {
- const res = await getPlanInfoApi(planId.value)
- detailInfo.value = res.data
- if (btnType?.value === '1') {
- return setInfo()
- }
- const typeList = ['2', '4', '5', '6', '7']
- if (typeList.includes(type.value)) {
- setFormCommonFields(res.data)
- form.value.planName = res.data.planName
- form.value.consigneeIdLable = res.data.consigneeInfo.consigneeName
- form.value.planScore = res.data.planScore + ''
- } else if (type.value === '3') {
- setFormCommonFields(res.data)
- form.value.skuId = res.data.skuId
- form.value.planIssue = res.data.planIssue
- form.value.planExpiry = res.data.planExpiry
- }
- if (['6', '7'].includes(type.value)) {
- setTimeout(async () => {
- const resDetail = await tableDetailRef.value.getDetail(res.data?.planDetails?.detailsId)
- detailsState.value = resDetail.data.detailsState
- }, 500)
- }
- }
- const setInfo = () => {
- const data = detailInfo.value
- if (type.value === '3') {
- if (data.planState === 'INIT') {
- detailInfo.value.availScore = data?.parentPlanAvailScore + data.availScore
- } else {
- detailInfo.value.availScore = data?.parentPlanAvailScore
- }
- }
- setFormCommonFields(data)
- form.value.planName = data.planName
- form.value.parentId = data.parentId
- form.value.locFlag = data.locFlag
- form.value.consigneeId = data.consigneeId
- form.value.consigneeIdLable = data.consigneeInfo.consigneeName
- if (data.planType === 'ANN') {
- const arr = data.planIssue.split('-')
- form.value.monthrange = arr[0]
- } else {
- form.value.monthrange = convertToQuarterStart(data.planIssue)
- }
- form.value.planIssue = data.skuInfo.planIssue
- form.value.planExpiry = data.skuInfo.planExpiry
- form.value.planScore = data.planScore + ''
- formRef.value.validateField('planScore')
- }
- const setFormCommonFields = (data: any) => {
- form.value.planType = data.planType
- const curr = planTypeList.find((item) => item.value === data.planType)
- if (curr) form.value.planTypeLable = curr.label
- form.value.skuIdLable = data.skuInfo.skuName
- form.value.ent_name = data.skuInfo.manufacturer
- form.value.monthrange = data.planIssue + '至' + data.planExpiry
- form.value.planType = data.planType
- }
- function convertToQuarterStart(dateString: string) {
- const date = new Date(dateString)
- const year = date.getFullYear()
- const month = date.getMonth() // 0 为 1 月,11 为 12 月
- let quarterStartMonth
- if (month >= 0 && month <= 2) {
- quarterStartMonth = '第一' // Q1: 1月
- } else if (month >= 3 && month <= 5) {
- quarterStartMonth = '第二' // Q2: 4月
- } else if (month >= 6 && month <= 8) {
- quarterStartMonth = '第三' // Q3: 7月
- } else {
- quarterStartMonth = '第四' // Q4: 10月
- }
- return `${year}年${quarterStartMonth}季度`
- }
- const customStyle = {
- height: '80rpx'
- }
- const formRef = ref()
- const form = ref({
- planType: '',
- planTypeLable: '',
- parentId: 0,
- locFlag: 'UN_LOCK',
- skuId: '',
- skuIdLable: '',
- planName: '',
- consigneeId: '',
- consigneeIdLable: '',
- ent_name: '',
- monthrange: '',
- planIssue: '',
- planExpiry: '',
- planScore: ''
- })
- const rules = reactive({
- skuIdLable: {
- type: 'string',
- required: true,
- message: '请选择目标产品',
- trigger: ['blur', 'change']
- },
- planName: {
- type: 'string',
- required: true,
- message: '请输入目标名称',
- trigger: ['blur', 'change']
- },
- consigneeIdLable: {
- type: 'string',
- required: true,
- message: '请选择承接对象',
- trigger: ['blur', 'change']
- },
- planTypeLable: {
- type: 'string',
- required: true,
- message: '请选择目标周期',
- trigger: ['blur', 'change']
- },
- monthrange: {
- type: 'string',
- required: true,
- message: '请选择目标周期',
- trigger: ['blur', 'change']
- },
- planScore: {
- type: 'string',
- required: true,
- message: '请输入目标总值',
- trigger: ['blur', 'change']
- }
- })
- const skuIdPicker = ref()
- const consigneeIdPicker = ref()
- const planTypePicker = ref()
- const planTypeList = [
- {
- label: '年度计划',
- value: 'ANN'
- },
- {
- label: '季度计划',
- value: 'QRT'
- }
- ]
- const show = ref(false)
- const yearPicker = ref()
- const seasonPicker = ref()
- const seasonList = ref()
- const showSelect = (detailType: string) => {
- if (formDisabled.value) return
- if (detailType === 'skuId') {
- if (type.value === '3') return
- skuIdPicker.value.open()
- } else if (detailType === 'consigneeId') {
- consigneeIdPicker.value.open()
- } else if (detailType === 'planType') {
- if (type.value === '3') return
- planTypePicker.value.open()
- } else if (detailType === 'monthrange') {
- if (type.value === '3') return
- if (!form.value.planTypeLable) return
- if (form.value.planType === 'ANN') {
- yearPicker.value.open()
- } else if (form.value.planType === 'QRT') {
- let arr = []
- let years = new Date().getFullYear()
- for (let i = years - 10; i <= years + 20; i++) {
- arr.push(i)
- }
- const seasonArr = ['一季度', '二季度', '三季度', '四季度']
- seasonList.value = [arr, seasonArr]
- seasonPicker.value.open()
- }
- }
- }
- const skuIdConfirm = (e: any) => {
- const value = e.value[0]
- form.value.skuId = value.drug_id
- form.value.skuIdLable = value.drug_name
- form.value.ent_name = value.ent_name
- formRef.value.validateField('skuIdLable')
- planNameChange()
- }
- const consigneeIdConfirm = (e: any) => {
- const value = e.value[0]
- form.value.consigneeId = value.deptId
- form.value.consigneeIdLable = value.name
- formRef.value.validateField('consigneeIdLable')
- if (type.value === '3') {
- const name = detailInfo.value.planName + '-' + value.name
- form.value.planName = name
- } else {
- planNameChange()
- }
- }
- const planTypeConfirm = (e: any) => {
- if (form.value?.planType === e.value[0]) return
- const value = e.value[0]
- form.value.planType = value.value
- form.value.planTypeLable = value.label
- formRef.value.validateField('planTypeLable')
- // 清空目标周期
- form.value.planIssue = ''
- form.value.planExpiry = ''
- form.value.monthrange = ''
- }
- const getDate = (e: string[]) => {
- form.value.monthrange = e[0] + ' 至 ' + e[1]
- form.value.planIssue = e[0]
- form.value.planExpiry = e[1]
- formRef.value.validateField('monthrange')
- show.value = false
- }
- const yearConfirm = (e: any) => {
- const year = dayjs(e.value).format('YYYY')
- form.value.monthrange = year
- form.value.planIssue = year + '-01-01'
- form.value.planExpiry = year + '-12-31'
- formRef.value.validateField('monthrange')
- planNameChange()
- }
- const seasonConfirm = (e: any) => {
- console.log('e', e)
- const seasonIndex = e.indexs[1]
- const value = e.value
- form.value.monthrange = value[0] + '年第' + value[1]
- let startMonth, endMonth, endDay, text
- switch (seasonIndex) {
- case 1: // Q1
- startMonth = 1
- endMonth = 3
- endDay = 31
- text = '第一'
- break
- case 2: // Q2
- startMonth = 4
- endMonth = 6
- endDay = 30
- text = '第二'
- break
- case 3: // Q3
- startMonth = 7
- endMonth = 9
- endDay = 30
- text = '第三'
- break
- case 4: // Q4
- startMonth = 10
- endMonth = 12
- endDay = 31
- text = '第四'
- break
- default:
- throw new Error('Invalid quarter code')
- }
- const startDate = `${value[0]}-${String(startMonth).padStart(2, '0')}-01`
- const endDate = `${value[0]}-${String(endMonth).padStart(2, '0')}-${endDay}`
- form.value.planIssue = startDate
- form.value.planExpiry = endDate
- formRef.value.validateField('monthrange')
- planNameChange()
- }
- const planNameChange = () => {
- if (
- form.value.skuIdLable &&
- form.value.consigneeIdLable &&
- form.value.planTypeLable &&
- form.value.monthrange
- ) {
- let name = ''
- if (form.value.planType === 'ANN') {
- name = `${form.value.monthrange}年度-全年-${form.value.consigneeIdLable}-${form.value.skuIdLable}`
- } else {
- const arr = form.value.monthrange.split('年')
- name = `${arr[0]}年度-${arr[1]}-${form.value.consigneeIdLable}-${form.value.skuIdLable}`
- }
- form.value.planName = name
- }
- }
- const cancelFn = () => {
- uni.navigateBack()
- }
- const confirmFn = () => {
- if (type.value === '5') {
- dismantleSubmit()
- return
- }
- formRef.value
- .validate()
- .then(async () => {
- let res
- if (type.value === '3') {
- form.value.parentId = detailInfo.value.planId
- if (form.value.planScore > detailInfo.value?.availScore) {
- return uni.showToast({
- title: '当前分发目标总值不能超过剩余积分值!',
- icon: 'none'
- })
- }
- }
- // 编辑 走编辑操作
- if (btnType.value === '1') {
- return submitEdit()
- }
- res = await createListApi(form.value)
- if (res.data) {
- uni.showToast({
- title: '添加成功',
- icon: 'none'
- })
- setTimeout(() => {
- uni.navigateBack()
- }, 1000)
- }
- })
- .catch((err: any) => {
- console.log('err', err)
- })
- }
- const submitEdit = async () => {
- const obj = Object.assign(form.value, {
- planId: detailInfo.value.planId
- })
- const res = await updatePlanApi(obj)
- if (res.data) {
- uni.showToast({
- title: '更新成功',
- icon: 'none'
- })
- setTimeout(() => {
- uni.navigateBack()
- }, 1000)
- }
- }
- // 审核相关
- const reviewFormRef = ref()
- const reviewForm = reactive({
- msg: ''
- })
- const reviewFormRules = reactive({
- msg: {
- type: 'string',
- required: false,
- message: '请输入审核说明',
- trigger: ['blur', 'change']
- }
- })
- const reviewFn = (flag: boolean) => {
- reviewFormRules.msg.required = !flag
- reviewFormRef.value
- .validate()
- .then(async () => {
- if (type.value === '7') {
- dismantleReviewSubmt(flag)
- return
- }
- const obj = {
- msg: reviewForm.msg,
- planId: detailInfo.value.planId,
- result: flag
- }
- const res = await planCheckApi(obj)
- if (res.data) {
- uni.showToast({
- title: '审核完成',
- icon: 'none'
- })
- setTimeout(() => {
- uni.navigateBack()
- }, 1000)
- }
- })
- .catch((err: any) => {
- console.log('err', err)
- })
- }
- // 拆解
- const tableRef = ref()
- const dismantleSubmit = async () => {
- const data = tableRef.value.getData()
- const allQty = data.reduce((prev: any, curr: any) => Number(prev) + Number(curr.qty), 0)
- const allTotal = data.reduce((prev: any, curr: any) => prev + Number(curr.subtotal), 0)
- if (allTotal != form.value.planScore) {
- return uni.showToast({
- title: '拆解总任务分值需等于目标总值',
- icon: 'none'
- })
- }
- const obj = {
- planId: detailInfo.value.planId,
- qty: allQty,
- total: allTotal,
- items: data
- }
- const res = await planDetailCreateApi(obj)
- if (res.data) {
- uni.showToast({
- title: '拆解完成',
- icon: 'none'
- })
- setTimeout(() => {
- uni.navigateBack()
- }, 1000)
- }
- }
- // 拆解审核
- const dismantleReviewSubmt = async (flag: boolean) => {
- const obj = {
- detailsId: detailInfo.value.planDetails.detailsId,
- result: flag,
- msg: reviewForm.msg,
- currentState: detailsState.value
- }
- const res = await checkPlanDetailsApi(obj)
- if (res.data) {
- uni.showToast({
- title: '审核完成',
- icon: 'none'
- })
- setTimeout(() => {
- uni.navigateBack()
- }, 1000)
- }
- }
- </script>
- <style lang="scss" scoped>
- .objectives-add {
- background: #f2f2f2;
- min-height: 100vh;
- box-sizing: border-box;
- padding: 24rpx;
- .message {
- background: #fff;
- padding: 30rpx;
- border-radius: 12rpx;
- width: 100%;
- box-sizing: border-box;
- }
- .form {
- background: #fff;
- padding: 30rpx;
- border-radius: 12rpx;
- .avail-score {
- margin-top: 34rpx;
- font-size: 30rpx;
- font-weight: 400;
- color: #000;
- }
- }
- .table {
- margin-top: 20rpx;
- }
- }
- .botton-content {
- /* position: fixed;
- bottom: 40rpx; */
- margin-top: 20rpx;
- padding: 30rpx 46rpx 54rpx;
- box-sizing: border-box;
- background-color: #fff;
- width: 700rpx;
- min-height: 160rpx;
- border-radius: 12rpx;
- }
- .btn {
- display: flex;
- justify-content: space-between;
- view {
- font-weight: 400;
- box-sizing: border-box;
- font-size: 32rpx;
- line-height: 45rpx;
- border-radius: 8rpx;
- height: 72rpx;
- width: 290rpx;
- display: flex;
- align-items: center;
- justify-content: center;
- }
- .cancel {
- border: 2rpx solid #c7c7c7;
- color: #111;
- }
- .confirm {
- background-color: #6eb657;
- color: #ffffff;
- }
- }
- :deep(.uv-form-item__body__left) {
- padding-left: 18rpx;
- }
- .review-form {
- margin-bottom: 54rpx;
- }
- .b-fixed {
- position: fixed;
- bottom: 40rpx;
- }
- </style>
|